aes_gcm_ossl.c (12519B)
1 /* 2 * aes_gcm_ossl.c 3 * 4 * AES Galois Counter Mode 5 * 6 * John A. Foley 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 <openssl/evp.h> 52 #include "aes_gcm.h" 53 #include "alloc.h" 54 #include "err.h" /* for srtp_debug */ 55 #include "crypto_types.h" 56 #include "cipher_types.h" 57 #include "cipher_test_cases.h" 58 59 srtp_debug_module_t srtp_mod_aes_gcm = { 60 0, /* debugging is off by default */ 61 "aes gcm" /* 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_AUTH_TAG_LEN 16 69 #define GCM_AUTH_TAG_LEN_8 8 70 71 /* 72 * This function allocates a new instance of this crypto engine. 73 * The key_len parameter should be one of 28 or 44 for 74 * AES-128-GCM or AES-256-GCM respectively. Note that the 75 * key length includes the 14 byte salt value that is used when 76 * initializing the KDF. 77 */ 78 static srtp_err_status_t srtp_aes_gcm_openssl_alloc(srtp_cipher_t **c, 79 int key_len, 80 int tlen) 81 { 82 srtp_aes_gcm_ctx_t *gcm; 83 84 debug_print(srtp_mod_aes_gcm, "allocating cipher with key length %d", 85 key_len); 86 debug_print(srtp_mod_aes_gcm, "allocating cipher with tag length %d", tlen); 87 88 /* 89 * Verify the key_len is valid for one of: AES-128/256 90 */ 91 if (key_len != SRTP_AES_GCM_128_KEY_LEN_WSALT && 92 key_len != SRTP_AES_GCM_256_KEY_LEN_WSALT) { 93 return (srtp_err_status_bad_param); 94 } 95 96 if (tlen != GCM_AUTH_TAG_LEN && tlen != GCM_AUTH_TAG_LEN_8) { 97 return (srtp_err_status_bad_param); 98 } 99 100 /* allocate memory a cipher of type aes_gcm */ 101 *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t)); 102 if (*c == NULL) { 103 return (srtp_err_status_alloc_fail); 104 } 105 106 gcm = (srtp_aes_gcm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_gcm_ctx_t)); 107 if (gcm == NULL) { 108 srtp_crypto_free(*c); 109 *c = NULL; 110 return (srtp_err_status_alloc_fail); 111 } 112 113 gcm->ctx = EVP_CIPHER_CTX_new(); 114 if (gcm->ctx == NULL) { 115 srtp_crypto_free(gcm); 116 srtp_crypto_free(*c); 117 *c = NULL; 118 return srtp_err_status_alloc_fail; 119 } 120 121 /* set pointers */ 122 (*c)->state = gcm; 123 124 /* setup cipher attributes */ 125 switch (key_len) { 126 case SRTP_AES_GCM_128_KEY_LEN_WSALT: 127 (*c)->type = &srtp_aes_gcm_128; 128 (*c)->algorithm = SRTP_AES_GCM_128; 129 gcm->key_size = SRTP_AES_128_KEY_LEN; 130 gcm->tag_len = 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_len = tlen; 137 break; 138 } 139 140 /* set key size */ 141 (*c)->key_len = key_len; 142 143 return (srtp_err_status_ok); 144 } 145 146 /* 147 * This function deallocates a GCM session 148 */ 149 static srtp_err_status_t srtp_aes_gcm_openssl_dealloc(srtp_cipher_t *c) 150 { 151 srtp_aes_gcm_ctx_t *ctx; 152 153 ctx = (srtp_aes_gcm_ctx_t *)c->state; 154 if (ctx) { 155 EVP_CIPHER_CTX_free(ctx->ctx); 156 /* zeroize the key material */ 157 octet_string_set_to_zero(ctx, sizeof(srtp_aes_gcm_ctx_t)); 158 srtp_crypto_free(ctx); 159 } 160 161 /* free memory */ 162 srtp_crypto_free(c); 163 164 return (srtp_err_status_ok); 165 } 166 167 /* 168 * aes_gcm_openssl_context_init(...) initializes the aes_gcm_context 169 * using the value in key[]. 170 * 171 * the key is the secret key 172 */ 173 static srtp_err_status_t srtp_aes_gcm_openssl_context_init(void *cv, 174 const uint8_t *key) 175 { 176 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; 177 const EVP_CIPHER *evp; 178 179 c->dir = srtp_direction_any; 180 181 debug_print(srtp_mod_aes_gcm, "key: %s", 182 srtp_octet_string_hex_string(key, c->key_size)); 183 184 switch (c->key_size) { 185 case SRTP_AES_256_KEY_LEN: 186 evp = EVP_aes_256_gcm(); 187 break; 188 case SRTP_AES_128_KEY_LEN: 189 evp = EVP_aes_128_gcm(); 190 break; 191 default: 192 return (srtp_err_status_bad_param); 193 break; 194 } 195 196 EVP_CIPHER_CTX_reset(c->ctx); 197 198 if (!EVP_CipherInit_ex(c->ctx, evp, NULL, key, NULL, 0)) { 199 return (srtp_err_status_init_fail); 200 } 201 202 if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_IVLEN, 12, 0)) { 203 return (srtp_err_status_init_fail); 204 } 205 206 return (srtp_err_status_ok); 207 } 208 209 /* 210 * aes_gcm_openssl_set_iv(c, iv) sets the counter value to the exor of iv with 211 * the offset 212 */ 213 static srtp_err_status_t srtp_aes_gcm_openssl_set_iv( 214 void *cv, 215 uint8_t *iv, 216 srtp_cipher_direction_t direction) 217 { 218 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; 219 220 if (direction != srtp_direction_encrypt && 221 direction != srtp_direction_decrypt) { 222 return (srtp_err_status_bad_param); 223 } 224 c->dir = direction; 225 226 debug_print(srtp_mod_aes_gcm, "setting iv: %s", 227 srtp_octet_string_hex_string(iv, 12)); 228 229 if (!EVP_CipherInit_ex(c->ctx, NULL, NULL, NULL, iv, 230 (c->dir == srtp_direction_encrypt ? 1 : 0))) { 231 return (srtp_err_status_init_fail); 232 } 233 234 return (srtp_err_status_ok); 235 } 236 237 /* 238 * This function processes the AAD 239 * 240 * Parameters: 241 * c Crypto context 242 * aad Additional data to process for AEAD cipher suites 243 * aad_len length of aad buffer 244 */ 245 static srtp_err_status_t srtp_aes_gcm_openssl_set_aad(void *cv, 246 const uint8_t *aad, 247 uint32_t aad_len) 248 { 249 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; 250 int rv; 251 252 debug_print(srtp_mod_aes_gcm, "setting AAD: %s", 253 srtp_octet_string_hex_string(aad, aad_len)); 254 255 /* 256 * EVP_CTRL_GCM_SET_TAG can only be used when decrypting 257 */ 258 if (c->dir == srtp_direction_decrypt) { 259 /* 260 * Set dummy tag, OpenSSL requires the Tag to be set before 261 * processing AAD 262 */ 263 264 /* 265 * OpenSSL never write to address pointed by the last parameter of 266 * EVP_CIPHER_CTX_ctrl while EVP_CTRL_GCM_SET_TAG (in reality, 267 * OpenSSL copy its content to the context), so we can make 268 * aad read-only in this function and all its wrappers. 269 */ 270 unsigned char dummy_tag[GCM_AUTH_TAG_LEN]; 271 memset(dummy_tag, 0x0, GCM_AUTH_TAG_LEN); 272 if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, 273 &dummy_tag)) { 274 return (srtp_err_status_algo_fail); 275 } 276 } 277 278 rv = EVP_Cipher(c->ctx, NULL, aad, aad_len); 279 if (rv < 0 || (uint32_t)rv != aad_len) { 280 return (srtp_err_status_algo_fail); 281 } else { 282 return (srtp_err_status_ok); 283 } 284 } 285 286 /* 287 * This function encrypts a buffer using AES GCM mode 288 * 289 * Parameters: 290 * c Crypto context 291 * buf data to encrypt 292 * enc_len length of encrypt buffer 293 */ 294 static srtp_err_status_t srtp_aes_gcm_openssl_encrypt(void *cv, 295 unsigned char *buf, 296 unsigned int *enc_len) 297 { 298 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; 299 if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) { 300 return (srtp_err_status_bad_param); 301 } 302 303 /* 304 * Encrypt the data 305 */ 306 EVP_Cipher(c->ctx, buf, buf, *enc_len); 307 308 return (srtp_err_status_ok); 309 } 310 311 /* 312 * This function calculates and returns the GCM tag for a given context. 313 * This should be called after encrypting the data. The *len value 314 * is increased by the tag size. The caller must ensure that *buf has 315 * enough room to accept the appended tag. 316 * 317 * Parameters: 318 * c Crypto context 319 * buf data to encrypt 320 * len length of encrypt buffer 321 */ 322 static srtp_err_status_t srtp_aes_gcm_openssl_get_tag(void *cv, 323 uint8_t *buf, 324 uint32_t *len) 325 { 326 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; 327 /* 328 * Calculate the tag 329 */ 330 EVP_Cipher(c->ctx, NULL, NULL, 0); 331 332 /* 333 * Retreive the tag 334 */ 335 if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_GET_TAG, c->tag_len, buf)) { 336 return (srtp_err_status_algo_fail); 337 } 338 339 /* 340 * Increase encryption length by desired tag size 341 */ 342 *len = c->tag_len; 343 344 return (srtp_err_status_ok); 345 } 346 347 /* 348 * This function decrypts a buffer using AES GCM mode 349 * 350 * Parameters: 351 * c Crypto context 352 * buf data to encrypt 353 * enc_len length of encrypt buffer 354 */ 355 static srtp_err_status_t srtp_aes_gcm_openssl_decrypt(void *cv, 356 unsigned char *buf, 357 unsigned int *enc_len) 358 { 359 srtp_aes_gcm_ctx_t *c = (srtp_aes_gcm_ctx_t *)cv; 360 if (c->dir != srtp_direction_encrypt && c->dir != srtp_direction_decrypt) { 361 return (srtp_err_status_bad_param); 362 } 363 364 /* 365 * Set the tag before decrypting 366 */ 367 if (!EVP_CIPHER_CTX_ctrl(c->ctx, EVP_CTRL_GCM_SET_TAG, c->tag_len, 368 buf + (*enc_len - c->tag_len))) { 369 return (srtp_err_status_auth_fail); 370 } 371 EVP_Cipher(c->ctx, buf, buf, *enc_len - c->tag_len); 372 373 /* 374 * Check the tag 375 */ 376 if (EVP_Cipher(c->ctx, NULL, NULL, 0)) { 377 return (srtp_err_status_auth_fail); 378 } 379 380 /* 381 * Reduce the buffer size by the tag length since the tag 382 * is not part of the original payload 383 */ 384 *enc_len -= c->tag_len; 385 386 return (srtp_err_status_ok); 387 } 388 389 /* 390 * Name of this crypto engine 391 */ 392 static const char srtp_aes_gcm_128_openssl_description[] = 393 "AES-128 GCM using openssl"; 394 static const char srtp_aes_gcm_256_openssl_description[] = 395 "AES-256 GCM using openssl"; 396 397 /* 398 * This is the vector function table for this crypto engine. 399 */ 400 const srtp_cipher_type_t srtp_aes_gcm_128 = { 401 srtp_aes_gcm_openssl_alloc, 402 srtp_aes_gcm_openssl_dealloc, 403 srtp_aes_gcm_openssl_context_init, 404 srtp_aes_gcm_openssl_set_aad, 405 srtp_aes_gcm_openssl_encrypt, 406 srtp_aes_gcm_openssl_decrypt, 407 srtp_aes_gcm_openssl_set_iv, 408 srtp_aes_gcm_openssl_get_tag, 409 srtp_aes_gcm_128_openssl_description, 410 &srtp_aes_gcm_128_test_case_0, 411 SRTP_AES_GCM_128 412 }; 413 414 /* 415 * This is the vector function table for this crypto engine. 416 */ 417 const srtp_cipher_type_t srtp_aes_gcm_256 = { 418 srtp_aes_gcm_openssl_alloc, 419 srtp_aes_gcm_openssl_dealloc, 420 srtp_aes_gcm_openssl_context_init, 421 srtp_aes_gcm_openssl_set_aad, 422 srtp_aes_gcm_openssl_encrypt, 423 srtp_aes_gcm_openssl_decrypt, 424 srtp_aes_gcm_openssl_set_iv, 425 srtp_aes_gcm_openssl_get_tag, 426 srtp_aes_gcm_256_openssl_description, 427 &srtp_aes_gcm_256_test_case_0, 428 SRTP_AES_GCM_256 429 };