1/* 2 * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved. 3 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 4 * 5 * Licensed under the Apache License 2.0 (the "License"). You may not use 6 * this file except in compliance with the License. You can obtain a copy 7 * in the file LICENSE in the source distribution or at 8 * https://www.openssl.org/source/license.html 9 */ 10 11#include "internal/deprecated.h" 12 13#include "internal/cryptlib.h" 14#ifndef OPENSSL_NO_ARIA 15# include <openssl/evp.h> 16# include <openssl/modes.h> 17# include <openssl/rand.h> 18# include "crypto/aria.h" 19# include "crypto/evp.h" 20# include "crypto/modes.h" 21# include "evp_local.h" 22 23/* ARIA subkey Structure */ 24typedef struct { 25 ARIA_KEY ks; 26} EVP_ARIA_KEY; 27 28/* ARIA GCM context */ 29typedef struct { 30 union { 31 OSSL_UNION_ALIGN; 32 ARIA_KEY ks; 33 } ks; /* ARIA subkey to use */ 34 int key_set; /* Set if key initialised */ 35 int iv_set; /* Set if an iv is set */ 36 GCM128_CONTEXT gcm; 37 unsigned char *iv; /* Temporary IV store */ 38 int ivlen; /* IV length */ 39 int taglen; 40 int iv_gen; /* It is OK to generate IVs */ 41 int tls_aad_len; /* TLS AAD length */ 42} EVP_ARIA_GCM_CTX; 43 44/* ARIA CCM context */ 45typedef struct { 46 union { 47 OSSL_UNION_ALIGN; 48 ARIA_KEY ks; 49 } ks; /* ARIA key schedule to use */ 50 int key_set; /* Set if key initialised */ 51 int iv_set; /* Set if an iv is set */ 52 int tag_set; /* Set if tag is valid */ 53 int len_set; /* Set if message length set */ 54 int L, M; /* L and M parameters from RFC3610 */ 55 int tls_aad_len; /* TLS AAD length */ 56 CCM128_CONTEXT ccm; 57 ccm128_f str; 58} EVP_ARIA_CCM_CTX; 59 60/* The subkey for ARIA is generated. */ 61static int aria_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 62 const unsigned char *iv, int enc) 63{ 64 int ret; 65 int mode = EVP_CIPHER_CTX_get_mode(ctx); 66 67 if (enc || (mode != EVP_CIPH_ECB_MODE && mode != EVP_CIPH_CBC_MODE)) 68 ret = ossl_aria_set_encrypt_key(key, 69 EVP_CIPHER_CTX_get_key_length(ctx) * 8, 70 EVP_CIPHER_CTX_get_cipher_data(ctx)); 71 else 72 ret = ossl_aria_set_decrypt_key(key, 73 EVP_CIPHER_CTX_get_key_length(ctx) * 8, 74 EVP_CIPHER_CTX_get_cipher_data(ctx)); 75 if (ret < 0) { 76 ERR_raise(ERR_LIB_EVP,EVP_R_ARIA_KEY_SETUP_FAILED); 77 return 0; 78 } 79 return 1; 80} 81 82static void aria_cbc_encrypt(const unsigned char *in, unsigned char *out, 83 size_t len, const ARIA_KEY *key, 84 unsigned char *ivec, const int enc) 85{ 86 87 if (enc) 88 CRYPTO_cbc128_encrypt(in, out, len, key, ivec, 89 (block128_f) ossl_aria_encrypt); 90 else 91 CRYPTO_cbc128_decrypt(in, out, len, key, ivec, 92 (block128_f) ossl_aria_encrypt); 93} 94 95static void aria_cfb128_encrypt(const unsigned char *in, unsigned char *out, 96 size_t length, const ARIA_KEY *key, 97 unsigned char *ivec, int *num, const int enc) 98{ 99 100 CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, 101 (block128_f) ossl_aria_encrypt); 102} 103 104static void aria_cfb1_encrypt(const unsigned char *in, unsigned char *out, 105 size_t length, const ARIA_KEY *key, 106 unsigned char *ivec, int *num, const int enc) 107{ 108 CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc, 109 (block128_f) ossl_aria_encrypt); 110} 111 112static void aria_cfb8_encrypt(const unsigned char *in, unsigned char *out, 113 size_t length, const ARIA_KEY *key, 114 unsigned char *ivec, int *num, const int enc) 115{ 116 CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc, 117 (block128_f) ossl_aria_encrypt); 118} 119 120static void aria_ecb_encrypt(const unsigned char *in, unsigned char *out, 121 const ARIA_KEY *key, const int enc) 122{ 123 ossl_aria_encrypt(in, out, key); 124} 125 126static void aria_ofb128_encrypt(const unsigned char *in, unsigned char *out, 127 size_t length, const ARIA_KEY *key, 128 unsigned char *ivec, int *num) 129{ 130 CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, 131 (block128_f) ossl_aria_encrypt); 132} 133 134IMPLEMENT_BLOCK_CIPHER(aria_128, ks, aria, EVP_ARIA_KEY, 135 NID_aria_128, 16, 16, 16, 128, 136 0, aria_init_key, NULL, 137 EVP_CIPHER_set_asn1_iv, 138 EVP_CIPHER_get_asn1_iv, 139 NULL) 140IMPLEMENT_BLOCK_CIPHER(aria_192, ks, aria, EVP_ARIA_KEY, 141 NID_aria_192, 16, 24, 16, 128, 142 0, aria_init_key, NULL, 143 EVP_CIPHER_set_asn1_iv, 144 EVP_CIPHER_get_asn1_iv, 145 NULL) 146IMPLEMENT_BLOCK_CIPHER(aria_256, ks, aria, EVP_ARIA_KEY, 147 NID_aria_256, 16, 32, 16, 128, 148 0, aria_init_key, NULL, 149 EVP_CIPHER_set_asn1_iv, 150 EVP_CIPHER_get_asn1_iv, 151 NULL) 152 153# define IMPLEMENT_ARIA_CFBR(ksize,cbits) \ 154 IMPLEMENT_CFBR(aria,aria,EVP_ARIA_KEY,ks,ksize,cbits,16,0) 155IMPLEMENT_ARIA_CFBR(128,1) 156IMPLEMENT_ARIA_CFBR(192,1) 157IMPLEMENT_ARIA_CFBR(256,1) 158IMPLEMENT_ARIA_CFBR(128,8) 159IMPLEMENT_ARIA_CFBR(192,8) 160IMPLEMENT_ARIA_CFBR(256,8) 161 162# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ 163static const EVP_CIPHER aria_##keylen##_##mode = { \ 164 nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ 165 flags|EVP_CIPH_##MODE##_MODE, \ 166 EVP_ORIG_GLOBAL, \ 167 aria_init_key, \ 168 aria_##mode##_cipher, \ 169 NULL, \ 170 sizeof(EVP_ARIA_KEY), \ 171 NULL,NULL,NULL,NULL }; \ 172const EVP_CIPHER *EVP_aria_##keylen##_##mode(void) \ 173{ return &aria_##keylen##_##mode; } 174 175static int aria_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 176 const unsigned char *in, size_t len) 177{ 178 int n = EVP_CIPHER_CTX_get_num(ctx); 179 unsigned int num; 180 EVP_ARIA_KEY *dat = EVP_C_DATA(EVP_ARIA_KEY, ctx); 181 182 if (n < 0) 183 return 0; 184 num = (unsigned int)n; 185 186 CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, 187 EVP_CIPHER_CTX_buf_noconst(ctx), &num, 188 (block128_f) ossl_aria_encrypt); 189 EVP_CIPHER_CTX_set_num(ctx, num); 190 return 1; 191} 192 193BLOCK_CIPHER_generic(NID_aria, 128, 1, 16, ctr, ctr, CTR, 0) 194BLOCK_CIPHER_generic(NID_aria, 192, 1, 16, ctr, ctr, CTR, 0) 195BLOCK_CIPHER_generic(NID_aria, 256, 1, 16, ctr, ctr, CTR, 0) 196 197/* Authenticated cipher modes (GCM/CCM) */ 198 199/* increment counter (64-bit int) by 1 */ 200static void ctr64_inc(unsigned char *counter) 201{ 202 int n = 8; 203 unsigned char c; 204 205 do { 206 --n; 207 c = counter[n]; 208 ++c; 209 counter[n] = c; 210 if (c) 211 return; 212 } while (n); 213} 214 215static int aria_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 216 const unsigned char *iv, int enc) 217{ 218 int ret; 219 EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx); 220 221 if (!iv && !key) 222 return 1; 223 if (key) { 224 ret = ossl_aria_set_encrypt_key(key, 225 EVP_CIPHER_CTX_get_key_length(ctx) * 8, 226 &gctx->ks.ks); 227 CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, 228 (block128_f) ossl_aria_encrypt); 229 if (ret < 0) { 230 ERR_raise(ERR_LIB_EVP,EVP_R_ARIA_KEY_SETUP_FAILED); 231 return 0; 232 } 233 234 /* 235 * If we have an iv can set it directly, otherwise use saved IV. 236 */ 237 if (iv == NULL && gctx->iv_set) 238 iv = gctx->iv; 239 if (iv) { 240 CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); 241 gctx->iv_set = 1; 242 } 243 gctx->key_set = 1; 244 } else { 245 /* If key set use IV, otherwise copy */ 246 if (gctx->key_set) 247 CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); 248 else 249 memcpy(gctx->iv, iv, gctx->ivlen); 250 gctx->iv_set = 1; 251 gctx->iv_gen = 0; 252 } 253 return 1; 254} 255 256static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 257{ 258 EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,c); 259 260 switch (type) { 261 case EVP_CTRL_INIT: 262 gctx->key_set = 0; 263 gctx->iv_set = 0; 264 gctx->ivlen = EVP_CIPHER_get_iv_length(c->cipher); 265 gctx->iv = c->iv; 266 gctx->taglen = -1; 267 gctx->iv_gen = 0; 268 gctx->tls_aad_len = -1; 269 return 1; 270 271 case EVP_CTRL_GET_IVLEN: 272 *(int *)ptr = gctx->ivlen; 273 return 1; 274 275 case EVP_CTRL_AEAD_SET_IVLEN: 276 if (arg <= 0) 277 return 0; 278 /* Allocate memory for IV if needed */ 279 if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { 280 if (gctx->iv != c->iv) 281 OPENSSL_free(gctx->iv); 282 if ((gctx->iv = OPENSSL_malloc(arg)) == NULL) { 283 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); 284 return 0; 285 } 286 } 287 gctx->ivlen = arg; 288 return 1; 289 290 case EVP_CTRL_AEAD_SET_TAG: 291 if (arg <= 0 || arg > 16 || EVP_CIPHER_CTX_is_encrypting(c)) 292 return 0; 293 memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg); 294 gctx->taglen = arg; 295 return 1; 296 297 case EVP_CTRL_AEAD_GET_TAG: 298 if (arg <= 0 || arg > 16 || !EVP_CIPHER_CTX_is_encrypting(c) 299 || gctx->taglen < 0) 300 return 0; 301 memcpy(ptr, EVP_CIPHER_CTX_buf_noconst(c), arg); 302 return 1; 303 304 case EVP_CTRL_GCM_SET_IV_FIXED: 305 /* Special case: -1 length restores whole IV */ 306 if (arg == -1) { 307 memcpy(gctx->iv, ptr, gctx->ivlen); 308 gctx->iv_gen = 1; 309 return 1; 310 } 311 /* 312 * Fixed field must be at least 4 bytes and invocation field at least 313 * 8. 314 */ 315 if ((arg < 4) || (gctx->ivlen - arg) < 8) 316 return 0; 317 if (arg) 318 memcpy(gctx->iv, ptr, arg); 319 if (EVP_CIPHER_CTX_is_encrypting(c) 320 && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) 321 return 0; 322 gctx->iv_gen = 1; 323 return 1; 324 325 case EVP_CTRL_GCM_IV_GEN: 326 if (gctx->iv_gen == 0 || gctx->key_set == 0) 327 return 0; 328 CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); 329 if (arg <= 0 || arg > gctx->ivlen) 330 arg = gctx->ivlen; 331 memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); 332 /* 333 * Invocation field will be at least 8 bytes in size and so no need 334 * to check wrap around or increment more than last 8 bytes. 335 */ 336 ctr64_inc(gctx->iv + gctx->ivlen - 8); 337 gctx->iv_set = 1; 338 return 1; 339 340 case EVP_CTRL_GCM_SET_IV_INV: 341 if (gctx->iv_gen == 0 || gctx->key_set == 0 342 || EVP_CIPHER_CTX_is_encrypting(c)) 343 return 0; 344 memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); 345 CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); 346 gctx->iv_set = 1; 347 return 1; 348 349 case EVP_CTRL_AEAD_TLS1_AAD: 350 /* Save the AAD for later use */ 351 if (arg != EVP_AEAD_TLS1_AAD_LEN) 352 return 0; 353 memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg); 354 gctx->tls_aad_len = arg; 355 { 356 unsigned int len = 357 EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8 358 | EVP_CIPHER_CTX_buf_noconst(c)[arg - 1]; 359 /* Correct length for explicit IV */ 360 if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN) 361 return 0; 362 len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; 363 /* If decrypting correct for tag too */ 364 if (!EVP_CIPHER_CTX_is_encrypting(c)) { 365 if (len < EVP_GCM_TLS_TAG_LEN) 366 return 0; 367 len -= EVP_GCM_TLS_TAG_LEN; 368 } 369 EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8; 370 EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff; 371 } 372 /* Extra padding: tag appended to record */ 373 return EVP_GCM_TLS_TAG_LEN; 374 375 case EVP_CTRL_COPY: 376 { 377 EVP_CIPHER_CTX *out = ptr; 378 EVP_ARIA_GCM_CTX *gctx_out = EVP_C_DATA(EVP_ARIA_GCM_CTX,out); 379 if (gctx->gcm.key) { 380 if (gctx->gcm.key != &gctx->ks) 381 return 0; 382 gctx_out->gcm.key = &gctx_out->ks; 383 } 384 if (gctx->iv == c->iv) 385 gctx_out->iv = out->iv; 386 else { 387 if ((gctx_out->iv = OPENSSL_malloc(gctx->ivlen)) == NULL) { 388 ERR_raise(ERR_LIB_EVP, ERR_R_MALLOC_FAILURE); 389 return 0; 390 } 391 memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); 392 } 393 return 1; 394 } 395 396 default: 397 return -1; 398 399 } 400} 401 402static int aria_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 403 const unsigned char *in, size_t len) 404{ 405 EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx); 406 int rv = -1; 407 408 /* Encrypt/decrypt must be performed in place */ 409 if (out != in 410 || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) 411 return -1; 412 /* 413 * Set IV from start of buffer or generate IV and write to start of 414 * buffer. 415 */ 416 if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CIPHER_CTX_is_encrypting(ctx) ? 417 EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, 418 EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) 419 goto err; 420 /* Use saved AAD */ 421 if (CRYPTO_gcm128_aad(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), 422 gctx->tls_aad_len)) 423 goto err; 424 /* Fix buffer and length to point to payload */ 425 in += EVP_GCM_TLS_EXPLICIT_IV_LEN; 426 out += EVP_GCM_TLS_EXPLICIT_IV_LEN; 427 len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; 428 if (EVP_CIPHER_CTX_is_encrypting(ctx)) { 429 /* Encrypt payload */ 430 if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) 431 goto err; 432 out += len; 433 /* Finally write tag */ 434 CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN); 435 rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; 436 } else { 437 /* Decrypt */ 438 if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) 439 goto err; 440 /* Retrieve tag */ 441 CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), 442 EVP_GCM_TLS_TAG_LEN); 443 /* If tag mismatch wipe buffer */ 444 if (CRYPTO_memcmp(EVP_CIPHER_CTX_buf_noconst(ctx), in + len, 445 EVP_GCM_TLS_TAG_LEN)) { 446 OPENSSL_cleanse(out, len); 447 goto err; 448 } 449 rv = len; 450 } 451 452 err: 453 gctx->iv_set = 0; 454 gctx->tls_aad_len = -1; 455 return rv; 456} 457 458static int aria_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 459 const unsigned char *in, size_t len) 460{ 461 EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx); 462 463 /* If not set up, return error */ 464 if (!gctx->key_set) 465 return -1; 466 467 if (gctx->tls_aad_len >= 0) 468 return aria_gcm_tls_cipher(ctx, out, in, len); 469 470 if (!gctx->iv_set) 471 return -1; 472 if (in) { 473 if (out == NULL) { 474 if (CRYPTO_gcm128_aad(&gctx->gcm, in, len)) 475 return -1; 476 } else if (EVP_CIPHER_CTX_is_encrypting(ctx)) { 477 if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) 478 return -1; 479 } else { 480 if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) 481 return -1; 482 } 483 return len; 484 } 485 if (!EVP_CIPHER_CTX_is_encrypting(ctx)) { 486 if (gctx->taglen < 0) 487 return -1; 488 if (CRYPTO_gcm128_finish(&gctx->gcm, 489 EVP_CIPHER_CTX_buf_noconst(ctx), 490 gctx->taglen) != 0) 491 return -1; 492 gctx->iv_set = 0; 493 return 0; 494 } 495 CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), 16); 496 gctx->taglen = 16; 497 /* Don't reuse the IV */ 498 gctx->iv_set = 0; 499 return 0; 500} 501 502static int aria_gcm_cleanup(EVP_CIPHER_CTX *ctx) 503{ 504 EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, ctx); 505 506 if (gctx->iv != ctx->iv) 507 OPENSSL_free(gctx->iv); 508 509 return 1; 510} 511 512static int aria_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, 513 const unsigned char *iv, int enc) 514{ 515 int ret; 516 EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,ctx); 517 518 if (!iv && !key) 519 return 1; 520 521 if (key) { 522 ret = ossl_aria_set_encrypt_key(key, 523 EVP_CIPHER_CTX_get_key_length(ctx) * 8, 524 &cctx->ks.ks); 525 CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, 526 &cctx->ks, (block128_f) ossl_aria_encrypt); 527 if (ret < 0) { 528 ERR_raise(ERR_LIB_EVP,EVP_R_ARIA_KEY_SETUP_FAILED); 529 return 0; 530 } 531 cctx->str = NULL; 532 cctx->key_set = 1; 533 } 534 if (iv) { 535 memcpy(ctx->iv, iv, 15 - cctx->L); 536 cctx->iv_set = 1; 537 } 538 return 1; 539} 540 541static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) 542{ 543 EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,c); 544 545 switch (type) { 546 case EVP_CTRL_INIT: 547 cctx->key_set = 0; 548 cctx->iv_set = 0; 549 cctx->L = 8; 550 cctx->M = 12; 551 cctx->tag_set = 0; 552 cctx->len_set = 0; 553 cctx->tls_aad_len = -1; 554 return 1; 555 556 case EVP_CTRL_GET_IVLEN: 557 *(int *)ptr = 15 - cctx->L; 558 return 1; 559 560 case EVP_CTRL_AEAD_TLS1_AAD: 561 /* Save the AAD for later use */ 562 if (arg != EVP_AEAD_TLS1_AAD_LEN) 563 return 0; 564 memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg); 565 cctx->tls_aad_len = arg; 566 { 567 uint16_t len = 568 EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8 569 | EVP_CIPHER_CTX_buf_noconst(c)[arg - 1]; 570 /* Correct length for explicit IV */ 571 if (len < EVP_CCM_TLS_EXPLICIT_IV_LEN) 572 return 0; 573 len -= EVP_CCM_TLS_EXPLICIT_IV_LEN; 574 /* If decrypting correct for tag too */ 575 if (!EVP_CIPHER_CTX_is_encrypting(c)) { 576 if (len < cctx->M) 577 return 0; 578 len -= cctx->M; 579 } 580 EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8; 581 EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff; 582 } 583 /* Extra padding: tag appended to record */ 584 return cctx->M; 585 586 case EVP_CTRL_CCM_SET_IV_FIXED: 587 /* Sanity check length */ 588 if (arg != EVP_CCM_TLS_FIXED_IV_LEN) 589 return 0; 590 /* Just copy to first part of IV */ 591 memcpy(c->iv, ptr, arg); 592 return 1; 593 594 case EVP_CTRL_AEAD_SET_IVLEN: 595 arg = 15 - arg; 596 /* fall thru */ 597 case EVP_CTRL_CCM_SET_L: 598 if (arg < 2 || arg > 8) 599 return 0; 600 cctx->L = arg; 601 return 1; 602 case EVP_CTRL_AEAD_SET_TAG: 603 if ((arg & 1) || arg < 4 || arg > 16) 604 return 0; 605 if (EVP_CIPHER_CTX_is_encrypting(c) && ptr) 606 return 0; 607 if (ptr) { 608 cctx->tag_set = 1; 609 memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg); 610 } 611 cctx->M = arg; 612 return 1; 613 614 case EVP_CTRL_AEAD_GET_TAG: 615 if (!EVP_CIPHER_CTX_is_encrypting(c) || !cctx->tag_set) 616 return 0; 617 if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg)) 618 return 0; 619 cctx->tag_set = 0; 620 cctx->iv_set = 0; 621 cctx->len_set = 0; 622 return 1; 623 624 case EVP_CTRL_COPY: 625 { 626 EVP_CIPHER_CTX *out = ptr; 627 EVP_ARIA_CCM_CTX *cctx_out = EVP_C_DATA(EVP_ARIA_CCM_CTX,out); 628 if (cctx->ccm.key) { 629 if (cctx->ccm.key != &cctx->ks) 630 return 0; 631 cctx_out->ccm.key = &cctx_out->ks; 632 } 633 return 1; 634 } 635 636 default: 637 return -1; 638 } 639} 640 641static int aria_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 642 const unsigned char *in, size_t len) 643{ 644 EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,ctx); 645 CCM128_CONTEXT *ccm = &cctx->ccm; 646 647 /* Encrypt/decrypt must be performed in place */ 648 if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->M)) 649 return -1; 650 /* If encrypting set explicit IV from sequence number (start of AAD) */ 651 if (EVP_CIPHER_CTX_is_encrypting(ctx)) 652 memcpy(out, EVP_CIPHER_CTX_buf_noconst(ctx), 653 EVP_CCM_TLS_EXPLICIT_IV_LEN); 654 /* Get rest of IV from explicit IV */ 655 memcpy(ctx->iv + EVP_CCM_TLS_FIXED_IV_LEN, in, 656 EVP_CCM_TLS_EXPLICIT_IV_LEN); 657 /* Correct length value */ 658 len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; 659 if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, 660 len)) 661 return -1; 662 /* Use saved AAD */ 663 CRYPTO_ccm128_aad(ccm, EVP_CIPHER_CTX_buf_noconst(ctx), 664 cctx->tls_aad_len); 665 /* Fix buffer to point to payload */ 666 in += EVP_CCM_TLS_EXPLICIT_IV_LEN; 667 out += EVP_CCM_TLS_EXPLICIT_IV_LEN; 668 if (EVP_CIPHER_CTX_is_encrypting(ctx)) { 669 if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str) 670 : CRYPTO_ccm128_encrypt(ccm, in, out, len)) 671 return -1; 672 if (!CRYPTO_ccm128_tag(ccm, out + len, cctx->M)) 673 return -1; 674 return len + EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; 675 } else { 676 if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, cctx->str) 677 : !CRYPTO_ccm128_decrypt(ccm, in, out, len)) { 678 unsigned char tag[16]; 679 if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) { 680 if (!CRYPTO_memcmp(tag, in + len, cctx->M)) 681 return len; 682 } 683 } 684 OPENSSL_cleanse(out, len); 685 return -1; 686 } 687} 688 689static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, 690 const unsigned char *in, size_t len) 691{ 692 EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,ctx); 693 CCM128_CONTEXT *ccm = &cctx->ccm; 694 695 /* If not set up, return error */ 696 if (!cctx->key_set) 697 return -1; 698 699 if (cctx->tls_aad_len >= 0) 700 return aria_ccm_tls_cipher(ctx, out, in, len); 701 702 /* EVP_*Final() doesn't return any data */ 703 if (in == NULL && out != NULL) 704 return 0; 705 706 if (!cctx->iv_set) 707 return -1; 708 709 if (!out) { 710 if (!in) { 711 if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) 712 return -1; 713 cctx->len_set = 1; 714 return len; 715 } 716 /* If have AAD need message length */ 717 if (!cctx->len_set && len) 718 return -1; 719 CRYPTO_ccm128_aad(ccm, in, len); 720 return len; 721 } 722 723 /* The tag must be set before actually decrypting data */ 724 if (!EVP_CIPHER_CTX_is_encrypting(ctx) && !cctx->tag_set) 725 return -1; 726 727 /* If not set length yet do it */ 728 if (!cctx->len_set) { 729 if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) 730 return -1; 731 cctx->len_set = 1; 732 } 733 if (EVP_CIPHER_CTX_is_encrypting(ctx)) { 734 if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str) 735 : CRYPTO_ccm128_encrypt(ccm, in, out, len)) 736 return -1; 737 cctx->tag_set = 1; 738 return len; 739 } else { 740 int rv = -1; 741 if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, 742 cctx->str) : 743 !CRYPTO_ccm128_decrypt(ccm, in, out, len)) { 744 unsigned char tag[16]; 745 if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) { 746 if (!CRYPTO_memcmp(tag, EVP_CIPHER_CTX_buf_noconst(ctx), 747 cctx->M)) 748 rv = len; 749 } 750 } 751 if (rv == -1) 752 OPENSSL_cleanse(out, len); 753 cctx->iv_set = 0; 754 cctx->tag_set = 0; 755 cctx->len_set = 0; 756 return rv; 757 } 758} 759 760#define aria_ccm_cleanup NULL 761 762#define ARIA_AUTH_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \ 763 | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ 764 | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ 765 | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_AEAD_CIPHER \ 766 | EVP_CIPH_CUSTOM_IV_LENGTH) 767 768#define BLOCK_CIPHER_aead(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ 769static const EVP_CIPHER aria_##keylen##_##mode = { \ 770 nid##_##keylen##_##nmode, \ 771 blocksize, keylen/8, ivlen, \ 772 ARIA_AUTH_FLAGS|EVP_CIPH_##MODE##_MODE, \ 773 EVP_ORIG_GLOBAL, \ 774 aria_##mode##_init_key, \ 775 aria_##mode##_cipher, \ 776 aria_##mode##_cleanup, \ 777 sizeof(EVP_ARIA_##MODE##_CTX), \ 778 NULL,NULL,aria_##mode##_ctrl,NULL }; \ 779const EVP_CIPHER *EVP_aria_##keylen##_##mode(void) \ 780{ return (EVP_CIPHER*)&aria_##keylen##_##mode; } 781 782BLOCK_CIPHER_aead(NID_aria, 128, 1, 12, gcm, gcm, GCM, 0) 783BLOCK_CIPHER_aead(NID_aria, 192, 1, 12, gcm, gcm, GCM, 0) 784BLOCK_CIPHER_aead(NID_aria, 256, 1, 12, gcm, gcm, GCM, 0) 785 786BLOCK_CIPHER_aead(NID_aria, 128, 1, 12, ccm, ccm, CCM, 0) 787BLOCK_CIPHER_aead(NID_aria, 192, 1, 12, ccm, ccm, CCM, 0) 788BLOCK_CIPHER_aead(NID_aria, 256, 1, 12, ccm, ccm, CCM, 0) 789 790#endif 791