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