diff options
author | Jon Spillett <jon.spillett@oracle.com> | 2017-08-22 09:56:13 +1000 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2017-08-30 12:33:53 +0200 |
commit | bc32673869842c7f00ae7016040a612f516ead7e (patch) | |
tree | ad88525fc75299889456ce83876ea76fd819c3ef /crypto | |
parent | 1c2ac294721b636665aa7d62f5e3f843d3b1ac71 (diff) |
Implement Aria GCM/CCM Modes and TLS cipher suites
AEAD cipher mode implementation is based on that used for AES:
https://tools.ietf.org/html/rfc5116
TLS GCM cipher suites as specified in:
https://tools.ietf.org/html/rfc6209
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4287)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/err/openssl.txt | 2 | ||||
-rw-r--r-- | crypto/evp/build.info | 1 | ||||
-rw-r--r-- | crypto/evp/c_allc.c | 6 | ||||
-rw-r--r-- | crypto/evp/e_aria.c | 602 | ||||
-rw-r--r-- | crypto/evp/evp_err.c | 2 | ||||
-rw-r--r-- | crypto/objects/obj_dat.h | 40 | ||||
-rw-r--r-- | crypto/objects/obj_mac.num | 6 | ||||
-rw-r--r-- | crypto/objects/objects.txt | 7 |
8 files changed, 660 insertions, 6 deletions
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 13b1348a93..517c9f4803 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -634,6 +634,8 @@ EVP_F_AES_OCB_CIPHER:169:aes_ocb_cipher EVP_F_AES_T4_INIT_KEY:178:aes_t4_init_key EVP_F_AES_WRAP_CIPHER:170:aes_wrap_cipher EVP_F_ALG_MODULE_INIT:177:alg_module_init +EVP_F_ARIA_CCM_INIT_KEY:175:aria_ccm_init_key +EVP_F_ARIA_GCM_INIT_KEY:176:aria_gcm_init_key EVP_F_ARIA_INIT_KEY:185:aria_init_key EVP_F_CAMELLIA_INIT_KEY:159:camellia_init_key EVP_F_CHACHA20_POLY1305_CTRL:182:chacha20_poly1305_ctrl diff --git a/crypto/evp/build.info b/crypto/evp/build.info index 88a5b6889f..d65276a0c7 100644 --- a/crypto/evp/build.info +++ b/crypto/evp/build.info @@ -17,6 +17,7 @@ SOURCE[../../libcrypto]=\ INCLUDE[e_aes.o]=.. ../modes INCLUDE[e_aes_cbc_hmac_sha1.o]=../modes INCLUDE[e_aes_cbc_hmac_sha256.o]=../modes +INCLUDE[e_aria.o]=.. ../modes INCLUDE[e_camellia.o]=.. ../modes INCLUDE[e_des.o]=.. INCLUDE[e_des3.o]=.. diff --git a/crypto/evp/c_allc.c b/crypto/evp/c_allc.c index 58a0691df7..ee77d65be9 100644 --- a/crypto/evp/c_allc.c +++ b/crypto/evp/c_allc.c @@ -189,6 +189,8 @@ void openssl_add_all_ciphers_int(void) EVP_add_cipher(EVP_aria_128_cfb8()); EVP_add_cipher(EVP_aria_128_ctr()); EVP_add_cipher(EVP_aria_128_ofb()); + EVP_add_cipher(EVP_aria_128_gcm()); + EVP_add_cipher(EVP_aria_128_ccm()); EVP_add_cipher_alias(SN_aria_128_cbc, "ARIA128"); EVP_add_cipher_alias(SN_aria_128_cbc, "aria128"); EVP_add_cipher(EVP_aria_192_ecb()); @@ -198,6 +200,8 @@ void openssl_add_all_ciphers_int(void) EVP_add_cipher(EVP_aria_192_cfb8()); EVP_add_cipher(EVP_aria_192_ctr()); EVP_add_cipher(EVP_aria_192_ofb()); + EVP_add_cipher(EVP_aria_192_gcm()); + EVP_add_cipher(EVP_aria_192_ccm()); EVP_add_cipher_alias(SN_aria_192_cbc, "ARIA192"); EVP_add_cipher_alias(SN_aria_192_cbc, "aria192"); EVP_add_cipher(EVP_aria_256_ecb()); @@ -207,6 +211,8 @@ void openssl_add_all_ciphers_int(void) EVP_add_cipher(EVP_aria_256_cfb8()); EVP_add_cipher(EVP_aria_256_ctr()); EVP_add_cipher(EVP_aria_256_ofb()); + EVP_add_cipher(EVP_aria_256_gcm()); + EVP_add_cipher(EVP_aria_256_ccm()); EVP_add_cipher_alias(SN_aria_256_cbc, "ARIA256"); EVP_add_cipher_alias(SN_aria_256_cbc, "aria256"); #endif diff --git a/crypto/evp/e_aria.c b/crypto/evp/e_aria.c index 6f179e2544..00e008a368 100644 --- a/crypto/evp/e_aria.c +++ b/crypto/evp/e_aria.c @@ -12,14 +12,49 @@ #ifndef OPENSSL_NO_ARIA # include <openssl/evp.h> # include <openssl/modes.h> -# include"internal/aria.h" +# include <openssl/rand.h> +# include "internal/aria.h" # include "internal/evp_int.h" +# include "modes_lcl.h" +# include "evp_locl.h" /* ARIA subkey Structure */ typedef struct { ARIA_KEY ks; } EVP_ARIA_KEY; +/* ARIA GCM context */ +typedef struct { + union { + double align; + ARIA_KEY ks; + } ks; /* ARIA subkey to use */ + int key_set; /* Set if key initialised */ + int iv_set; /* Set if an iv is set */ + GCM128_CONTEXT gcm; + unsigned char *iv; /* Temporary IV store */ + int ivlen; /* IV length */ + int taglen; + int iv_gen; /* It is OK to generate IVs */ + int tls_aad_len; /* TLS AAD length */ +} EVP_ARIA_GCM_CTX; + +/* ARIA CCM context */ +typedef struct { + union { + double align; + ARIA_KEY ks; + } ks; /* ARIA key schedule to use */ + int key_set; /* Set if key initialised */ + int iv_set; /* Set if an iv is set */ + int tag_set; /* Set if tag is valid */ + int len_set; /* Set if message length set */ + int L, M; /* L and M parameters from RFC3610 */ + int tls_aad_len; /* TLS AAD length */ + CCM128_CONTEXT ccm; + ccm128_f str; +} EVP_ARIA_CCM_CTX; + /* The subkey for ARIA is generated. */ static int aria_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc) @@ -150,4 +185,569 @@ BLOCK_CIPHER_generic(NID_aria, 128, 1, 16, ctr, ctr, CTR, 0) BLOCK_CIPHER_generic(NID_aria, 192, 1, 16, ctr, ctr, CTR, 0) BLOCK_CIPHER_generic(NID_aria, 256, 1, 16, ctr, ctr, CTR, 0) +/* Authenticated cipher modes (GCM/CCM) */ + +/* increment counter (64-bit int) by 1 */ +static void ctr64_inc(unsigned char *counter) +{ + int n = 8; + unsigned char c; + + do { + --n; + c = counter[n]; + ++c; + counter[n] = c; + if (c) + return; + } while (n); +} + +static int aria_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + int ret; + EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx); + + if (!iv && !key) + return 1; + if (key) { + ret = aria_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + &gctx->ks.ks); + CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, + (block128_f) aria_encrypt); + if (ret < 0) { + EVPerr(EVP_F_ARIA_GCM_INIT_KEY,EVP_R_ARIA_KEY_SETUP_FAILED); + return 0; + } + + /* + * If we have an iv can set it directly, otherwise use saved IV. + */ + if (iv == NULL && gctx->iv_set) + iv = gctx->iv; + if (iv) { + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + gctx->iv_set = 1; + } + gctx->key_set = 1; + } else { + /* If key set use IV, otherwise copy */ + if (gctx->key_set) + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + else + memcpy(gctx->iv, iv, gctx->ivlen); + gctx->iv_set = 1; + gctx->iv_gen = 0; + } + return 1; +} + +static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,c); + + switch (type) { + case EVP_CTRL_INIT: + gctx->key_set = 0; + gctx->iv_set = 0; + gctx->ivlen = EVP_CIPHER_CTX_iv_length(c); + gctx->iv = EVP_CIPHER_CTX_iv_noconst(c); + gctx->taglen = -1; + gctx->iv_gen = 0; + gctx->tls_aad_len = -1; + return 1; + + case EVP_CTRL_AEAD_SET_IVLEN: + if (arg <= 0) + return 0; + /* Allocate memory for IV if needed */ + if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { + if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(c)) + OPENSSL_free(gctx->iv); + gctx->iv = OPENSSL_malloc(arg); + if (gctx->iv == NULL) + return 0; + } + gctx->ivlen = arg; + return 1; + + case EVP_CTRL_AEAD_SET_TAG: + if (arg <= 0 || arg > 16 || EVP_CIPHER_CTX_encrypting(c)) + return 0; + memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg); + gctx->taglen = arg; + return 1; + + case EVP_CTRL_AEAD_GET_TAG: + if (arg <= 0 || arg > 16 || !EVP_CIPHER_CTX_encrypting(c) + || gctx->taglen < 0) + return 0; + memcpy(ptr, EVP_CIPHER_CTX_buf_noconst(c), arg); + return 1; + + case EVP_CTRL_GCM_SET_IV_FIXED: + /* Special case: -1 length restores whole IV */ + if (arg == -1) { + memcpy(gctx->iv, ptr, gctx->ivlen); + gctx->iv_gen = 1; + return 1; + } + /* + * Fixed field must be at least 4 bytes and invocation field at least + * 8. + */ + if ((arg < 4) || (gctx->ivlen - arg) < 8) + return 0; + if (arg) + memcpy(gctx->iv, ptr, arg); + if (EVP_CIPHER_CTX_encrypting(c) + && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) + return 0; + gctx->iv_gen = 1; + return 1; + + case EVP_CTRL_GCM_IV_GEN: + if (gctx->iv_gen == 0 || gctx->key_set == 0) + return 0; + CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); + if (arg <= 0 || arg > gctx->ivlen) + arg = gctx->ivlen; + memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); + /* + * Invocation field will be at least 8 bytes in size and so no need + * to check wrap around or increment more than last 8 bytes. + */ + ctr64_inc(gctx->iv + gctx->ivlen - 8); + gctx->iv_set = 1; + return 1; + + case EVP_CTRL_GCM_SET_IV_INV: + if (gctx->iv_gen == 0 || gctx->key_set == 0 + || EVP_CIPHER_CTX_encrypting(c)) + return 0; + memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); + CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); + gctx->iv_set = 1; + return 1; + + case EVP_CTRL_AEAD_TLS1_AAD: + /* Save the AAD for later use */ + if (arg != EVP_AEAD_TLS1_AAD_LEN) + return 0; + memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg); + gctx->tls_aad_len = arg; + { + unsigned int len = + EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8 + | EVP_CIPHER_CTX_buf_noconst(c)[arg - 1]; + /* Correct length for explicit IV */ + if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN) + return 0; + len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; + /* If decrypting correct for tag too */ + if (!EVP_CIPHER_CTX_encrypting(c)) { + if (len < EVP_GCM_TLS_TAG_LEN) + return 0; + len -= EVP_GCM_TLS_TAG_LEN; + } + EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8; + EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff; + } + /* Extra padding: tag appended to record */ + return EVP_GCM_TLS_TAG_LEN; + + case EVP_CTRL_COPY: + { + EVP_CIPHER_CTX *out = ptr; + EVP_ARIA_GCM_CTX *gctx_out = EVP_C_DATA(EVP_ARIA_GCM_CTX,out); + if (gctx->gcm.key) { + if (gctx->gcm.key != &gctx->ks) + return 0; + gctx_out->gcm.key = &gctx_out->ks; + } + if (gctx->iv == EVP_CIPHER_CTX_iv_noconst(c)) + gctx_out->iv = EVP_CIPHER_CTX_iv_noconst(out); + else { + gctx_out->iv = OPENSSL_malloc(gctx->ivlen); + if (gctx_out->iv == NULL) + return 0; + memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); + } + return 1; + } + + default: + return -1; + + } +} + +static int aria_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx); + int rv = -1; + + /* Encrypt/decrypt must be performed in place */ + if (out != in + || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) + return -1; + /* + * Set IV from start of buffer or generate IV and write to start of + * buffer. + */ + if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CIPHER_CTX_encrypting(ctx) ? + EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, + EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) + goto err; + /* Use saved AAD */ + if (CRYPTO_gcm128_aad(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), + gctx->tls_aad_len)) + goto err; + /* Fix buffer and length to point to payload */ + in += EVP_GCM_TLS_EXPLICIT_IV_LEN; + out += EVP_GCM_TLS_EXPLICIT_IV_LEN; + len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; + if (EVP_CIPHER_CTX_encrypting(ctx)) { + /* Encrypt payload */ + if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) + goto err; + out += len; + /* Finally write tag */ + CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN); + rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; + } else { + /* Decrypt */ + if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) + goto err; + /* Retrieve tag */ + CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), + EVP_GCM_TLS_TAG_LEN); + /* If tag mismatch wipe buffer */ + if (CRYPTO_memcmp(EVP_CIPHER_CTX_buf_noconst(ctx), in + len, + EVP_GCM_TLS_TAG_LEN)) { + OPENSSL_cleanse(out, len); + goto err; + } + rv = len; + } + + err: + gctx->iv_set = 0; + gctx->tls_aad_len = -1; + return rv; +} + +static int aria_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX,ctx); + + /* If not set up, return error */ + if (!gctx->key_set) + return -1; + + if (gctx->tls_aad_len >= 0) + return aria_gcm_tls_cipher(ctx, out, in, len); + + if (!gctx->iv_set) + return -1; + if (in) { + if (out == NULL) { + if (CRYPTO_gcm128_aad(&gctx->gcm, in, len)) + return -1; + } else if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) + return -1; + } else { + if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) + return -1; + } + return len; + } + if (!EVP_CIPHER_CTX_encrypting(ctx)) { + if (gctx->taglen < 0) + return -1; + if (CRYPTO_gcm128_finish(&gctx->gcm, + EVP_CIPHER_CTX_buf_noconst(ctx), + gctx->taglen) != 0) + return -1; + gctx->iv_set = 0; + return 0; + } + CRYPTO_gcm128_tag(&gctx->gcm, EVP_CIPHER_CTX_buf_noconst(ctx), 16); + gctx->taglen = 16; + /* Don't reuse the IV */ + gctx->iv_set = 0; + return 0; +} + +static int aria_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + int ret; + EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,ctx); + + if (!iv && !key) + return 1; + + if (key) { + ret = aria_set_encrypt_key(key, EVP_CIPHER_CTX_key_length(ctx) * 8, + &cctx->ks.ks); + CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, + &cctx->ks, (block128_f) aria_encrypt); + if (ret < 0) { + EVPerr(EVP_F_ARIA_CCM_INIT_KEY,EVP_R_ARIA_KEY_SETUP_FAILED); + return 0; + } + cctx->str = NULL; + cctx->key_set = 1; + } + if (iv) { + memcpy(EVP_CIPHER_CTX_iv_noconst(ctx), iv, 15 - cctx->L); + cctx->iv_set = 1; + } + return 1; +} + +static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,c); + + switch (type) { + case EVP_CTRL_INIT: + cctx->key_set = 0; + cctx->iv_set = 0; + cctx->L = 8; + cctx->M = 12; + cctx->tag_set = 0; + cctx->len_set = 0; + cctx->tls_aad_len = -1; + return 1; + + case EVP_CTRL_AEAD_TLS1_AAD: + /* Save the AAD for later use */ + if (arg != EVP_AEAD_TLS1_AAD_LEN) + return 0; + memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg); + cctx->tls_aad_len = arg; + { + uint16_t len = + EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] << 8 + | EVP_CIPHER_CTX_buf_noconst(c)[arg - 1]; + /* Correct length for explicit IV */ + if (len < EVP_CCM_TLS_EXPLICIT_IV_LEN) + return 0; + len -= EVP_CCM_TLS_EXPLICIT_IV_LEN; + /* If decrypting correct for tag too */ + if (!EVP_CIPHER_CTX_encrypting(c)) { + if (len < cctx->M) + return 0; + len -= cctx->M; + } + EVP_CIPHER_CTX_buf_noconst(c)[arg - 2] = len >> 8; + EVP_CIPHER_CTX_buf_noconst(c)[arg - 1] = len & 0xff; + } + /* Extra padding: tag appended to record */ + return cctx->M; + + case EVP_CTRL_CCM_SET_IV_FIXED: + /* Sanity check length */ + if (arg != EVP_CCM_TLS_FIXED_IV_LEN) + return 0; + /* Just copy to first part of IV */ + memcpy(EVP_CIPHER_CTX_iv_noconst(c), ptr, arg); + return 1; + + case EVP_CTRL_AEAD_SET_IVLEN: + arg = 15 - arg; + /* fall thru */ + case EVP_CTRL_CCM_SET_L: + if (arg < 2 || arg > 8) + return 0; + cctx->L = arg; + return 1; + case EVP_CTRL_AEAD_SET_TAG: + if ((arg & 1) || arg < 4 || arg > 16) + return 0; + if (EVP_CIPHER_CTX_encrypting(c) && ptr) + return 0; + if (ptr) { + cctx->tag_set = 1; + memcpy(EVP_CIPHER_CTX_buf_noconst(c), ptr, arg); + } + cctx->M = arg; + return 1; + + case EVP_CTRL_AEAD_GET_TAG: + if (!EVP_CIPHER_CTX_encrypting(c) || !cctx->tag_set) + return 0; + if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg)) + return 0; + cctx->tag_set = 0; + cctx->iv_set = 0; + cctx->len_set = 0; + return 1; + + case EVP_CTRL_COPY: + { + EVP_CIPHER_CTX *out = ptr; + EVP_ARIA_CCM_CTX *cctx_out = EVP_C_DATA(EVP_ARIA_CCM_CTX,out); + if (cctx->ccm.key) { + if (cctx->ccm.key != &cctx->ks) + return 0; + cctx_out->ccm.key = &cctx_out->ks; + } + return 1; + } + + default: + return -1; + } +} + +static int aria_ccm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,ctx); + CCM128_CONTEXT *ccm = &cctx->ccm; + + /* Encrypt/decrypt must be performed in place */ + if (out != in || len < (EVP_CCM_TLS_EXPLICIT_IV_LEN + (size_t)cctx->M)) + return -1; + /* If encrypting set explicit IV from sequence number (start of AAD) */ + if (EVP_CIPHER_CTX_encrypting(ctx)) + memcpy(out, EVP_CIPHER_CTX_buf_noconst(ctx), + EVP_CCM_TLS_EXPLICIT_IV_LEN); + /* Get rest of IV from explicit IV */ + memcpy(EVP_CIPHER_CTX_iv_noconst(ctx) + EVP_CCM_TLS_FIXED_IV_LEN, in, + EVP_CCM_TLS_EXPLICIT_IV_LEN); + /* Correct length value */ + len -= EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; + if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), 15 - cctx->L, + len)) + return -1; + /* Use saved AAD */ + CRYPTO_ccm128_aad(ccm, EVP_CIPHER_CTX_buf_noconst(ctx), cctx->tls_aad_len); + /* Fix buffer to point to payload */ + in += EVP_CCM_TLS_EXPLICIT_IV_LEN; + out += EVP_CCM_TLS_EXPLICIT_IV_LEN; + if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str) + : CRYPTO_ccm128_encrypt(ccm, in, out, len)) + return -1; + if (!CRYPTO_ccm128_tag(ccm, out + len, cctx->M)) + return -1; + return len + EVP_CCM_TLS_EXPLICIT_IV_LEN + cctx->M; + } else { + if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, cctx->str) + : !CRYPTO_ccm128_decrypt(ccm, in, out, len)) { + unsigned char tag[16]; + if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) { + if (!CRYPTO_memcmp(tag, in + len, cctx->M)) + return len; + } + } + OPENSSL_cleanse(out, len); + return -1; + } +} + +static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_ARIA_CCM_CTX *cctx = EVP_C_DATA(EVP_ARIA_CCM_CTX,ctx); + CCM128_CONTEXT *ccm = &cctx->ccm; + + /* If not set up, return error */ + if (!cctx->key_set) + return -1; + + if (cctx->tls_aad_len >= 0) + return aria_ccm_tls_cipher(ctx, out, in, len); + + /* EVP_*Final() doesn't return any data */ + if (in == NULL && out != NULL) + return 0; + + if (!cctx->iv_set) + return -1; + + if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set) + return -1; + if (!out) { + if (!in) { + if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), + 15 - cctx->L, len)) + return -1; + cctx->len_set = 1; + return len; + } + /* If have AAD need message length */ + if (!cctx->len_set && len) + return -1; + CRYPTO_ccm128_aad(ccm, in, len); + return len; + } + /* If not set length yet do it */ + if (!cctx->len_set) { + if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx), + 15 - cctx->L, len)) + return -1; + cctx->len_set = 1; + } + if (EVP_CIPHER_CTX_encrypting(ctx)) { + if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, cctx->str) + : CRYPTO_ccm128_encrypt(ccm, in, out, len)) + return -1; + cctx->tag_set = 1; + return len; + } else { + int rv = -1; + if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, + cctx->str) : + !CRYPTO_ccm128_decrypt(ccm, in, out, len)) { + unsigned char tag[16]; + if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) { + if (!CRYPTO_memcmp(tag, EVP_CIPHER_CTX_buf_noconst(ctx), + cctx->M)) + rv = len; + } + } + if (rv == -1) + OPENSSL_cleanse(out, len); + cctx->iv_set = 0; + cctx->tag_set = 0; + cctx->len_set = 0; + return rv; + } +} + +#define ARIA_AUTH_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \ + | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ + | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ + | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_AEAD_CIPHER) + +#define BLOCK_CIPHER_aead(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ +static const EVP_CIPHER aria_##keylen##_##mode = { \ + nid##_##keylen##_##nmode, \ + blocksize, keylen/8, ivlen, \ + ARIA_AUTH_FLAGS|EVP_CIPH_##MODE##_MODE, \ + aria_##mode##_init_key, \ + aria_##mode##_cipher, \ + NULL, \ + sizeof(EVP_ARIA_##MODE##_CTX), \ + NULL,NULL,aria_##mode##_ctrl,NULL }; \ +const EVP_CIPHER *EVP_aria_##keylen##_##mode(void) \ +{ return (EVP_CIPHER*)&aria_##keylen##_##mode; } + +BLOCK_CIPHER_aead(NID_aria, 128, 1, 12, gcm, gcm, GCM, 0) +BLOCK_CIPHER_aead(NID_aria, 192, 1, 12, gcm, gcm, GCM, 0) +BLOCK_CIPHER_aead(NID_aria, 256, 1, 12, gcm, gcm, GCM, 0) + +BLOCK_CIPHER_aead(NID_aria, 128, 1, 12, ccm, ccm, CCM, 0) +BLOCK_CIPHER_aead(NID_aria, 192, 1, 12, ccm, ccm, CCM, 0) +BLOCK_CIPHER_aead(NID_aria, 256, 1, 12, ccm, ccm, CCM, 0) + #endif diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c index 97fdf68b47..c8161965d8 100644 --- a/crypto/evp/evp_err.c +++ b/crypto/evp/evp_err.c @@ -20,6 +20,8 @@ static const ERR_STRING_DATA EVP_str_functs[] = { {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_T4_INIT_KEY, 0), "aes_t4_init_key"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_AES_WRAP_CIPHER, 0), "aes_wrap_cipher"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_ALG_MODULE_INIT, 0), "alg_module_init"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_CCM_INIT_KEY, 0), "aria_ccm_init_key"}, + {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_GCM_INIT_KEY, 0), "aria_gcm_init_key"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_ARIA_INIT_KEY, 0), "aria_init_key"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_CAMELLIA_INIT_KEY, 0), "camellia_init_key"}, {ERR_PACK(ERR_LIB_EVP, EVP_F_CHACHA20_POLY1305_CTRL, 0), diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index 9647e31677..4c3c9d5755 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -10,7 +10,7 @@ */ /* Serialized OID's */ -static const unsigned char so[7168] = { +static const unsigned char so[7222] = { 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ @@ -1010,9 +1010,15 @@ static const unsigned char so[7168] = { 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0E, /* [ 7140] OBJ_RSA_SHA3_256 */ 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x0F, /* [ 7149] OBJ_RSA_SHA3_284 */ 0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x10, /* [ 7158] OBJ_RSA_SHA3_512 */ + 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x25, /* [ 7167] OBJ_aria_128_ccm */ + 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x26, /* [ 7176] OBJ_aria_192_ccm */ + 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x27, /* [ 7185] OBJ_aria_256_ccm */ + 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x22, /* [ 7194] OBJ_aria_128_gcm */ + 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x23, /* [ 7203] OBJ_aria_192_gcm */ + 0x2A,0x83,0x1A,0x8C,0x9A,0x6E,0x01,0x01,0x24, /* [ 7212] OBJ_aria_256_gcm */ }; -#define NUM_NID 1120 +#define NUM_NID 1126 static const ASN1_OBJECT nid_objs[NUM_NID] = { {"UNDEF", "undefined", NID_undef}, {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]}, @@ -2134,9 +2140,15 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = { {"id-rsassa-pkcs1-v1_5-with-sha3-256", "RSA-SHA3-256", NID_RSA_SHA3_256, 9, &so[7140]}, {"id-rsassa-pkcs1-v1_5-with-sha3-384", "RSA-SHA3-284", NID_RSA_SHA3_284, 9, &so[7149]}, {"id-rsassa-pkcs1-v1_5-with-sha3-512", "RSA-SHA3-512", NID_RSA_SHA3_512, 9, &so[7158]}, + {"ARIA-128-CCM", "aria-128-ccm", NID_aria_128_ccm, 9, &so[7167]}, + {"ARIA-192-CCM", "aria-192-ccm", NID_aria_192_ccm, 9, &so[7176]}, + {"ARIA-256-CCM", "aria-256-ccm", NID_aria_256_ccm, 9, &so[7185]}, + {"ARIA-128-GCM", "aria-128-gcm", NID_aria_128_gcm, 9, &so[7194]}, + {"ARIA-192-GCM", "aria-192-gcm", NID_aria_192_gcm, 9, &so[7203]}, + {"ARIA-256-GCM", "aria-256-gcm", NID_aria_256_gcm, 9, &so[7212]}, }; -#define NUM_SN 1111 +#define NUM_SN 1117 static const unsigned int sn_objs[NUM_SN] = { 364, /* "AD_DVCS" */ 419, /* "AES-128-CBC" */ @@ -2172,25 +2184,31 @@ static const unsigned int sn_objs[NUM_SN] = { 428, /* "AES-256-OFB" */ 914, /* "AES-256-XTS" */ 1066, /* "ARIA-128-CBC" */ + 1120, /* "ARIA-128-CCM" */ 1067, /* "ARIA-128-CFB" */ 1080, /* "ARIA-128-CFB1" */ 1083, /* "ARIA-128-CFB8" */ 1069, /* "ARIA-128-CTR" */ 1065, /* "ARIA-128-ECB" */ + 1123, /* "ARIA-128-GCM" */ 1068, /* "ARIA-128-OFB" */ 1071, /* "ARIA-192-CBC" */ + 1121, /* "ARIA-192-CCM" */ 1072, /* "ARIA-192-CFB" */ 1081, /* "ARIA-192-CFB1" */ 1084, /* "ARIA-192-CFB8" */ 1074, /* "ARIA-192-CTR" */ 1070, /* "ARIA-192-ECB" */ + 1124, /* "ARIA-192-GCM" */ 1073, /* "ARIA-192-OFB" */ 1076, /* "ARIA-256-CBC" */ + 1122, /* "ARIA-256-CCM" */ 1077, /* "ARIA-256-CFB" */ 1082, /* "ARIA-256-CFB1" */ 1085, /* "ARIA-256-CFB8" */ 1079, /* "ARIA-256-CTR" */ 1075, /* "ARIA-256-ECB" */ + 1125, /* "ARIA-256-GCM" */ 1078, /* "ARIA-256-OFB" */ 1064, /* "AuthANY" */ 1049, /* "AuthDSS" */ @@ -3251,7 +3269,7 @@ static const unsigned int sn_objs[NUM_SN] = { 1093, /* "x509ExtAdmission" */ }; -#define NUM_LN 1111 +#define NUM_LN 1117 static const unsigned int ln_objs[NUM_LN] = { 363, /* "AD Time Stamping" */ 405, /* "ANSI X9.62" */ @@ -3478,25 +3496,31 @@ static const unsigned int ln_objs[NUM_LN] = { 914, /* "aes-256-xts" */ 376, /* "algorithm" */ 1066, /* "aria-128-cbc" */ + 1120, /* "aria-128-ccm" */ 1067, /* "aria-128-cfb" */ 1080, /* "aria-128-cfb1" */ 1083, /* "aria-128-cfb8" */ 1069, /* "aria-128-ctr" */ 1065, /* "aria-128-ecb" */ + 1123, /* "aria-128-gcm" */ 1068, /* "aria-128-ofb" */ 1071, /* "aria-192-cbc" */ + 1121, /* "aria-192-ccm" */ 1072, /* "aria-192-cfb" */ 1081, /* "aria-192-cfb1" */ 1084, /* "aria-192-cfb8" */ 1074, /* "aria-192-ctr" */ 1070, /* "aria-192-ecb" */ + 1124, /* "aria-192-gcm" */ 1073, /* "aria-192-ofb" */ 1076, /* "aria-256-cbc" */ + 1122, /* "aria-256-ccm" */ 1077, /* "aria-256-cfb" */ 1082, /* "aria-256-cfb1" */ 1085, /* "aria-256-cfb8" */ 1079, /* "aria-256-ctr" */ 1075, /* "aria-256-ecb" */ + 1125, /* "aria-256-gcm" */ 1078, /* "aria-256-ofb" */ 484, /* "associatedDomain" */ 485, /* "associatedName" */ @@ -4366,7 +4390,7 @@ static const unsigned int ln_objs[NUM_LN] = { 125, /* "zlib compression" */ }; -#define NUM_OBJ 1005 +#define NUM_OBJ 1011 static const unsigned int obj_objs[NUM_OBJ] = { 0, /* OBJ_undef 0 */ 181, /* OBJ_iso 1 */ @@ -5033,6 +5057,12 @@ static const unsigned int obj_objs[NUM_OBJ] = { 1077, /* OBJ_aria_256_cfb128 1 2 410 200046 1 1 13 */ 1078, /* OBJ_aria_256_ofb128 1 2 410 200046 1 1 14 */ 1079, /* OBJ_aria_256_ctr 1 2 410 200046 1 1 15 */ + 1123, /* OBJ_aria_128_gcm 1 2 410 200046 1 1 34 */ + 1124, /* OBJ_aria_192_gcm 1 2 410 200046 1 1 35 */ + 1125, /* OBJ_aria_256_gcm 1 2 410 200046 1 1 36 */ + 1120, /* OBJ_aria_128_ccm 1 2 410 200046 1 1 37 */ + 1121, /* OBJ_aria_192_ccm 1 2 410 200046 1 1 38 */ + 1122, /* OBJ_aria_256_ccm 1 2 410 200046 1 1 39 */ 997, /* OBJ_id_tc26_gost_3410_2012_512_paramSetTest 1 2 643 7 1 2 1 2 0 */ 998, /* OBJ_id_tc26_gost_3410_2012_512_paramSetA 1 2 643 7 1 2 1 2 1 */ 999, /* OBJ_id_tc26_gost_3410_2012_512_paramSetB 1 2 643 7 1 2 1 2 2 */ diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index 0c16f318d0..b0b3d4d997 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -1117,3 +1117,9 @@ RSA_SHA3_224 1116 RSA_SHA3_256 1117 RSA_SHA3_284 1118 RSA_SHA3_512 1119 +aria_128_ccm 1120 +aria_192_ccm 1121 +aria_256_ccm 1122 +aria_128_gcm 1123 +aria_192_gcm 1124 +aria_256_gcm 1125 diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index 7464d670e9..185a7a72e4 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -1442,6 +1442,13 @@ aria 15 : ARIA-256-CTR : aria-256-ctr : ARIA-192-CFB8 : aria-192-cfb8 : ARIA-256-CFB8 : aria-256-cfb8 +aria 37 : ARIA-128-CCM : aria-128-ccm +aria 38 : ARIA-192-CCM : aria-192-ccm +aria 39 : ARIA-256-CCM : aria-256-ccm +aria 34 : ARIA-128-GCM : aria-128-gcm +aria 35 : ARIA-192-GCM : aria-192-gcm +aria 36 : ARIA-256-GCM : aria-256-gcm + # Definitions for SEED cipher - ECB, CBC, OFB mode member-body 410 200004 : KISA : kisa |