/*
- * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2017-2019 The OpenSSL Project Authors. All Rights Reserved.
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
*
- * Licensed under the OpenSSL license (the "License"). You may not use
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
# include <openssl/evp.h>
# include <openssl/modes.h>
# include <openssl/rand.h>
-# include "internal/aria.h"
-# include "internal/evp_int.h"
-# include "internal/rand.h"
-# include "modes_lcl.h"
-# include "evp_locl.h"
+# include <openssl/rand_drbg.h>
+# include "crypto/aria.h"
+# include "crypto/evp.h"
+# include "crypto/modes.h"
+# include "evp_local.h"
/* ARIA subkey Structure */
typedef struct {
/* ARIA GCM context */
typedef struct {
union {
- double align;
+ OSSL_UNION_ALIGN;
ARIA_KEY ks;
} ks; /* ARIA subkey to use */
int key_set; /* Set if key initialised */
/* ARIA CCM context */
typedef struct {
union {
- double align;
+ OSSL_UNION_ALIGN;
ARIA_KEY ks;
} ks; /* ARIA key schedule to use */
int key_set; /* Set if key initialised */
case EVP_CTRL_INIT:
gctx->key_set = 0;
gctx->iv_set = 0;
- gctx->ivlen = EVP_CIPHER_CTX_iv_length(c);
+ gctx->ivlen = EVP_CIPHER_iv_length(c->cipher);
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_GET_IVLEN:
+ *(int *)ptr = gctx->ivlen;
+ return 1;
+
case EVP_CTRL_AEAD_SET_IVLEN:
if (arg <= 0)
return 0;
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)
+ if ((gctx->iv = OPENSSL_malloc(arg)) == NULL) {
+ EVPerr(EVP_F_ARIA_GCM_CTRL, ERR_R_MALLOC_FAILURE);
return 0;
+ }
}
gctx->ivlen = arg;
return 1;
return 0;
if (arg)
memcpy(gctx->iv, ptr, arg);
- if (EVP_CIPHER_CTX_encrypting(c)) {
- if (c->drbg != NULL) {
- if (RAND_DRBG_bytes(c->drbg, gctx->iv + arg, gctx->ivlen - arg) == 0)
- return 0;
- } else if (RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) {
- return 0;
- }
- }
+ if (EVP_CIPHER_CTX_encrypting(c)
+ && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0)
+ return 0;
gctx->iv_gen = 1;
return 1;
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)
+ if ((gctx_out->iv = OPENSSL_malloc(gctx->ivlen)) == NULL) {
+ EVPerr(EVP_F_ARIA_GCM_CTRL, ERR_R_MALLOC_FAILURE);
return 0;
+ }
memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
}
return 1;
return 0;
}
+static int aria_gcm_cleanup(EVP_CIPHER_CTX *ctx)
+{
+ EVP_ARIA_GCM_CTX *gctx = EVP_C_DATA(EVP_ARIA_GCM_CTX, ctx);
+
+ if (gctx->iv != EVP_CIPHER_CTX_iv_noconst(ctx))
+ OPENSSL_free(gctx->iv);
+
+ return 1;
+}
+
static int aria_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
{
cctx->tls_aad_len = -1;
return 1;
+ case EVP_CTRL_GET_IVLEN:
+ *(int *)ptr = 15 - cctx->L;
+ return 1;
+
case EVP_CTRL_AEAD_TLS1_AAD:
/* Save the AAD for later use */
if (arg != EVP_AEAD_TLS1_AAD_LEN)
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),
CRYPTO_ccm128_aad(ccm, in, len);
return len;
}
+
+ /* The tag must be set before actually decrypting data */
+ if (!EVP_CIPHER_CTX_encrypting(ctx) && !cctx->tag_set)
+ return -1;
+
/* If not set length yet do it */
if (!cctx->len_set) {
if (CRYPTO_ccm128_setiv(ccm, EVP_CIPHER_CTX_iv_noconst(ctx),
}
}
+#define aria_ccm_cleanup NULL
+
#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)
+ | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_AEAD_CIPHER \
+ | EVP_CIPH_CUSTOM_IV_LENGTH)
#define BLOCK_CIPHER_aead(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \
static const EVP_CIPHER aria_##keylen##_##mode = { \
ARIA_AUTH_FLAGS|EVP_CIPH_##MODE##_MODE, \
aria_##mode##_init_key, \
aria_##mode##_cipher, \
- NULL, \
+ aria_##mode##_cleanup, \
sizeof(EVP_ARIA_##MODE##_CTX), \
NULL,NULL,aria_##mode##_ctrl,NULL }; \
const EVP_CIPHER *EVP_aria_##keylen##_##mode(void) \