aes_icm_mbedtls.c (12403B)
1 /* 2 * aes_icm_mbedtls.c 3 * 4 * AES Integer Counter Mode 5 * 6 * YongCheng Yang 7 */ 8 9 /* 10 * 11 * Copyright (c) 2013-2017, Cisco Systems, Inc. 12 * All rights reserved. 13 * 14 * Redistribution and use in source and binary forms, with or without 15 * modification, are permitted provided that the following conditions 16 * are met: 17 * 18 * Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 21 * Redistributions in binary form must reproduce the above 22 * copyright notice, this list of conditions and the following 23 * disclaimer in the documentation and/or other materials provided 24 * with the distribution. 25 * 26 * Neither the name of the Cisco Systems, Inc. nor the names of its 27 * contributors may be used to endorse or promote products derived 28 * from this software without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 31 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 32 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 33 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 34 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 35 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 37 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 40 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 41 * OF THE POSSIBILITY OF SUCH DAMAGE. 42 * 43 */ 44 45 #ifdef HAVE_CONFIG_H 46 #include <config.h> 47 #endif 48 #include <mbedtls/aes.h> 49 #include "aes_icm_ext.h" 50 #include "crypto_types.h" 51 #include "err.h" /* for srtp_debug */ 52 #include "alloc.h" 53 #include "cipher_types.h" 54 #include "cipher_test_cases.h" 55 56 srtp_debug_module_t srtp_mod_aes_icm = { 57 0, /* debugging is off by default */ 58 "aes icm mbedtls" /* printable module name */ 59 }; 60 61 /* 62 * integer counter mode works as follows: 63 * 64 * https://tools.ietf.org/html/rfc3711#section-4.1.1 65 * 66 * E(k, IV) || E(k, IV + 1 mod 2^128) || E(k, IV + 2 mod 2^128) ... 67 * IV = (k_s * 2^16) XOR (SSRC * 2^64) XOR (i * 2^16) 68 * 69 * IV SHALL be defined by the SSRC, the SRTP packet index i, 70 * and the SRTP session salting key k_s. 71 * 72 * SSRC: 32bits. 73 * Sequence number: 16bits. 74 * nonce is 64bits. . 75 * packet index = ROC || SEQ. (ROC: Rollover counter) 76 * 77 * 16 bits 78 * <-----> 79 * +------+------+------+------+------+------+------+------+ 80 * | nonce | packet index | ctr |---+ 81 * +------+------+------+------+------+------+------+------+ | 82 * | 83 * +------+------+------+------+------+------+------+------+ v 84 * | salt |000000|->(+) 85 * +------+------+------+------+------+------+------+------+ | 86 * | 87 * +---------+ 88 * | encrypt | 89 * +---------+ 90 * | 91 * +------+------+------+------+------+------+------+------+ | 92 * | keystream block |<--+ 93 * +------+------+------+------+------+------+------+------+ 94 * 95 * All fields are big-endian 96 * 97 * ctr is the block counter, which increments from zero for 98 * each packet (16 bits wide) 99 * 100 * packet index is distinct for each packet (48 bits wide) 101 * 102 * nonce can be distinct across many uses of the same key, or 103 * can be a fixed value per key, or can be per-packet randomness 104 * (64 bits) 105 * 106 */ 107 108 /* 109 * This function allocates a new instance of this crypto engine. 110 * The key_len parameter should be one of 30, 38, or 46 for 111 * AES-128, AES-192, and AES-256 respectively. Note, this key_len 112 * value is inflated, as it also accounts for the 112 bit salt 113 * value. The tlen argument is for the AEAD tag length, which 114 * isn't used in counter mode. 115 */ 116 static srtp_err_status_t srtp_aes_icm_mbedtls_alloc(srtp_cipher_t **c, 117 int key_len, 118 int tlen) 119 { 120 srtp_aes_icm_ctx_t *icm; 121 (void)tlen; 122 123 debug_print(srtp_mod_aes_icm, "allocating cipher with key length %d", 124 key_len); 125 126 /* 127 * Verify the key_len is valid for one of: AES-128/192/256 128 */ 129 if (key_len != SRTP_AES_ICM_128_KEY_LEN_WSALT && 130 key_len != SRTP_AES_ICM_192_KEY_LEN_WSALT && 131 key_len != SRTP_AES_ICM_256_KEY_LEN_WSALT) { 132 return srtp_err_status_bad_param; 133 } 134 135 /* allocate memory a cipher of type aes_icm */ 136 *c = (srtp_cipher_t *)srtp_crypto_alloc(sizeof(srtp_cipher_t)); 137 if (*c == NULL) { 138 return srtp_err_status_alloc_fail; 139 } 140 141 icm = (srtp_aes_icm_ctx_t *)srtp_crypto_alloc(sizeof(srtp_aes_icm_ctx_t)); 142 if (icm == NULL) { 143 srtp_crypto_free(*c); 144 *c = NULL; 145 return srtp_err_status_alloc_fail; 146 } 147 148 icm->ctx = 149 (mbedtls_aes_context *)srtp_crypto_alloc(sizeof(mbedtls_aes_context)); 150 if (icm->ctx == NULL) { 151 srtp_crypto_free(icm); 152 srtp_crypto_free(*c); 153 *c = NULL; 154 return srtp_err_status_alloc_fail; 155 } 156 157 mbedtls_aes_init(icm->ctx); 158 159 /* set pointers */ 160 (*c)->state = icm; 161 162 /* setup cipher parameters */ 163 switch (key_len) { 164 case SRTP_AES_ICM_128_KEY_LEN_WSALT: 165 (*c)->algorithm = SRTP_AES_ICM_128; 166 (*c)->type = &srtp_aes_icm_128; 167 icm->key_size = SRTP_AES_128_KEY_LEN; 168 break; 169 case SRTP_AES_ICM_192_KEY_LEN_WSALT: 170 (*c)->algorithm = SRTP_AES_ICM_192; 171 (*c)->type = &srtp_aes_icm_192; 172 icm->key_size = SRTP_AES_192_KEY_LEN; 173 break; 174 case SRTP_AES_ICM_256_KEY_LEN_WSALT: 175 (*c)->algorithm = SRTP_AES_ICM_256; 176 (*c)->type = &srtp_aes_icm_256; 177 icm->key_size = SRTP_AES_256_KEY_LEN; 178 break; 179 } 180 181 /* set key size */ 182 (*c)->key_len = key_len; 183 184 return srtp_err_status_ok; 185 } 186 187 /* 188 * This function deallocates an instance of this engine 189 */ 190 static srtp_err_status_t srtp_aes_icm_mbedtls_dealloc(srtp_cipher_t *c) 191 { 192 srtp_aes_icm_ctx_t *ctx; 193 194 if (c == NULL) { 195 return srtp_err_status_bad_param; 196 } 197 198 /* 199 * Free the aes context 200 */ 201 ctx = (srtp_aes_icm_ctx_t *)c->state; 202 if (ctx != NULL) { 203 mbedtls_aes_free(ctx->ctx); 204 srtp_crypto_free(ctx->ctx); 205 /* zeroize the key material */ 206 octet_string_set_to_zero(ctx, sizeof(srtp_aes_icm_ctx_t)); 207 srtp_crypto_free(ctx); 208 } 209 210 /* free memory */ 211 srtp_crypto_free(c); 212 213 return srtp_err_status_ok; 214 } 215 216 static srtp_err_status_t srtp_aes_icm_mbedtls_context_init(void *cv, 217 const uint8_t *key) 218 { 219 srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv; 220 uint32_t key_size_in_bits = (c->key_size << 3); 221 int errcode = 0; 222 223 /* 224 * set counter and initial values to 'offset' value, being careful not to 225 * go past the end of the key buffer 226 */ 227 v128_set_to_zero(&c->counter); 228 v128_set_to_zero(&c->offset); 229 memcpy(&c->counter, key + c->key_size, SRTP_SALT_LEN); 230 memcpy(&c->offset, key + c->key_size, SRTP_SALT_LEN); 231 232 /* force last two octets of the offset to zero (for srtp compatibility) */ 233 c->offset.v8[SRTP_SALT_LEN] = c->offset.v8[SRTP_SALT_LEN + 1] = 0; 234 c->counter.v8[SRTP_SALT_LEN] = c->counter.v8[SRTP_SALT_LEN + 1] = 0; 235 debug_print(srtp_mod_aes_icm, "key: %s", 236 srtp_octet_string_hex_string(key, c->key_size)); 237 debug_print(srtp_mod_aes_icm, "offset: %s", v128_hex_string(&c->offset)); 238 239 switch (c->key_size) { 240 case SRTP_AES_256_KEY_LEN: 241 case SRTP_AES_192_KEY_LEN: 242 case SRTP_AES_128_KEY_LEN: 243 break; 244 default: 245 return srtp_err_status_bad_param; 246 break; 247 } 248 249 errcode = mbedtls_aes_setkey_enc(c->ctx, key, key_size_in_bits); 250 if (errcode != 0) { 251 debug_print(srtp_mod_aes_icm, "errCode: %d", errcode); 252 } 253 254 return srtp_err_status_ok; 255 } 256 257 /* 258 * aes_icm_set_iv(c, iv) sets the counter value to the exor of iv with 259 * the offset 260 */ 261 static srtp_err_status_t srtp_aes_icm_mbedtls_set_iv( 262 void *cv, 263 uint8_t *iv, 264 srtp_cipher_direction_t dir) 265 { 266 srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv; 267 v128_t nonce; 268 (void)dir; 269 270 c->nc_off = 0; 271 /* set nonce (for alignment) */ 272 v128_copy_octet_string(&nonce, iv); 273 274 debug_print(srtp_mod_aes_icm, "setting iv: %s", v128_hex_string(&nonce)); 275 276 v128_xor(&c->counter, &c->offset, &nonce); 277 278 debug_print(srtp_mod_aes_icm, "set_counter: %s", 279 v128_hex_string(&c->counter)); 280 281 return srtp_err_status_ok; 282 } 283 284 /* 285 * This function encrypts a buffer using AES CTR mode 286 * 287 * Parameters: 288 * c Crypto context 289 * buf data to encrypt 290 * enc_len length of encrypt buffer 291 */ 292 static srtp_err_status_t srtp_aes_icm_mbedtls_encrypt(void *cv, 293 unsigned char *buf, 294 unsigned int *enc_len) 295 { 296 srtp_aes_icm_ctx_t *c = (srtp_aes_icm_ctx_t *)cv; 297 298 int errCode = 0; 299 debug_print(srtp_mod_aes_icm, "rs0: %s", v128_hex_string(&c->counter)); 300 301 errCode = 302 mbedtls_aes_crypt_ctr(c->ctx, *enc_len, &(c->nc_off), c->counter.v8, 303 c->stream_block.v8, buf, buf); 304 if (errCode != 0) { 305 debug_print(srtp_mod_aes_icm, "encrypt error: %d", errCode); 306 return srtp_err_status_cipher_fail; 307 } 308 309 return srtp_err_status_ok; 310 } 311 312 /* 313 * Name of this crypto engine 314 */ 315 static const char srtp_aes_icm_128_mbedtls_description[] = 316 "AES-128 counter mode using mbedtls"; 317 static const char srtp_aes_icm_192_mbedtls_description[] = 318 "AES-192 counter mode using mbedtls"; 319 static const char srtp_aes_icm_256_mbedtls_description[] = 320 "AES-256 counter mode using mbedtls"; 321 322 /* 323 * This is the function table for this crypto engine. 324 * note: the encrypt function is identical to the decrypt function 325 */ 326 const srtp_cipher_type_t srtp_aes_icm_128 = { 327 srtp_aes_icm_mbedtls_alloc, /* */ 328 srtp_aes_icm_mbedtls_dealloc, /* */ 329 srtp_aes_icm_mbedtls_context_init, /* */ 330 0, /* set_aad */ 331 srtp_aes_icm_mbedtls_encrypt, /* */ 332 srtp_aes_icm_mbedtls_encrypt, /* */ 333 srtp_aes_icm_mbedtls_set_iv, /* */ 334 0, /* get_tag */ 335 srtp_aes_icm_128_mbedtls_description, /* */ 336 &srtp_aes_icm_128_test_case_0, /* */ 337 SRTP_AES_ICM_128 /* */ 338 }; 339 340 /* 341 * This is the function table for this crypto engine. 342 * note: the encrypt function is identical to the decrypt function 343 */ 344 const srtp_cipher_type_t srtp_aes_icm_192 = { 345 srtp_aes_icm_mbedtls_alloc, /* */ 346 srtp_aes_icm_mbedtls_dealloc, /* */ 347 srtp_aes_icm_mbedtls_context_init, /* */ 348 0, /* set_aad */ 349 srtp_aes_icm_mbedtls_encrypt, /* */ 350 srtp_aes_icm_mbedtls_encrypt, /* */ 351 srtp_aes_icm_mbedtls_set_iv, /* */ 352 0, /* get_tag */ 353 srtp_aes_icm_192_mbedtls_description, /* */ 354 &srtp_aes_icm_192_test_case_0, /* */ 355 SRTP_AES_ICM_192 /* */ 356 }; 357 358 /* 359 * This is the function table for this crypto engine. 360 * note: the encrypt function is identical to the decrypt function 361 */ 362 const srtp_cipher_type_t srtp_aes_icm_256 = { 363 srtp_aes_icm_mbedtls_alloc, /* */ 364 srtp_aes_icm_mbedtls_dealloc, /* */ 365 srtp_aes_icm_mbedtls_context_init, /* */ 366 0, /* set_aad */ 367 srtp_aes_icm_mbedtls_encrypt, /* */ 368 srtp_aes_icm_mbedtls_encrypt, /* */ 369 srtp_aes_icm_mbedtls_set_iv, /* */ 370 0, /* get_tag */ 371 srtp_aes_icm_256_mbedtls_description, /* */ 372 &srtp_aes_icm_256_test_case_0, /* */ 373 SRTP_AES_ICM_256 /* */ 374 };