Line data Source code
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 :
44 59 : GF_Err gf_crypt_init_openssl_cbc(GF_Crypt* td, void *key, const void *iv)
45 : {
46 59 : Openssl_ctx_cbc *ctx = (Openssl_ctx_cbc*)td->context;
47 59 : if (!ctx) {
48 59 : GF_SAFEALLOC(ctx, Openssl_ctx_cbc);
49 59 : if (ctx == NULL) return GF_OUT_OF_MEM;
50 59 : td->context = ctx;
51 : }
52 :
53 59 : if (iv != NULL) {
54 59 : memcpy(ctx->previous_ciphertext, iv, AES_BLOCK_SIZE);
55 : }
56 : return GF_OK;
57 : }
58 :
59 59 : void gf_crypt_deinit_openssl_cbc(GF_Crypt* td)
60 : {
61 59 : }
62 :
63 66 : void gf_set_key_openssl_cbc(GF_Crypt* td, void *key)
64 : {
65 66 : Openssl_ctx_cbc* ctx = (Openssl_ctx_cbc*)td->context;
66 66 : AES_set_encrypt_key(key, 128, &(ctx->enc_key));
67 66 : AES_set_decrypt_key(key, 128, &(ctx->dec_key));
68 66 : }
69 :
70 10951 : GF_Err gf_crypt_set_IV_openssl_cbc(GF_Crypt* td, const u8 *iv, u32 iv_size)
71 : {
72 10951 : Openssl_ctx_cbc* ctx = (Openssl_ctx_cbc*)td->context;
73 10951 : memcpy(ctx->previous_ciphertext, iv, iv_size);
74 10951 : return GF_OK;
75 : }
76 :
77 2600 : GF_Err gf_crypt_get_IV_openssl_cbc(GF_Crypt* td, u8 *iv, u32 *iv_size)
78 : {
79 2600 : Openssl_ctx_cbc* ctx = (Openssl_ctx_cbc*)td->context;
80 2600 : *iv_size = AES_BLOCK_SIZE;
81 2600 : memcpy(iv, ctx->previous_ciphertext, AES_BLOCK_SIZE);
82 2600 : return GF_OK;
83 : }
84 :
85 41054 : GF_Err gf_crypt_crypt_openssl_cbc(GF_Crypt* td, u8 *plaintext, u32 len, u32 aes_crypt_type) {
86 41054 : Openssl_ctx_cbc* ctx = (Openssl_ctx_cbc*)td->context;
87 : u32 iteration;
88 41054 : AES_KEY *key = aes_crypt_type ? &ctx->enc_key : &ctx->dec_key;
89 41054 : u32 numberOfIterations = len / AES_BLOCK_SIZE;
90 41054 : if (numberOfIterations * AES_BLOCK_SIZE < len) numberOfIterations++;
91 :
92 223378 : for (iteration = 0; iteration < numberOfIterations; ++iteration) {
93 182324 : if (len - iteration*AES_BLOCK_SIZE < AES_BLOCK_SIZE) {
94 0 : memset(ctx->padded_input, 0, AES_BLOCK_SIZE);
95 0 : memcpy(ctx->padded_input, plaintext, len - iteration*AES_BLOCK_SIZE);
96 0 : 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 182324 : 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 41054 : return GF_OK;
103 : }
104 :
105 26648 : GF_Err gf_crypt_encrypt_openssl_cbc(GF_Crypt* td, u8 *plaintext, u32 len)
106 : {
107 26648 : return gf_crypt_crypt_openssl_cbc(td, plaintext, len, AES_ENCRYPT);
108 : }
109 :
110 14406 : GF_Err gf_crypt_decrypt_openssl_cbc(GF_Crypt* td, u8 *ciphertext, u32 len)
111 : {
112 14406 : 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 :
126 788 : void gf_set_key_openssl_ctr(GF_Crypt* td, void *key)
127 : {
128 788 : Openssl_ctx_ctr* ctx = (Openssl_ctx_ctr*)td->context;
129 788 : AES_set_encrypt_key(key, 128, &(ctx->key));
130 788 : }
131 :
132 37363 : GF_Err gf_crypt_set_IV_openssl_ctr(GF_Crypt* td, const u8 *iv, u32 iv_size)
133 : {
134 37363 : Openssl_ctx_ctr* ctx = (Openssl_ctx_ctr*)td->context;
135 :
136 37363 : ctx->c_counter_pos = ((u8*)iv)[0];
137 37363 : memcpy(ctx->iv, &((u8*)iv)[1], iv_size - 1);
138 37363 : memset(ctx->cyphered_iv, 0, 16);
139 37363 : return GF_OK;
140 : }
141 :
142 21117 : GF_Err gf_crypt_get_IV_openssl_ctr(GF_Crypt* td, u8 *iv, u32 *iv_size)
143 : {
144 21117 : Openssl_ctx_ctr* ctx = (Openssl_ctx_ctr*)td->context;
145 :
146 21117 : *iv_size = AES_BLOCK_SIZE + 1;
147 :
148 21117 : ((u8 *)iv)[0] = ctx->c_counter_pos;
149 21117 : memcpy(&((u8 *)iv)[1], ctx->iv, AES_BLOCK_SIZE);
150 21117 : return GF_OK;
151 : }
152 :
153 623 : GF_Err gf_crypt_init_openssl_ctr(GF_Crypt* td, void *key, const void *iv)
154 : {
155 623 : Openssl_ctx_ctr *ctx = (Openssl_ctx_ctr*)td->context;
156 623 : if (!ctx) {
157 458 : GF_SAFEALLOC(ctx, Openssl_ctx_ctr);
158 458 : if (!ctx) return GF_OUT_OF_MEM;
159 :
160 458 : td->context = ctx;
161 : }
162 623 : ctx->c_counter_pos = 0;
163 623 : if (iv != NULL) {
164 623 : memcpy(ctx->iv, &((u8*)iv)[0], AES_BLOCK_SIZE);
165 : }
166 :
167 : return GF_OK;
168 : }
169 :
170 462 : void gf_crypt_deinit_openssl_ctr(GF_Crypt* td)
171 : {
172 462 : }
173 :
174 0 : GF_Err gf_crypt_crypt_openssl_ctr(GF_Crypt* td, u8 *plaintext, u32 len)
175 : {
176 115812 : Openssl_ctx_ctr* ctx = (Openssl_ctx_ctr*)td->context;
177 :
178 115812 : CRYPTO_ctr128_encrypt(plaintext, plaintext, len, &ctx->key, ctx->iv, ctx->cyphered_iv, &ctx->c_counter_pos, (block128_f)AES_encrypt);
179 :
180 0 : return GF_OK;
181 : }
182 :
183 60396 : GF_Err gf_crypt_encrypt_openssl_ctr(GF_Crypt* td, u8 *plaintext, u32 len)
184 : {
185 60396 : return gf_crypt_crypt_openssl_ctr(td, plaintext, len);
186 : }
187 :
188 55416 : GF_Err gf_crypt_decrypt_openssl_ctr(GF_Crypt* td, u8 *ciphertext, u32 len)
189 : {
190 55416 : return gf_crypt_crypt_openssl_ctr(td, ciphertext, len);
191 : }
192 :
193 :
194 521 : GF_Err gf_crypt_open_open_openssl(GF_Crypt* td, GF_CRYPTO_MODE mode)
195 : {
196 521 : td->mode = mode;
197 521 : switch (td->mode) {
198 59 : case GF_CBC:
199 59 : td->_init_crypt = gf_crypt_init_openssl_cbc;
200 59 : td->_deinit_crypt = gf_crypt_deinit_openssl_cbc;
201 59 : td->_set_key = gf_set_key_openssl_cbc;
202 59 : td->_crypt = gf_crypt_encrypt_openssl_cbc;
203 59 : td->_decrypt = gf_crypt_decrypt_openssl_cbc;
204 59 : td->_get_state = gf_crypt_get_IV_openssl_cbc;
205 59 : td->_set_state = gf_crypt_set_IV_openssl_cbc;
206 59 : break;
207 462 : case GF_CTR:
208 462 : td->_init_crypt = gf_crypt_init_openssl_ctr;
209 462 : td->_deinit_crypt = gf_crypt_deinit_openssl_ctr;
210 462 : td->_set_key = gf_set_key_openssl_ctr;
211 462 : td->_crypt = gf_crypt_encrypt_openssl_ctr;
212 462 : td->_decrypt = gf_crypt_decrypt_openssl_ctr;
213 462 : td->_get_state = gf_crypt_get_IV_openssl_ctr;
214 462 : td->_set_state = gf_crypt_set_IV_openssl_ctr;
215 462 : break;
216 : default:
217 : return GF_BAD_PARAM;
218 : break;
219 : }
220 :
221 521 : td->algo = GF_AES_128;
222 521 : return GF_OK;
223 : }
224 :
225 : #endif
226 :
|