1 /*
2 *			GPAC - Multimedia Framework C SDK
3 *
4 *			Authors: Rodolphe Fouquet
5 *			Copyright (c) Motion Spell 2016
6 *					All rights reserved
7 *
8 *  This file is part of GPAC / crypto lib sub-project
9 *
10 *  GPAC is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU Lesser General Public License as published by
12 *  the Free Software Foundation; either version 2, or (at your option)
13 *  any later version.
14 *
15 *  GPAC is distributed in the hope that it will be useful,
16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *  GNU Lesser General Public License for more details.
19 *
20 *  You should have received a copy of the GNU Lesser General Public
21 *  License along with this library; see the file COPYING.  If not, write to
22 *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 */
25 
26 #include <gpac/internal/crypt_dev.h>
27 
28 #ifdef GPAC_HAS_SSL
29 #include <openssl/aes.h>
30 #include <openssl/modes.h>
31 
32 #include <math.h>
33 
34 typedef struct {
35 	AES_KEY enc_key, dec_key;
36 
37 	u8 block[AES_BLOCK_SIZE];
38 	u8 padded_input[AES_BLOCK_SIZE]; // use only when the input length is inferior to the algo block size
39 	u8 previous_ciphertext[AES_BLOCK_SIZE];
40 } Openssl_ctx_cbc;
41 
42 /** CBC STUFF **/
43 
gf_crypt_init_openssl_cbc(GF_Crypt * td,void * key,const void * iv)44 GF_Err gf_crypt_init_openssl_cbc(GF_Crypt* td, void *key, const void *iv)
45 {
46 	Openssl_ctx_cbc *ctx = (Openssl_ctx_cbc*)td->context;
47 	if (!ctx) {
48 		GF_SAFEALLOC(ctx, Openssl_ctx_cbc);
49 		if (ctx == NULL) return GF_OUT_OF_MEM;
50 		td->context = ctx;
51 	}
52 
53 	if (iv != NULL) {
54 		memcpy(ctx->previous_ciphertext, iv, AES_BLOCK_SIZE);
55 	}
56 	return GF_OK;
57 }
58 
gf_crypt_deinit_openssl_cbc(GF_Crypt * td)59 void gf_crypt_deinit_openssl_cbc(GF_Crypt* td)
60 {
61 }
62 
gf_set_key_openssl_cbc(GF_Crypt * td,void * key)63 void gf_set_key_openssl_cbc(GF_Crypt* td, void *key)
64 {
65 	Openssl_ctx_cbc* ctx = (Openssl_ctx_cbc*)td->context;
66 	AES_set_encrypt_key(key, 128, &(ctx->enc_key));
67 	AES_set_decrypt_key(key, 128, &(ctx->dec_key));
68 }
69 
gf_crypt_set_IV_openssl_cbc(GF_Crypt * td,const u8 * iv,u32 iv_size)70 GF_Err gf_crypt_set_IV_openssl_cbc(GF_Crypt* td, const u8 *iv, u32 iv_size)
71 {
72 	Openssl_ctx_cbc* ctx = (Openssl_ctx_cbc*)td->context;
73 	memcpy(ctx->previous_ciphertext, iv, iv_size);
74 	return GF_OK;
75 }
76 
gf_crypt_get_IV_openssl_cbc(GF_Crypt * td,u8 * iv,u32 * iv_size)77 GF_Err gf_crypt_get_IV_openssl_cbc(GF_Crypt* td, u8 *iv, u32 *iv_size)
78 {
79 	Openssl_ctx_cbc* ctx = (Openssl_ctx_cbc*)td->context;
80 	*iv_size = AES_BLOCK_SIZE;
81 	memcpy(iv, ctx->previous_ciphertext, AES_BLOCK_SIZE);
82 	return GF_OK;
83 }
84 
gf_crypt_crypt_openssl_cbc(GF_Crypt * td,u8 * plaintext,u32 len,u32 aes_crypt_type)85 GF_Err gf_crypt_crypt_openssl_cbc(GF_Crypt* td, u8 *plaintext, u32 len, u32 aes_crypt_type) {
86 	Openssl_ctx_cbc* ctx = (Openssl_ctx_cbc*)td->context;
87 	u32 iteration;
88 	AES_KEY *key = aes_crypt_type ? &ctx->enc_key : &ctx->dec_key;
89 	u32 numberOfIterations = len / AES_BLOCK_SIZE;
90 	if (numberOfIterations * AES_BLOCK_SIZE < len) numberOfIterations++;
91 
92 	for (iteration = 0; iteration < numberOfIterations; ++iteration) {
93 		if (len - iteration*AES_BLOCK_SIZE < AES_BLOCK_SIZE) {
94 			memset(ctx->padded_input, 0, AES_BLOCK_SIZE);
95 			memcpy(ctx->padded_input, plaintext, len - iteration*AES_BLOCK_SIZE);
96 			AES_cbc_encrypt(plaintext + iteration*AES_BLOCK_SIZE, ctx->block, AES_BLOCK_SIZE, key, ctx->previous_ciphertext, aes_crypt_type);
97 			memcpy(plaintext + iteration*AES_BLOCK_SIZE, ctx->block, len - iteration*AES_BLOCK_SIZE);
98 		} else {
99 			AES_cbc_encrypt(plaintext + iteration*AES_BLOCK_SIZE, plaintext + iteration*AES_BLOCK_SIZE, AES_BLOCK_SIZE, key, ctx->previous_ciphertext, aes_crypt_type);
100 		}
101 	}
102 	return GF_OK;
103 }
104 
gf_crypt_encrypt_openssl_cbc(GF_Crypt * td,u8 * plaintext,u32 len)105 GF_Err gf_crypt_encrypt_openssl_cbc(GF_Crypt* td, u8 *plaintext, u32 len)
106 {
107 	return gf_crypt_crypt_openssl_cbc(td, plaintext, len, AES_ENCRYPT);
108 }
109 
gf_crypt_decrypt_openssl_cbc(GF_Crypt * td,u8 * ciphertext,u32 len)110 GF_Err gf_crypt_decrypt_openssl_cbc(GF_Crypt* td, u8 *ciphertext, u32 len)
111 {
112 	return gf_crypt_crypt_openssl_cbc(td, ciphertext, len, AES_DECRYPT);
113 }
114 
115 typedef struct {
116 	AES_KEY key;
117 
118 	u8 cyphered_iv[16];
119 	u8 iv[16];
120 	unsigned int c_counter_pos;
121 } Openssl_ctx_ctr;
122 
123 
124 /** CTR STUFF **/
125 
gf_set_key_openssl_ctr(GF_Crypt * td,void * key)126 void gf_set_key_openssl_ctr(GF_Crypt* td, void *key)
127 {
128 	Openssl_ctx_ctr* ctx = (Openssl_ctx_ctr*)td->context;
129 	AES_set_encrypt_key(key, 128, &(ctx->key));
130 }
131 
gf_crypt_set_IV_openssl_ctr(GF_Crypt * td,const u8 * iv,u32 iv_size)132 GF_Err gf_crypt_set_IV_openssl_ctr(GF_Crypt* td, const u8 *iv, u32 iv_size)
133 {
134 	Openssl_ctx_ctr* ctx = (Openssl_ctx_ctr*)td->context;
135 
136 	ctx->c_counter_pos = ((u8*)iv)[0];
137 	memcpy(ctx->iv, &((u8*)iv)[1], iv_size - 1);
138 	memset(ctx->cyphered_iv, 0, 16);
139 	return GF_OK;
140 }
141 
gf_crypt_get_IV_openssl_ctr(GF_Crypt * td,u8 * iv,u32 * iv_size)142 GF_Err gf_crypt_get_IV_openssl_ctr(GF_Crypt* td, u8 *iv, u32 *iv_size)
143 {
144 	Openssl_ctx_ctr* ctx = (Openssl_ctx_ctr*)td->context;
145 
146 	*iv_size = AES_BLOCK_SIZE + 1;
147 
148 	((u8 *)iv)[0] = ctx->c_counter_pos;
149 	memcpy(&((u8 *)iv)[1], ctx->iv, AES_BLOCK_SIZE);
150 	return GF_OK;
151 }
152 
gf_crypt_init_openssl_ctr(GF_Crypt * td,void * key,const void * iv)153 GF_Err gf_crypt_init_openssl_ctr(GF_Crypt* td, void *key, const void *iv)
154 {
155 	Openssl_ctx_ctr *ctx = (Openssl_ctx_ctr*)td->context;
156 	if (!ctx) {
157 		GF_SAFEALLOC(ctx, Openssl_ctx_ctr);
158 		if (!ctx) return GF_OUT_OF_MEM;
159 
160 		td->context = ctx;
161 	}
162 	ctx->c_counter_pos = 0;
163 	if (iv != NULL) {
164 		memcpy(ctx->iv, &((u8*)iv)[0], AES_BLOCK_SIZE);
165 	}
166 
167 	return GF_OK;
168 }
169 
gf_crypt_deinit_openssl_ctr(GF_Crypt * td)170 void gf_crypt_deinit_openssl_ctr(GF_Crypt* td)
171 {
172 }
173 
gf_crypt_crypt_openssl_ctr(GF_Crypt * td,u8 * plaintext,u32 len)174 GF_Err gf_crypt_crypt_openssl_ctr(GF_Crypt* td, u8 *plaintext, u32 len)
175 {
176 	Openssl_ctx_ctr* ctx = (Openssl_ctx_ctr*)td->context;
177 
178 	CRYPTO_ctr128_encrypt(plaintext, plaintext, len, &ctx->key, ctx->iv, ctx->cyphered_iv, &ctx->c_counter_pos, (block128_f)AES_encrypt);
179 
180 	return GF_OK;
181 }
182 
gf_crypt_encrypt_openssl_ctr(GF_Crypt * td,u8 * plaintext,u32 len)183 GF_Err gf_crypt_encrypt_openssl_ctr(GF_Crypt* td, u8 *plaintext, u32 len)
184 {
185 	return gf_crypt_crypt_openssl_ctr(td, plaintext, len);
186 }
187 
gf_crypt_decrypt_openssl_ctr(GF_Crypt * td,u8 * ciphertext,u32 len)188 GF_Err gf_crypt_decrypt_openssl_ctr(GF_Crypt* td, u8 *ciphertext, u32 len)
189 {
190 	return gf_crypt_crypt_openssl_ctr(td, ciphertext, len);
191 }
192 
193 
gf_crypt_open_open_openssl(GF_Crypt * td,GF_CRYPTO_MODE mode)194 GF_Err gf_crypt_open_open_openssl(GF_Crypt* td, GF_CRYPTO_MODE mode)
195 {
196 	td->mode = mode;
197 	switch (td->mode) {
198 	case GF_CBC:
199 		td->_init_crypt = gf_crypt_init_openssl_cbc;
200 		td->_deinit_crypt = gf_crypt_deinit_openssl_cbc;
201 		td->_set_key = gf_set_key_openssl_cbc;
202 		td->_crypt = gf_crypt_encrypt_openssl_cbc;
203 		td->_decrypt = gf_crypt_decrypt_openssl_cbc;
204 		td->_get_state = gf_crypt_get_IV_openssl_cbc;
205 		td->_set_state = gf_crypt_set_IV_openssl_cbc;
206 		break;
207 	case GF_CTR:
208 		td->_init_crypt = gf_crypt_init_openssl_ctr;
209 		td->_deinit_crypt = gf_crypt_deinit_openssl_ctr;
210 		td->_set_key = gf_set_key_openssl_ctr;
211 		td->_crypt = gf_crypt_encrypt_openssl_ctr;
212 		td->_decrypt = gf_crypt_decrypt_openssl_ctr;
213 		td->_get_state = gf_crypt_get_IV_openssl_ctr;
214 		td->_set_state = gf_crypt_set_IV_openssl_ctr;
215 		break;
216 	default:
217 		return GF_BAD_PARAM;
218 		break;
219 	}
220 
221 	td->algo = GF_AES_128;
222 	return GF_OK;
223 }
224 
225 #endif
226 
227