1 /*
2 * aes_gcm_nss.c
3 *
4 * AES Galois Counter Mode
5 *
6 * Richard L. Barnes
7 * Cisco Systems, Inc.
8 *
9 */
10
11 /*
12 *
13 * Copyright (c) 2013-2017, Cisco Systems, Inc.
14 * All rights reserved.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 *
20 * Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 *
23 * Redistributions in binary form must reproduce the above
24 * copyright notice, this list of conditions and the following
25 * disclaimer in the documentation and/or other materials provided
26 * with the distribution.
27 *
28 * Neither the name of the Cisco Systems, Inc. nor the names of its
29 * contributors may be used to endorse or promote products derived
30 * from this software without specific prior written permission.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
33 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
34 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
35 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
36 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
37 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
38 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
39 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
41 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
43 * OF THE POSSIBILITY OF SUCH DAMAGE.
44 *
45 */
46
47 #ifdef HAVE_CONFIG_H
48 #include <config.h>
49 #endif
50
51 #include "aes_gcm.h"
52 #include "alloc.h"
53 #include "err.h" /* for srtp_debug */
54 #include "crypto_types.h"
55 #include "cipher_types.h"
56 #include <secerr.h>
57 #include <nspr.h>
58
59 srtp_debug_module_t srtp_mod_aes_gcm = {
60 0, /* debugging is off by default */
61 "aes gcm nss" /* printable module name */
62 };
63
64 /*
65 * For now we only support 8 and 16 octet tags. The spec allows for
66 * optional 12 byte tag, which may be supported in the future.
67 */
68 #define GCM_IV_LEN 12
69 #define GCM_AUTH_TAG_LEN 16
70 #define GCM_AUTH_TAG_LEN_8 8
71
72 /*
73 * This function allocates a new instance of this crypto engine.
74 * The key_len parameter should be one of 28 or 44 for
75 * AES-128-GCM or AES-256-GCM respectively. Note that the
76 * key length includes the 14 byte salt value that is used when
77 * initializing the KDF.
78 */
srtp_aes_gcm_nss_alloc(srtp_cipher_t ** c,int key_len,int tlen)79 static srtp_err_status_t srtp_aes_gcm_nss_alloc(srtp_cipher_t **c,
80 int key_len,
81 int tlen)
82 {
83 srtp_aes_gcm_ctx_t *gcm;
84 NSSInitContext *nss;
85
86 debug_print(srtp_mod_aes_gcm, "allocating cipher with key length %d",
87 key_len);
88 debug_print(srtp_mod_aes_gcm, "allocating cipher with tag length %d", tlen);
89
90 /*
91 * Verify the key_len is valid for one of: AES-128/256
92 */
93 if (key_len != SRTP_AES_GCM_128_KEY_LEN_WSALT &&
94 key_len != SRTP_AES_GCM_256_KEY_LEN_WSALT) {
95 return (srtp_err_status_bad_param);
96 }
97
98 if (tlen != GCM_AUTH_TAG_LEN && tlen != GCM_AUTH_TAG_LEN_8) {
99 return (srtp_err_status_bad_param);
100 }
101
102 /* Initialize NSS equiv of NSS_NoDB_Init(NULL) */
103 nss = NSS_InitContext("", "", "", "", NULL,
104 NSS_INIT_READONLY | NSS_INIT_NOCERTDB |
105 NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN |
106 NSS_INIT_OPTIMIZESPACE);
107 if (!nss) {
108 return (srtp_err_status_cipher_fail);
109 }
110
111 /* allocate memory a cipher of type aes_gcm */
112 *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t));
113 if (*c == NULL) {
114 NSS_ShutdownContext(nss);
115 return (srtp_err_status_alloc_fail);
116 }
117
118 gcm = (srtp_aes_gcm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_gcm_ctx_t));
119 if (gcm == NULL) {
120 NSS_ShutdownContext(nss);
121 srtp_crypto_free(*c);
122 *c = NULL;
123 return (srtp_err_status_alloc_fail);
124 }
125
126 gcm->nss = nss;
127
128 /* set pointers */
129 (*c)->state = gcm;
130
131 /* setup cipher attributes */
132 switch (key_len) {
133 case SRTP_AES_GCM_128_KEY_LEN_WSALT:
134 (*c)->type = &srtp_aes_gcm_128;
135 (*c)->algorithm = SRTP_AES_GCM_128;
136 gcm->key_size = SRTP_AES_128_KEY_LEN;
137 gcm->tag_size = tlen;
138 gcm->params.ulTagBits = 8 * tlen;
139 break;
140 case SRTP_AES_GCM_256_KEY_LEN_WSALT:
141 (*c)->type = &srtp_aes_gcm_256;
142 (*c)->algorithm = SRTP_AES_GCM_256;
143 gcm->key_size = SRTP_AES_256_KEY_LEN;
144 gcm->tag_size = tlen;
145 gcm->params.ulTagBits = 8 * tlen;
146 break;
147 default:
148 /* this should never hit, but to be sure... */
149 return (srtp_err_status_bad_param);
150 }
151
152 /* set key size and tag size*/
153 (*c)->key_len = key_len;
154
155 return (srtp_err_status_ok);
156 }
157
158 /*
159 * This function deallocates a GCM session
160 */
srtp_aes_gcm_nss_dealloc(srtp_cipher_t * c)161 static srtp_err_status_t srtp_aes_gcm_nss_dealloc(srtp_cipher_t *c)
162 {
163 srtp_aes_gcm_ctx_t *ctx;
164
165 ctx = (srtp_aes_gcm_ctx_t *)c->state;
166 if (ctx) {
167 /* release NSS resources */
168 if (ctx->key) {
169 PK11_FreeSymKey(ctx->key);
170 }
171
172 if (ctx->nss) {
173 NSS_ShutdownContext(ctx->nss);
174 ctx->nss = NULL;
175 }
176
177 /* zeroize the key material */
178 octet_string_set_to_zero(ctx, sizeof(srtp_aes_gcm_ctx_t));
179 srtp_crypto_free(ctx);
180 }
181
182 /* free memory */
183 srtp_crypto_free(c);
184
185 return (srtp_err_status_ok);
186 }
187
188 /*
189 * aes_gcm_nss_context_init(...) initializes the aes_gcm_context
190 * using the value in key[].
191 *
192 * the key is the secret key
193 */
srtp_aes_gcm_nss_context_init(void * cv,const uint8_t * key)194 static srtp_err_status_t srtp_aes_gcm_nss_context_init(void *cv,
195 const uint8_t *key)
196 {
197 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
198
199 c->dir = srtp_direction_any;
200
201 debug_print(srtp_mod_aes_gcm, "key: %s",
202 srtp_octet_string_hex_string(key, c->key_size));
203
204 if (c->key) {
205 PK11_FreeSymKey(c->key);
206 c->key = NULL;
207 }
208
209 PK11SlotInfo *slot = PK11_GetBestSlot(CKM_AES_GCM, NULL);
210 if (!slot) {
211 return (srtp_err_status_cipher_fail);
212 }
213
214 SECItem key_item = { siBuffer, (unsigned char *)key, c->key_size };
215 c->key = PK11_ImportSymKey(slot, CKM_AES_GCM, PK11_OriginUnwrap,
216 CKA_ENCRYPT, &key_item, NULL);
217 PK11_FreeSlot(slot);
218
219 if (!c->key) {
220 return (srtp_err_status_cipher_fail);
221 }
222
223 return (srtp_err_status_ok);
224 }
225
226 /*
227 * aes_gcm_nss_set_iv(c, iv) sets the counter value to the exor of iv with
228 * the offset
229 */
srtp_aes_gcm_nss_set_iv(void * cv,uint8_t * iv,srtp_cipher_direction_t direction)230 static srtp_err_status_t srtp_aes_gcm_nss_set_iv(
231 void *cv,
232 uint8_t *iv,
233 srtp_cipher_direction_t direction)
234 {
235 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
236
237 if (direction != srtp_direction_encrypt &&
238 direction != srtp_direction_decrypt) {
239 return (srtp_err_status_bad_param);
240 }
241 c->dir = direction;
242
243 debug_print(srtp_mod_aes_gcm, "setting iv: %s",
244 srtp_octet_string_hex_string(iv, GCM_IV_LEN));
245
246 memcpy(c->iv, iv, GCM_IV_LEN);
247
248 return (srtp_err_status_ok);
249 }
250
251 /*
252 * This function processes the AAD
253 *
254 * Parameters:
255 * c Crypto context
256 * aad Additional data to process for AEAD cipher suites
257 * aad_len length of aad buffer
258 */
srtp_aes_gcm_nss_set_aad(void * cv,const uint8_t * aad,uint32_t aad_len)259 static srtp_err_status_t srtp_aes_gcm_nss_set_aad(void *cv,
260 const uint8_t *aad,
261 uint32_t aad_len)
262 {
263 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
264
265 debug_print(srtp_mod_aes_gcm, "setting AAD: %s",
266 srtp_octet_string_hex_string(aad, aad_len));
267
268 if (aad_len + c->aad_size > MAX_AD_SIZE) {
269 return srtp_err_status_bad_param;
270 }
271
272 memcpy(c->aad + c->aad_size, aad, aad_len);
273 c->aad_size += aad_len;
274
275 return (srtp_err_status_ok);
276 }
277
srtp_aes_gcm_nss_do_crypto(void * cv,int encrypt,unsigned char * buf,unsigned int * enc_len)278 static srtp_err_status_t srtp_aes_gcm_nss_do_crypto(void *cv,
279 int encrypt,
280 unsigned char *buf,
281 unsigned int *enc_len)
282 {
283 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
284
285 c->params.pIv = c->iv;
286 c->params.ulIvLen = GCM_IV_LEN;
287 c->params.pAAD = c->aad;
288 c->params.ulAADLen = c->aad_size;
289
290 // Reset AAD
291 c->aad_size = 0;
292
293 int rv;
294 SECItem param = { siBuffer, (unsigned char *)&c->params,
295 sizeof(CK_GCM_PARAMS) };
296 if (encrypt) {
297 rv = PK11_Encrypt(c->key, CKM_AES_GCM, ¶m, buf, enc_len,
298 *enc_len + 16, buf, *enc_len);
299 } else {
300 rv = PK11_Decrypt(c->key, CKM_AES_GCM, ¶m, buf, enc_len, *enc_len,
301 buf, *enc_len);
302 }
303
304 srtp_err_status_t status = (srtp_err_status_ok);
305 if (rv != SECSuccess) {
306 status = (srtp_err_status_cipher_fail);
307 }
308
309 return status;
310 }
311
312 /*
313 * This function encrypts a buffer using AES GCM mode
314 *
315 * XXX(rlb@ipv.sx): We're required to break off and cache the tag
316 * here, because the get_tag() method is separate and the tests expect
317 * encrypt() not to change the size of the plaintext. It might be
318 * good to update the calling API so that this is cleaner.
319 *
320 * Parameters:
321 * c Crypto context
322 * buf data to encrypt
323 * enc_len length of encrypt buffer
324 */
srtp_aes_gcm_nss_encrypt(void * cv,unsigned char * buf,unsigned int * enc_len)325 static srtp_err_status_t srtp_aes_gcm_nss_encrypt(void *cv,
326 unsigned char *buf,
327 unsigned int *enc_len)
328 {
329 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
330
331 // When we get a non-NULL buffer, we know that the caller is
332 // prepared to also take the tag. When we get a NULL buffer,
333 // even though there's no data, we need to give NSS a buffer
334 // where it can write the tag. We can't just use c->tag because
335 // memcpy has undefined behavior on overlapping ranges.
336 unsigned char tagbuf[16];
337 unsigned char *non_null_buf = buf;
338 if (!non_null_buf && (*enc_len == 0)) {
339 non_null_buf = tagbuf;
340 } else if (!non_null_buf) {
341 return srtp_err_status_bad_param;
342 }
343
344 srtp_err_status_t status =
345 srtp_aes_gcm_nss_do_crypto(cv, 1, non_null_buf, enc_len);
346 if (status != srtp_err_status_ok) {
347 return status;
348 }
349
350 memcpy(c->tag, non_null_buf + (*enc_len - c->tag_size), c->tag_size);
351 *enc_len -= c->tag_size;
352 return srtp_err_status_ok;
353 }
354
355 /*
356 * This function calculates and returns the GCM tag for a given context.
357 * This should be called after encrypting the data. The *len value
358 * is increased by the tag size. The caller must ensure that *buf has
359 * enough room to accept the appended tag.
360 *
361 * Parameters:
362 * c Crypto context
363 * buf data to encrypt
364 * len length of encrypt buffer
365 */
srtp_aes_gcm_nss_get_tag(void * cv,uint8_t * buf,uint32_t * len)366 static srtp_err_status_t srtp_aes_gcm_nss_get_tag(void *cv,
367 uint8_t *buf,
368 uint32_t *len)
369 {
370 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv;
371 *len = c->tag_size;
372 memcpy(buf, c->tag, c->tag_size);
373 return (srtp_err_status_ok);
374 }
375
376 /*
377 * This function decrypts a buffer using AES GCM mode
378 *
379 * Parameters:
380 * c Crypto context
381 * buf data to encrypt
382 * enc_len length of encrypt buffer
383 */
srtp_aes_gcm_nss_decrypt(void * cv,unsigned char * buf,unsigned int * enc_len)384 static srtp_err_status_t srtp_aes_gcm_nss_decrypt(void *cv,
385 unsigned char *buf,
386 unsigned int *enc_len)
387 {
388 srtp_err_status_t status = srtp_aes_gcm_nss_do_crypto(cv, 0, buf, enc_len);
389 if (status != srtp_err_status_ok) {
390 int err = PR_GetError();
391 if (err == SEC_ERROR_BAD_DATA) {
392 status = srtp_err_status_auth_fail;
393 }
394 }
395
396 return status;
397 }
398
399 /*
400 * Name of this crypto engine
401 */
402 static const char srtp_aes_gcm_128_nss_description[] = "AES-128 GCM using NSS";
403 static const char srtp_aes_gcm_256_nss_description[] = "AES-256 GCM using NSS";
404
405 /*
406 * KAT values for AES self-test. These
407 * values we're derived from independent test code
408 * using OpenSSL.
409 */
410 /* clang-format off */
411 static const uint8_t srtp_aes_gcm_test_case_0_key[SRTP_AES_GCM_128_KEY_LEN_WSALT] = {
412 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
413 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
414 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
415 0x09, 0x0a, 0x0b, 0x0c,
416 };
417 /* clang-format on */
418
419 /* clang-format off */
420 static uint8_t srtp_aes_gcm_test_case_0_iv[12] = {
421 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
422 0xde, 0xca, 0xf8, 0x88
423 };
424 /* clang-format on */
425
426 /* clang-format off */
427 static const uint8_t srtp_aes_gcm_test_case_0_plaintext[60] = {
428 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
429 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
430 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
431 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
432 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
433 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
434 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
435 0xba, 0x63, 0x7b, 0x39
436 };
437
438 /* clang-format off */
439 static const uint8_t srtp_aes_gcm_test_case_0_aad[20] = {
440 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
441 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
442 0xab, 0xad, 0xda, 0xd2
443 };
444 /* clang-format on */
445
446 /* clang-format off */
447 static const uint8_t srtp_aes_gcm_test_case_0_ciphertext[76] = {
448 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24,
449 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c,
450 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0,
451 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e,
452 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c,
453 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05,
454 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97,
455 0x3d, 0x58, 0xe0, 0x91,
456 /* the last 16 bytes are the tag */
457 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb,
458 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47,
459 };
460 /* clang-format on */
461
462 static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0a = {
463 SRTP_AES_GCM_128_KEY_LEN_WSALT, /* octets in key */
464 srtp_aes_gcm_test_case_0_key, /* key */
465 srtp_aes_gcm_test_case_0_iv, /* packet index */
466 60, /* octets in plaintext */
467 srtp_aes_gcm_test_case_0_plaintext, /* plaintext */
468 68, /* octets in ciphertext */
469 srtp_aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */
470 20, /* octets in AAD */
471 srtp_aes_gcm_test_case_0_aad, /* AAD */
472 GCM_AUTH_TAG_LEN_8, /* */
473 NULL /* pointer to next testcase */
474 };
475
476 static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_0 = {
477 SRTP_AES_GCM_128_KEY_LEN_WSALT, /* octets in key */
478 srtp_aes_gcm_test_case_0_key, /* key */
479 srtp_aes_gcm_test_case_0_iv, /* packet index */
480 60, /* octets in plaintext */
481 srtp_aes_gcm_test_case_0_plaintext, /* plaintext */
482 76, /* octets in ciphertext */
483 srtp_aes_gcm_test_case_0_ciphertext, /* ciphertext + tag */
484 20, /* octets in AAD */
485 srtp_aes_gcm_test_case_0_aad, /* AAD */
486 GCM_AUTH_TAG_LEN, /* */
487 &srtp_aes_gcm_test_case_0a /* pointer to next testcase */
488 };
489
490 /* clang-format off */
491 static const uint8_t srtp_aes_gcm_test_case_1_key[SRTP_AES_GCM_256_KEY_LEN_WSALT] = {
492 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c,
493 0xa5, 0x59, 0x09, 0xc5, 0x54, 0x66, 0x93, 0x1c,
494 0xaf, 0xf5, 0x26, 0x9a, 0x21, 0xd5, 0x14, 0xb2,
495 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08,
496 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
497 0x09, 0x0a, 0x0b, 0x0c,
498 };
499 /* clang-format on */
500
501 /* clang-format off */
502 static uint8_t srtp_aes_gcm_test_case_1_iv[12] = {
503 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad,
504 0xde, 0xca, 0xf8, 0x88
505 };
506 /* clang-format on */
507
508 /* clang-format off */
509 static const uint8_t srtp_aes_gcm_test_case_1_plaintext[60] = {
510 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5,
511 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a,
512 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda,
513 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72,
514 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53,
515 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25,
516 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57,
517 0xba, 0x63, 0x7b, 0x39
518 };
519 /* clang-format on */
520
521 /* clang-format off */
522 static const uint8_t srtp_aes_gcm_test_case_1_aad[20] = {
523 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
524 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef,
525 0xab, 0xad, 0xda, 0xd2
526 };
527 /* clang-format on */
528
529 /* clang-format off */
530 static const uint8_t srtp_aes_gcm_test_case_1_ciphertext[76] = {
531 0x0b, 0x11, 0xcf, 0xaf, 0x68, 0x4d, 0xae, 0x46,
532 0xc7, 0x90, 0xb8, 0x8e, 0xb7, 0x6a, 0x76, 0x2a,
533 0x94, 0x82, 0xca, 0xab, 0x3e, 0x39, 0xd7, 0x86,
534 0x1b, 0xc7, 0x93, 0xed, 0x75, 0x7f, 0x23, 0x5a,
535 0xda, 0xfd, 0xd3, 0xe2, 0x0e, 0x80, 0x87, 0xa9,
536 0x6d, 0xd7, 0xe2, 0x6a, 0x7d, 0x5f, 0xb4, 0x80,
537 0xef, 0xef, 0xc5, 0x29, 0x12, 0xd1, 0xaa, 0x10,
538 0x09, 0xc9, 0x86, 0xc1,
539 /* the last 16 bytes are the tag */
540 0x45, 0xbc, 0x03, 0xe6, 0xe1, 0xac, 0x0a, 0x9f,
541 0x81, 0xcb, 0x8e, 0x5b, 0x46, 0x65, 0x63, 0x1d,
542 };
543 /* clang-format on */
544
545 static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1a = {
546 SRTP_AES_GCM_256_KEY_LEN_WSALT, /* octets in key */
547 srtp_aes_gcm_test_case_1_key, /* key */
548 srtp_aes_gcm_test_case_1_iv, /* packet index */
549 60, /* octets in plaintext */
550 srtp_aes_gcm_test_case_1_plaintext, /* plaintext */
551 68, /* octets in ciphertext */
552 srtp_aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */
553 20, /* octets in AAD */
554 srtp_aes_gcm_test_case_1_aad, /* AAD */
555 GCM_AUTH_TAG_LEN_8, /* */
556 NULL /* pointer to next testcase */
557 };
558
559 static const srtp_cipher_test_case_t srtp_aes_gcm_test_case_1 = {
560 SRTP_AES_GCM_256_KEY_LEN_WSALT, /* octets in key */
561 srtp_aes_gcm_test_case_1_key, /* key */
562 srtp_aes_gcm_test_case_1_iv, /* packet index */
563 60, /* octets in plaintext */
564 srtp_aes_gcm_test_case_1_plaintext, /* plaintext */
565 76, /* octets in ciphertext */
566 srtp_aes_gcm_test_case_1_ciphertext, /* ciphertext + tag */
567 20, /* octets in AAD */
568 srtp_aes_gcm_test_case_1_aad, /* AAD */
569 GCM_AUTH_TAG_LEN, /* */
570 &srtp_aes_gcm_test_case_1a /* pointer to next testcase */
571 };
572
573 /*
574 * This is the vector function table for this crypto engine.
575 */
576 /* clang-format off */
577 const srtp_cipher_type_t srtp_aes_gcm_128 = {
578 srtp_aes_gcm_nss_alloc,
579 srtp_aes_gcm_nss_dealloc,
580 srtp_aes_gcm_nss_context_init,
581 srtp_aes_gcm_nss_set_aad,
582 srtp_aes_gcm_nss_encrypt,
583 srtp_aes_gcm_nss_decrypt,
584 srtp_aes_gcm_nss_set_iv,
585 srtp_aes_gcm_nss_get_tag,
586 srtp_aes_gcm_128_nss_description,
587 &srtp_aes_gcm_test_case_0,
588 SRTP_AES_GCM_128
589 };
590 /* clang-format on */
591
592 /*
593 * This is the vector function table for this crypto engine.
594 */
595 /* clang-format off */
596 const srtp_cipher_type_t srtp_aes_gcm_256 = {
597 srtp_aes_gcm_nss_alloc,
598 srtp_aes_gcm_nss_dealloc,
599 srtp_aes_gcm_nss_context_init,
600 srtp_aes_gcm_nss_set_aad,
601 srtp_aes_gcm_nss_encrypt,
602 srtp_aes_gcm_nss_decrypt,
603 srtp_aes_gcm_nss_set_iv,
604 srtp_aes_gcm_nss_get_tag,
605 srtp_aes_gcm_256_nss_description,
606 &srtp_aes_gcm_test_case_1,
607 SRTP_AES_GCM_256
608 };
609 /* clang-format on */
610