Make EVP_PKEY_CTX_[get|set]_group_name work for DH too
[openssl.git] / crypto / evp / e_aria.c
index 10525a84d9f6f30083473e43a386faf2c4595919..9720fcb7e5e5609014e250168a6727701fd6172a 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * 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 {
@@ -27,7 +27,7 @@ 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 */
@@ -43,7 +43,7 @@ typedef struct {
 /* 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 */
@@ -252,13 +252,17 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
     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;
@@ -266,9 +270,10 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
         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;
@@ -302,14 +307,9 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
             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;
 
@@ -375,9 +375,10 @@ static int aria_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
             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;
@@ -489,6 +490,16 @@ static int aria_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     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)
 {
@@ -532,6 +543,10 @@ static int aria_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
         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)
@@ -680,8 +695,6 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     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),
@@ -696,6 +709,11 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
         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),
@@ -730,10 +748,13 @@ static int aria_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
     }
 }
 
+#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 = { \
@@ -742,7 +763,7 @@ 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) \