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