aes_gcm_mbedtls.c (12561B)
1 /* 2 * aes_gcm_mbedtls.c 3 * 4 * AES Galois Counter Mode 5 * 6 * YongCheng Yang 7 * 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 #include <mbedtls/gcm.h> 50 #include "aes_gcm.h" 51 #include "alloc.h" 52 #include "err.h" /* for srtp_debug */ 53 #include "crypto_types.h" 54 #include "cipher_types.h" 55 #include "cipher_test_cases.h" 56 57 srtp_debug_module_t srtp_mod_aes_gcm = { 58 0, /* debugging is off by default */ 59 "aes gcm mbedtls" /* printable module name */ 60 }; 61 62 /** 63 * SRTP IV Formation for AES-GCM 64 * https://tools.ietf.org/html/rfc7714#section-8.1 65 * 0 0 0 0 0 0 0 0 0 0 1 1 66 * 0 1 2 3 4 5 6 7 8 9 0 1 67 * +--+--+--+--+--+--+--+--+--+--+--+--+ 68 * |00|00| SSRC | ROC | SEQ |---+ 69 * +--+--+--+--+--+--+--+--+--+--+--+--+ | 70 * | 71 * +--+--+--+--+--+--+--+--+--+--+--+--+ | 72 * | Encryption Salt |->(+) 73 * +--+--+--+--+--+--+--+--+--+--+--+--+ | 74 * | 75 * +--+--+--+--+--+--+--+--+--+--+--+--+ | 76 * | Initialization Vector |<--+ 77 * +--+--+--+--+--+--+--+--+--+--+--+--+ 78 * 79 * SRTCP IV Formation for AES-GCM 80 * https://tools.ietf.org/html/rfc7714#section-9.1 81 * 82 */ 83 84 /* 85 * For now we only support 8 and 16 octet tags. The spec allows for 86 * optional 12 byte tag, which may be supported in the future. 87 */ 88 #define GCM_IV_LEN 12 89 #define GCM_AUTH_TAG_LEN 16 90 #define GCM_AUTH_TAG_LEN_8 8 91 92 #define FUNC_ENTRY() debug_print(srtp_mod_aes_gcm, "%s entry", __func__); 93 /* 94 * This function allocates a new instance of this crypto engine. 95 * The key_len parameter should be one of 28 or 44 for 96 * AES-128-GCM or AES-256-GCM respectively. Note that the 97 * key length includes the 14 byte salt value that is used when 98 * initializing the KDF. 99 */ 100 static srtp_err_status_t srtp_aes_gcm_mbedtls_alloc(srtp_cipher_t **c, 101 int key_len, 102 int tlen) 103 { 104 FUNC_ENTRY(); 105 srtp_aes_gcm_ctx_t *gcm; 106 107 debug_print(srtp_mod_aes_gcm, "allocating cipher with key length %d", 108 key_len); 109 debug_print(srtp_mod_aes_gcm, "allocating cipher with tag length %d", tlen); 110 111 /* 112 * Verify the key_len is valid for one of: AES-128/256 113 */ 114 if (key_len != SRTP_AES_GCM_128_KEY_LEN_WSALT && 115 key_len != SRTP_AES_GCM_256_KEY_LEN_WSALT) { 116 return (srtp_err_status_bad_param); 117 } 118 119 if (tlen != GCM_AUTH_TAG_LEN && tlen != GCM_AUTH_TAG_LEN_8) { 120 return (srtp_err_status_bad_param); 121 } 122 123 /* allocate memory a cipher of type aes_gcm */ 124 *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t)); 125 if (*c == NULL) { 126 return (srtp_err_status_alloc_fail); 127 } 128 129 gcm = (srtp_aes_gcm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_gcm_ctx_t)); 130 if (gcm == NULL) { 131 srtp_crypto_free(*c); 132 *c = NULL; 133 return (srtp_err_status_alloc_fail); 134 } 135 136 gcm->ctx = 137 (mbedtls_gcm_context *)srtp_crypto_alloc(sizeof(mbedtls_gcm_context)); 138 if (gcm->ctx == NULL) { 139 srtp_crypto_free(gcm); 140 srtp_crypto_free(*c); 141 *c = NULL; 142 return srtp_err_status_alloc_fail; 143 } 144 mbedtls_gcm_init(gcm->ctx); 145 146 /* set pointers */ 147 (*c)->state = gcm; 148 149 /* setup cipher attributes */ 150 switch (key_len) { 151 case SRTP_AES_GCM_128_KEY_LEN_WSALT: 152 (*c)->type = &srtp_aes_gcm_128; 153 (*c)->algorithm = SRTP_AES_GCM_128; 154 gcm->key_size = SRTP_AES_128_KEY_LEN; 155 gcm->tag_len = tlen; 156 break; 157 case SRTP_AES_GCM_256_KEY_LEN_WSALT: 158 (*c)->type = &srtp_aes_gcm_256; 159 (*c)->algorithm = SRTP_AES_GCM_256; 160 gcm->key_size = SRTP_AES_256_KEY_LEN; 161 gcm->tag_len = tlen; 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 a GCM session 173 */ 174 static srtp_err_status_t srtp_aes_gcm_mbedtls_dealloc(srtp_cipher_t *c) 175 { 176 srtp_aes_gcm_ctx_t *ctx; 177 FUNC_ENTRY(); 178 ctx = (srtp_aes_gcm_ctx_t *)c->state; 179 if (ctx) { 180 mbedtls_gcm_free(ctx->ctx); 181 srtp_crypto_free(ctx->ctx); 182 /* zeroize the key material */ 183 octet_string_set_to_zero(ctx, sizeof(srtp_aes_gcm_ctx_t)); 184 srtp_crypto_free(ctx); 185 } 186 187 /* free memory */ 188 srtp_crypto_free(c); 189 190 return (srtp_err_status_ok); 191 } 192 193 static srtp_err_status_t srtp_aes_gcm_mbedtls_context_init(void *cv, 194 const uint8_t *key) 195 { 196 FUNC_ENTRY(); 197 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; 198 uint32_t key_len_in_bits; 199 int errCode = 0; 200 c->dir = srtp_direction_any; 201 c->aad_size = 0; 202 203 debug_print(srtp_mod_aes_gcm, "key: %s", 204 srtp_octet_string_hex_string(key, c->key_size)); 205 key_len_in_bits = (c->key_size << 3); 206 switch (c->key_size) { 207 case SRTP_AES_256_KEY_LEN: 208 case SRTP_AES_128_KEY_LEN: 209 break; 210 default: 211 return (srtp_err_status_bad_param); 212 break; 213 } 214 215 errCode = mbedtls_gcm_setkey(c->ctx, MBEDTLS_CIPHER_ID_AES, 216 (const unsigned char *)key, key_len_in_bits); 217 if (errCode != 0) { 218 debug_print(srtp_mod_aes_gcm, "mbedtls error code: %d", errCode); 219 return srtp_err_status_init_fail; 220 } 221 222 return (srtp_err_status_ok); 223 } 224 225 static srtp_err_status_t srtp_aes_gcm_mbedtls_set_iv( 226 void *cv, 227 uint8_t *iv, 228 srtp_cipher_direction_t direction) 229 { 230 FUNC_ENTRY(); 231 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; 232 233 if (direction != srtp_direction_encrypt && 234 direction != srtp_direction_decrypt) { 235 return (srtp_err_status_bad_param); 236 } 237 c->dir = direction; 238 239 debug_print(srtp_mod_aes_gcm, "setting iv: %s", 240 srtp_octet_string_hex_string(iv, GCM_IV_LEN)); 241 c->iv_len = GCM_IV_LEN; 242 memcpy(c->iv, iv, c->iv_len); 243 return (srtp_err_status_ok); 244 } 245 246 /* 247 * This function processes the AAD 248 * 249 * Parameters: 250 * c Crypto context 251 * aad Additional data to process for AEAD cipher suites 252 * aad_len length of aad buffer 253 */ 254 static srtp_err_status_t srtp_aes_gcm_mbedtls_set_aad(void *cv, 255 const uint8_t *aad, 256 uint32_t aad_len) 257 { 258 FUNC_ENTRY(); 259 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; 260 261 debug_print(srtp_mod_aes_gcm, "setting AAD: %s", 262 srtp_octet_string_hex_string(aad, aad_len)); 263 264 if (aad_len + c->aad_size > MAX_AD_SIZE) { 265 return srtp_err_status_bad_param; 266 } 267 268 memcpy(c->aad + c->aad_size, aad, aad_len); 269 c->aad_size += aad_len; 270 271 return (srtp_err_status_ok); 272 } 273 274 /* 275 * This function encrypts a buffer using AES GCM mode 276 * 277 * Parameters: 278 * c Crypto context 279 * buf data to encrypt 280 * enc_len length of encrypt buffer 281 */ 282 static srtp_err_status_t srtp_aes_gcm_mbedtls_encrypt(void *cv, 283 unsigned char *buf, 284 unsigned int *enc_len) 285 { 286 FUNC_ENTRY(); 287 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; 288 int errCode = 0; 289 290 if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) { 291 return (srtp_err_status_bad_param); 292 } 293 294 errCode = mbedtls_gcm_crypt_and_tag(c->ctx, MBEDTLS_GCM_ENCRYPT, *enc_len, 295 c->iv, c->iv_len, c->aad, c->aad_size, 296 buf, buf, c->tag_len, c->tag); 297 298 c->aad_size = 0; 299 if (errCode != 0) { 300 debug_print(srtp_mod_aes_gcm, "mbedtls error code: %d", errCode); 301 return srtp_err_status_bad_param; 302 } 303 304 return (srtp_err_status_ok); 305 } 306 307 /* 308 * This function calculates and returns the GCM tag for a given context. 309 * This should be called after encrypting the data. The *len value 310 * is increased by the tag size. The caller must ensure that *buf has 311 * enough room to accept the appended tag. 312 * 313 * Parameters: 314 * c Crypto context 315 * buf data to encrypt 316 * len length of encrypt buffer 317 */ 318 static srtp_err_status_t srtp_aes_gcm_mbedtls_get_tag(void *cv, 319 uint8_t *buf, 320 uint32_t *len) 321 { 322 FUNC_ENTRY(); 323 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; 324 debug_print(srtp_mod_aes_gcm, "appended tag size: %d", c->tag_len); 325 *len = c->tag_len; 326 memcpy(buf, c->tag, c->tag_len); 327 return (srtp_err_status_ok); 328 } 329 330 /* 331 * This function decrypts a buffer using AES GCM mode 332 * 333 * Parameters: 334 * c Crypto context 335 * buf data to encrypt 336 * enc_len length of encrypt buffer 337 */ 338 static srtp_err_status_t srtp_aes_gcm_mbedtls_decrypt(void *cv, 339 unsigned char *buf, 340 unsigned int *enc_len) 341 { 342 FUNC_ENTRY(); 343 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; 344 int errCode = 0; 345 346 if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) { 347 return (srtp_err_status_bad_param); 348 } 349 350 debug_print(srtp_mod_aes_gcm, "AAD: %s", 351 srtp_octet_string_hex_string(c->aad, c->aad_size)); 352 353 errCode = mbedtls_gcm_auth_decrypt( 354 c->ctx, (*enc_len - c->tag_len), c->iv, c->iv_len, c->aad, c->aad_size, 355 buf + (*enc_len - c->tag_len), c->tag_len, buf, buf); 356 c->aad_size = 0; 357 if (errCode != 0) { 358 return (srtp_err_status_auth_fail); 359 } 360 361 /* 362 * Reduce the buffer size by the tag length since the tag 363 * is not part of the original payload 364 */ 365 *enc_len -= c->tag_len; 366 367 return (srtp_err_status_ok); 368 } 369 370 /* 371 * Name of this crypto engine 372 */ 373 static const char srtp_aes_gcm_128_mbedtls_description[] = 374 "AES-128 GCM using mbedtls"; 375 static const char srtp_aes_gcm_256_mbedtls_description[] = 376 "AES-256 GCM using mbedtls"; 377 378 /* 379 * This is the vector function table for this crypto engine. 380 */ 381 const srtp_cipher_type_t srtp_aes_gcm_128 = { 382 srtp_aes_gcm_mbedtls_alloc, 383 srtp_aes_gcm_mbedtls_dealloc, 384 srtp_aes_gcm_mbedtls_context_init, 385 srtp_aes_gcm_mbedtls_set_aad, 386 srtp_aes_gcm_mbedtls_encrypt, 387 srtp_aes_gcm_mbedtls_decrypt, 388 srtp_aes_gcm_mbedtls_set_iv, 389 srtp_aes_gcm_mbedtls_get_tag, 390 srtp_aes_gcm_128_mbedtls_description, 391 &srtp_aes_gcm_128_test_case_0, 392 SRTP_AES_GCM_128 393 }; 394 395 /* 396 * This is the vector function table for this crypto engine. 397 */ 398 const srtp_cipher_type_t srtp_aes_gcm_256 = { 399 srtp_aes_gcm_mbedtls_alloc, 400 srtp_aes_gcm_mbedtls_dealloc, 401 srtp_aes_gcm_mbedtls_context_init, 402 srtp_aes_gcm_mbedtls_set_aad, 403 srtp_aes_gcm_mbedtls_encrypt, 404 srtp_aes_gcm_mbedtls_decrypt, 405 srtp_aes_gcm_mbedtls_set_iv, 406 srtp_aes_gcm_mbedtls_get_tag, 407 srtp_aes_gcm_256_mbedtls_description, 408 &srtp_aes_gcm_256_test_case_0, 409 SRTP_AES_GCM_256 410 };