1 /*
2 * aes_icm_ossl.c
3 *
4 * AES Integer Counter Mode
5 *
6 * John A. Foley
7 * Cisco Systems, Inc.
8 *
9 * 2/24/2012: This module was modified to use CiscoSSL for AES counter
10 * mode. Eddy Lem contributed the code to allow this.
11 *
12 * 12/20/2012: Added support for AES-192 and AES-256.
13 */
14
15 /*
16 *
17 * Copyright (c) 2013-2017, Cisco Systems, Inc.
18 * All rights reserved.
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
22 * are met:
23 *
24 * Redistributions of source code must retain the above copyright
25 * notice, this list of conditions and the following disclaimer.
26 *
27 * Redistributions in binary form must reproduce the above
28 * copyright notice, this list of conditions and the following
29 * disclaimer in the documentation and/or other materials provided
30 * with the distribution.
31 *
32 * Neither the name of the Cisco Systems, Inc. nor the names of its
33 * contributors may be used to endorse or promote products derived
34 * from this software without specific prior written permission.
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
37 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
38 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
39 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
40 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
41 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
42 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 *
49 */
50
51 #ifdef HAVE_CONFIG_H
52 #include <config.h>
53 #endif
54
55 #include <openssl/evp.h>
56 #include "aes_icm_ext.h"
57 #include "crypto_types.h"
58 #include "err.h" /* for srtp_debug */
59 #include "alloc.h"
60 #include "cipher_types.h"
61
62 srtp_debug_module_t srtp_mod_aes_icm = {
63 0, /* debugging is off by default */
64 "aes icm ossl" /* printable module name */
65 };
66
67 /*
68 * integer counter mode works as follows:
69 *
70 * 16 bits
71 * <----->
72 * +------+------+------+------+------+------+------+------+
73 * | nonce | packet index | ctr |---+
74 * +------+------+------+------+------+------+------+------+ |
75 * |
76 * +------+------+------+------+------+------+------+------+ v
77 * | salt |000000|->(+)
78 * +------+------+------+------+------+------+------+------+ |
79 * |
80 * +---------+
81 * | encrypt |
82 * +---------+
83 * |
84 * +------+------+------+------+------+------+------+------+ |
85 * | keystream block |<--+
86 * +------+------+------+------+------+------+------+------+
87 *
88 * All fields are big-endian
89 *
90 * ctr is the block counter, which increments from zero for
91 * each packet (16 bits wide)
92 *
93 * packet index is distinct for each packet (48 bits wide)
94 *
95 * nonce can be distinct across many uses of the same key, or
96 * can be a fixed value per key, or can be per-packet randomness
97 * (64 bits)
98 *
99 */
100
101 /*
102 * This function allocates a new instance of this crypto engine.
103 * The key_len parameter should be one of 30, 38, or 46 for
104 * AES-128, AES-192, and AES-256 respectively. Note, this key_len
105 * value is inflated, as it also accounts for the 112 bit salt
106 * value. The tlen argument is for the AEAD tag length, which
107 * isn't used in counter mode.
108 */
srtp_aes_icm_openssl_alloc(srtp_cipher_t ** c,int key_len,int tlen)109 static srtp_err_status_t srtp_aes_icm_openssl_alloc(srtp_cipher_t **c,
110 int key_len,
111 int tlen)
112 {
113 srtp_aes_icm_ctx_t *icm;
114
115 debug_print(srtp_mod_aes_icm, "allocating cipher with key length %d",
116 key_len);
117
118 /*
119 * Verify the key_len is valid for one of: AES-128/192/256
120 */
121 if (key_len != SRTP_AES_ICM_128_KEY_LEN_WSALT &&
122 key_len != SRTP_AES_ICM_192_KEY_LEN_WSALT &&
123 key_len != SRTP_AES_ICM_256_KEY_LEN_WSALT) {
124 return srtp_err_status_bad_param;
125 }
126
127 /* allocate memory a cipher of type aes_icm */
128 *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
129 if (*c == NULL) {
130 return srtp_err_status_alloc_fail;
131 }
132
133 icm = (srtp_aes_icm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_icm_ctx_t));
134 if (icm == NULL) {
135 srtp_crypto_free(*c);
136 *c = NULL;
137 return srtp_err_status_alloc_fail;
138 }
139
140 icm->ctx = EVP_CIPHER_CTX_new();
141 if (icm->ctx == NULL) {
142 srtp_crypto_free(icm);
143 srtp_crypto_free(*c);
144 *c = NULL;
145 return srtp_err_status_alloc_fail;
146 }
147
148 /* set pointers */
149 (*c)->state = icm;
150
151 /* setup cipher parameters */
152 switch (key_len) {
153 case SRTP_AES_ICM_128_KEY_LEN_WSALT:
154 (*c)->algorithm = SRTP_AES_ICM_128;
155 (*c)->type = &srtp_aes_icm_128;
156 icm->key_size = SRTP_AES_128_KEY_LEN;
157 break;
158 case SRTP_AES_ICM_192_KEY_LEN_WSALT:
159 (*c)->algorithm = SRTP_AES_ICM_192;
160 (*c)->type = &srtp_aes_icm_192;
161 icm->key_size = SRTP_AES_192_KEY_LEN;
162 break;
163 case SRTP_AES_ICM_256_KEY_LEN_WSALT:
164 (*c)->algorithm = SRTP_AES_ICM_256;
165 (*c)->type = &srtp_aes_icm_256;
166 icm->key_size = SRTP_AES_256_KEY_LEN;
167 break;
168 }
169
170 /* set key size */
171 (*c)->key_len = key_len;
172
173 return srtp_err_status_ok;
174 }
175
176 /*
177 * This function deallocates an instance of this engine
178 */
srtp_aes_icm_openssl_dealloc(srtp_cipher_t * c)179 static srtp_err_status_t srtp_aes_icm_openssl_dealloc(srtp_cipher_t *c)
180 {
181 srtp_aes_icm_ctx_t *ctx;
182
183 if (c == NULL) {
184 return srtp_err_status_bad_param;
185 }
186
187 /*
188 * Free the EVP context
189 */
190 ctx = (srtp_aes_icm_ctx_t *)c->state;
191 if (ctx != NULL) {
192 EVP_CIPHER_CTX_free(ctx->ctx);
193 /* zeroize the key material */
194 octet_string_set_to_zero(ctx, sizeof(srtp_aes_icm_ctx_t));
195 srtp_crypto_free(ctx);
196 }
197
198 /* free memory */
199 srtp_crypto_free(c);
200
201 return srtp_err_status_ok;
202 }
203
204 /*
205 * aes_icm_openssl_context_init(...) initializes the aes_icm_context
206 * using the value in key[].
207 *
208 * the key is the secret key
209 *
210 * the salt is unpredictable (but not necessarily secret) data which
211 * randomizes the starting point in the keystream
212 */
srtp_aes_icm_openssl_context_init(void * cv,const uint8_t * key)213 static srtp_err_status_t srtp_aes_icm_openssl_context_init(void *cv,
214 const uint8_t *key)
215 {
216 srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
217 const EVP_CIPHER *evp;
218
219 /*
220 * set counter and initial values to 'offset' value, being careful not to
221 * go past the end of the key buffer
222 */
223 v128_set_to_zero(&c->counter);
224 v128_set_to_zero(&c->offset);
225 memcpy(&c->counter, key + c->key_size, SRTP_SALT_LEN);
226 memcpy(&c->offset, key + c->key_size, SRTP_SALT_LEN);
227
228 /* force last two octets of the offset to zero (for srtp compatibility) */
229 c->offset.v8[SRTP_SALT_LEN] = c->offset.v8[SRTP_SALT_LEN + 1] = 0;
230 c->counter.v8[SRTP_SALT_LEN] = c->counter.v8[SRTP_SALT_LEN + 1] = 0;
231
232 debug_print(srtp_mod_aes_icm, "key: %s",
233 srtp_octet_string_hex_string(key, c->key_size));
234 debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset));
235
236 switch (c->key_size) {
237 case SRTP_AES_256_KEY_LEN:
238 evp = EVP_aes_256_ctr();
239 break;
240 case SRTP_AES_192_KEY_LEN:
241 evp = EVP_aes_192_ctr();
242 break;
243 case SRTP_AES_128_KEY_LEN:
244 evp = EVP_aes_128_ctr();
245 break;
246 default:
247 return srtp_err_status_bad_param;
248 break;
249 }
250
251 EVP_CIPHER_CTX_cleanup(c->ctx);
252 if (!EVP_EncryptInit_ex(c->ctx, evp, NULL, key, NULL)) {
253 return srtp_err_status_fail;
254 } else {
255 return srtp_err_status_ok;
256 }
257
258 return srtp_err_status_ok;
259 }
260
261 /*
262 * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with
263 * the offset
264 */
srtp_aes_icm_openssl_set_iv(void * cv,uint8_t * iv,srtp_cipher_direction_t dir)265 static srtp_err_status_t srtp_aes_icm_openssl_set_iv(
266 void *cv,
267 uint8_t *iv,
268 srtp_cipher_direction_t dir)
269 {
270 srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
271 v128_t nonce;
272
273 /* set nonce (for alignment) */
274 v128_copy_octet_string(&nonce, iv);
275
276 debug_print(srtp_mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce));
277
278 v128_xor(&c->counter, &c->offset, &nonce);
279
280 debug_print(srtp_mod_aes_icm, "set_counter: %s",
281 v128_hex_string(&c->counter));
282
283 if (!EVP_EncryptInit_ex(c->ctx, NULL, NULL, NULL, c->counter.v8)) {
284 return srtp_err_status_fail;
285 } else {
286 return srtp_err_status_ok;
287 }
288 }
289
290 /*
291 * This function encrypts a buffer using AES CTR mode
292 *
293 * Parameters:
294 * c Crypto context
295 * buf data to encrypt
296 * enc_len length of encrypt buffer
297 */
srtp_aes_icm_openssl_encrypt(void * cv,unsigned char * buf,unsigned int * enc_len)298 static srtp_err_status_t srtp_aes_icm_openssl_encrypt(void *cv,
299 unsigned char *buf,
300 unsigned int *enc_len)
301 {
302 srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv;
303 int len = 0;
304
305 debug_print(srtp_mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter));
306
307 if (!EVP_EncryptUpdate(c->ctx, buf, &len, buf, *enc_len)) {
308 return srtp_err_status_cipher_fail;
309 }
310 *enc_len = len;
311
312 if (!EVP_EncryptFinal_ex(c->ctx, buf, &len)) {
313 return srtp_err_status_cipher_fail;
314 }
315 *enc_len += len;
316
317 return srtp_err_status_ok;
318 }
319
320 /*
321 * Name of this crypto engine
322 */
323 static const char srtp_aes_icm_128_openssl_description[] =
324 "AES-128 counter mode using openssl";
325 static const char srtp_aes_icm_192_openssl_description[] =
326 "AES-192 counter mode using openssl";
327 static const char srtp_aes_icm_256_openssl_description[] =
328 "AES-256 counter mode using openssl";
329
330 /*
331 * KAT values for AES self-test. These
332 * values came from the legacy libsrtp code.
333 */
334 /* clang-format off */
335 static const uint8_t srtp_aes_icm_128_test_case_0_key[SRTP_AES_ICM_128_KEY_LEN_WSALT] = {
336 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
337 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c,
338 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
339 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
340 };
341 /* clang-format on */
342
343 /* clang-format off */
344 static uint8_t srtp_aes_icm_128_test_case_0_nonce[16] = {
345 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
346 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
347 };
348 /* clang-format on */
349
350 /* clang-format off */
351 static const uint8_t srtp_aes_icm_128_test_case_0_plaintext[32] = {
352 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
353 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
355 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
356 };
357 /* clang-format on */
358
359 /* clang-format off */
360 static const uint8_t srtp_aes_icm_128_test_case_0_ciphertext[32] = {
361 0xe0, 0x3e, 0xad, 0x09, 0x35, 0xc9, 0x5e, 0x80,
362 0xe1, 0x66, 0xb1, 0x6d, 0xd9, 0x2b, 0x4e, 0xb4,
363 0xd2, 0x35, 0x13, 0x16, 0x2b, 0x02, 0xd0, 0xf7,
364 0x2a, 0x43, 0xa2, 0xfe, 0x4a, 0x5f, 0x97, 0xab
365 };
366 /* clang-format on */
367
368 static const srtp_cipher_test_case_t srtp_aes_icm_128_test_case_0 = {
369 SRTP_AES_ICM_128_KEY_LEN_WSALT, /* octets in key */
370 srtp_aes_icm_128_test_case_0_key, /* key */
371 srtp_aes_icm_128_test_case_0_nonce, /* packet index */
372 32, /* octets in plaintext */
373 srtp_aes_icm_128_test_case_0_plaintext, /* plaintext */
374 32, /* octets in ciphertext */
375 srtp_aes_icm_128_test_case_0_ciphertext, /* ciphertext */
376 0, /* */
377 NULL, /* */
378 0, /* */
379 NULL /* pointer to next testcase */
380 };
381
382 /*
383 * KAT values for AES-192-CTR self-test. These
384 * values came from section 7 of RFC 6188.
385 */
386 /* clang-format off */
387 static const uint8_t srtp_aes_icm_192_test_case_0_key[SRTP_AES_ICM_192_KEY_LEN_WSALT] = {
388 0xea, 0xb2, 0x34, 0x76, 0x4e, 0x51, 0x7b, 0x2d,
389 0x3d, 0x16, 0x0d, 0x58, 0x7d, 0x8c, 0x86, 0x21,
390 0x97, 0x40, 0xf6, 0x5f, 0x99, 0xb6, 0xbc, 0xf7,
391 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
392 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
393 };
394 /* clang-format on */
395
396 /* clang-format off */
397 static uint8_t srtp_aes_icm_192_test_case_0_nonce[16] = {
398 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
399 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
400 };
401 /* clang-format on */
402
403 /* clang-format off */
404 static const uint8_t srtp_aes_icm_192_test_case_0_plaintext[32] = {
405 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
406 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
409 };
410 /* clang-format on */
411
412 /* clang-format off */
413 static const uint8_t srtp_aes_icm_192_test_case_0_ciphertext[32] = {
414 0x35, 0x09, 0x6c, 0xba, 0x46, 0x10, 0x02, 0x8d,
415 0xc1, 0xb5, 0x75, 0x03, 0x80, 0x4c, 0xe3, 0x7c,
416 0x5d, 0xe9, 0x86, 0x29, 0x1d, 0xcc, 0xe1, 0x61,
417 0xd5, 0x16, 0x5e, 0xc4, 0x56, 0x8f, 0x5c, 0x9a
418 };
419 /* clang-format on */
420
421 static const srtp_cipher_test_case_t srtp_aes_icm_192_test_case_0 = {
422 SRTP_AES_ICM_192_KEY_LEN_WSALT, /* octets in key */
423 srtp_aes_icm_192_test_case_0_key, /* key */
424 srtp_aes_icm_192_test_case_0_nonce, /* packet index */
425 32, /* octets in plaintext */
426 srtp_aes_icm_192_test_case_0_plaintext, /* plaintext */
427 32, /* octets in ciphertext */
428 srtp_aes_icm_192_test_case_0_ciphertext, /* ciphertext */
429 0, /* */
430 NULL, /* */
431 0, /* */
432 NULL /* pointer to next testcase */
433 };
434
435 /*
436 * KAT values for AES-256-CTR self-test. These
437 * values came from section 7 of RFC 6188.
438 */
439 /* clang-format off */
440 static const uint8_t srtp_aes_icm_256_test_case_0_key[SRTP_AES_ICM_256_KEY_LEN_WSALT] = {
441 0x57, 0xf8, 0x2f, 0xe3, 0x61, 0x3f, 0xd1, 0x70,
442 0xa8, 0x5e, 0xc9, 0x3c, 0x40, 0xb1, 0xf0, 0x92,
443 0x2e, 0xc4, 0xcb, 0x0d, 0xc0, 0x25, 0xb5, 0x82,
444 0x72, 0x14, 0x7c, 0xc4, 0x38, 0x94, 0x4a, 0x98,
445 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
446 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd
447 };
448 /* clang-format on */
449
450 /* clang-format off */
451 static uint8_t srtp_aes_icm_256_test_case_0_nonce[16] = {
452 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
454 };
455 /* clang-format on */
456
457 /* clang-format off */
458 static const uint8_t srtp_aes_icm_256_test_case_0_plaintext[32] = {
459 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
461 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
463 };
464 /* clang-format on */
465
466 /* clang-format off */
467 static const uint8_t srtp_aes_icm_256_test_case_0_ciphertext[32] = {
468 0x92, 0xbd, 0xd2, 0x8a, 0x93, 0xc3, 0xf5, 0x25,
469 0x11, 0xc6, 0x77, 0xd0, 0x8b, 0x55, 0x15, 0xa4,
470 0x9d, 0xa7, 0x1b, 0x23, 0x78, 0xa8, 0x54, 0xf6,
471 0x70, 0x50, 0x75, 0x6d, 0xed, 0x16, 0x5b, 0xac
472 };
473 /* clang-format on */
474
475 static const srtp_cipher_test_case_t srtp_aes_icm_256_test_case_0 = {
476 SRTP_AES_ICM_256_KEY_LEN_WSALT, /* octets in key */
477 srtp_aes_icm_256_test_case_0_key, /* key */
478 srtp_aes_icm_256_test_case_0_nonce, /* packet index */
479 32, /* octets in plaintext */
480 srtp_aes_icm_256_test_case_0_plaintext, /* plaintext */
481 32, /* octets in ciphertext */
482 srtp_aes_icm_256_test_case_0_ciphertext, /* ciphertext */
483 0, /* */
484 NULL, /* */
485 0, /* */
486 NULL /* pointer to next testcase */
487 };
488
489 /*
490 * This is the function table for this crypto engine.
491 * note: the encrypt function is identical to the decrypt function
492 */
493 const srtp_cipher_type_t srtp_aes_icm_128 = {
494 srtp_aes_icm_openssl_alloc, /* */
495 srtp_aes_icm_openssl_dealloc, /* */
496 srtp_aes_icm_openssl_context_init, /* */
497 0, /* set_aad */
498 srtp_aes_icm_openssl_encrypt, /* */
499 srtp_aes_icm_openssl_encrypt, /* */
500 srtp_aes_icm_openssl_set_iv, /* */
501 0, /* get_tag */
502 srtp_aes_icm_128_openssl_description, /* */
503 &srtp_aes_icm_128_test_case_0, /* */
504 SRTP_AES_ICM_128 /* */
505 };
506
507 /*
508 * This is the function table for this crypto engine.
509 * note: the encrypt function is identical to the decrypt function
510 */
511 const srtp_cipher_type_t srtp_aes_icm_192 = {
512 srtp_aes_icm_openssl_alloc, /* */
513 srtp_aes_icm_openssl_dealloc, /* */
514 srtp_aes_icm_openssl_context_init, /* */
515 0, /* set_aad */
516 srtp_aes_icm_openssl_encrypt, /* */
517 srtp_aes_icm_openssl_encrypt, /* */
518 srtp_aes_icm_openssl_set_iv, /* */
519 0, /* get_tag */
520 srtp_aes_icm_192_openssl_description, /* */
521 &srtp_aes_icm_192_test_case_0, /* */
522 SRTP_AES_ICM_192 /* */
523 };
524
525 /*
526 * This is the function table for this crypto engine.
527 * note: the encrypt function is identical to the decrypt function
528 */
529 const srtp_cipher_type_t srtp_aes_icm_256 = {
530 srtp_aes_icm_openssl_alloc, /* */
531 srtp_aes_icm_openssl_dealloc, /* */
532 srtp_aes_icm_openssl_context_init, /* */
533 0, /* set_aad */
534 srtp_aes_icm_openssl_encrypt, /* */
535 srtp_aes_icm_openssl_encrypt, /* */
536 srtp_aes_icm_openssl_set_iv, /* */
537 0, /* get_tag */
538 srtp_aes_icm_256_openssl_description, /* */
539 &srtp_aes_icm_256_test_case_0, /* */
540 SRTP_AES_ICM_256 /* */
541 };
542