• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &param, buf, enc_len,
298                           *enc_len + 16, buf, *enc_len);
299     } else {
300         rv = PK11_Decrypt(c->key, CKM_AES_GCM, &param, 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