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