[openssl] master update

shane.lontis at oracle.com shane.lontis at oracle.com
Fri Nov 8 02:16:09 UTC 2019


The branch master has been updated
       via  eb173822b2c02122844f4ffe89e38fe8e6d04697 (commit)
      from  1427d33cee59d6fe54efe1b5a322a1d7c8c03c20 (commit)


- Log -----------------------------------------------------------------
commit eb173822b2c02122844f4ffe89e38fe8e6d04697
Author: Shane Lontis <shane.lontis at oracle.com>
Date:   Fri Nov 8 12:14:44 2019 +1000

    Add AES SIV ciphers to default provider
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/10120)

-----------------------------------------------------------------------

Summary of changes:
 crypto/evp/evp_enc.c                               |   9 +
 doc/man7/provider-cipher.pod                       |   7 +
 include/openssl/core_names.h                       |   2 +
 providers/defltprov.c                              |   5 +
 providers/implementations/ciphers/build.info       |   6 +
 providers/implementations/ciphers/cipher_aes_siv.c | 236 +++++++++++++++++++++
 providers/implementations/ciphers/cipher_aes_siv.h |  34 +++
 .../implementations/ciphers/cipher_aes_siv_hw.c    |  99 +++++++++
 .../implementations/include/prov/implementations.h |   6 +
 test/recipes/30-test_evp.t                         |   6 +-
 10 files changed, 408 insertions(+), 2 deletions(-)
 create mode 100644 providers/implementations/ciphers/cipher_aes_siv.c
 create mode 100644 providers/implementations/ciphers/cipher_aes_siv.h
 create mode 100644 providers/implementations/ciphers/cipher_aes_siv_hw.c

diff --git a/crypto/evp/evp_enc.c b/crypto/evp/evp_enc.c
index efcb7e509a..53bd02d3c4 100644
--- a/crypto/evp/evp_enc.c
+++ b/crypto/evp/evp_enc.c
@@ -171,6 +171,9 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
         case NID_aes_256_gcm:
         case NID_aes_192_gcm:
         case NID_aes_128_gcm:
+        case NID_aes_256_siv:
+        case NID_aes_192_siv:
+        case NID_aes_128_siv:
         case NID_id_aes256_wrap:
         case NID_id_aes256_wrap_pad:
         case NID_id_aes192_wrap:
@@ -1124,6 +1127,12 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
         i = (unsigned int)arg;
         params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_ROUNDS, &i);
         break;
+    case EVP_CTRL_SET_SPEED:
+        if (arg < 0)
+            return 0;
+        i = (unsigned int)arg;
+        params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_SPEED, &i);
+        break;
     case EVP_CTRL_AEAD_GET_TAG:
         set_params = 0; /* Fall thru */
     case EVP_CTRL_AEAD_SET_TAG:
diff --git a/doc/man7/provider-cipher.pod b/doc/man7/provider-cipher.pod
index cd9e0fd8a9..c5415a5441 100644
--- a/doc/man7/provider-cipher.pod
+++ b/doc/man7/provider-cipher.pod
@@ -342,6 +342,13 @@ This is used by the RC5 cipher.
 Gets or sets the effective keybits used for a RC2 cipher.
 The length of the "keybits" parameter should not exceed that of a B<size_t>.
 
+=item "speed" (B<OSSL_CIPHER_PARAM_SPEED>) <unsigned integer>
+
+Sets the speed option for the associated cipher ctx. This is only supported
+by AES SIV ciphers which disallow multiple operations by default.
+Setting "speed" to 1 allows another encrypt or decrypt operation to be
+performed. This is used for performance testing.
+
 =back
 
 =head1 RETURN VALUES
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index 4cbcf0cc71..42350e80d1 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -69,9 +69,11 @@ extern "C" {
 #define OSSL_CIPHER_PARAM_AEAD_MAC_KEY       "mackey"     /* octet_string */
 #define OSSL_CIPHER_PARAM_RANDOM_KEY         "randkey"    /* octet_string */
 #define OSSL_CIPHER_PARAM_RC2_KEYBITS        "keybits"    /* size_t */
+#define OSSL_CIPHER_PARAM_SPEED              "speed"      /* uint */
 /* For passing the AlgorithmIdentifier parameter in DER form */
 #define OSSL_CIPHER_PARAM_ALG_ID             "alg_id_param" /* octet_string */
 
+
 /* digest parameters */
 #define OSSL_DIGEST_PARAM_XOFLEN     "xoflen"    /* size_t */
 #define OSSL_DIGEST_PARAM_SSL3_MS    "ssl3-ms"   /* octet string */
diff --git a/providers/defltprov.c b/providers/defltprov.c
index a0f3b8bb9f..186f1f5368 100644
--- a/providers/defltprov.c
+++ b/providers/defltprov.c
@@ -156,6 +156,11 @@ static const OSSL_ALGORITHM deflt_ciphers[] = {
     { "AES-192-OCB", "default=yes", aes192ocb_functions },
     { "AES-128-OCB", "default=yes", aes128ocb_functions },
 #endif /* OPENSSL_NO_OCB */
+#ifndef OPENSSL_NO_SIV
+    { "AES-128-SIV", "default=yes", aes128siv_functions },
+    { "AES-192-SIV", "default=yes", aes192siv_functions },
+    { "AES-256-SIV", "default=yes", aes256siv_functions },
+#endif /* OPENSSL_NO_SIV */
     { "AES-256-GCM:id-aes256-GCM", "default=yes", aes256gcm_functions },
     { "AES-192-GCM:id-aes192-GCM", "default=yes", aes192gcm_functions },
     { "AES-128-GCM:id-aes128-GCM", "default=yes", aes128gcm_functions },
diff --git a/providers/implementations/ciphers/build.info b/providers/implementations/ciphers/build.info
index 7f0b76c01b..1ac2a70ca6 100644
--- a/providers/implementations/ciphers/build.info
+++ b/providers/implementations/ciphers/build.info
@@ -21,6 +21,7 @@ $RC5_GOAL=../../libimplementations.a
 $RC2_GOAL=../../libimplementations.a
 $CHACHA_GOAL=../../libimplementations.a
 $CHACHAPOLY_GOAL=../../libimplementations.a
+$SIV_GOAL=../../libimplementations.a
 
 IF[{- !$disabled{des} -}]
   SOURCE[$TDES_1_GOAL]=cipher_tdes.c cipher_tdes_hw.c
@@ -37,6 +38,11 @@ SOURCE[$AES_GOAL]=\
 SOURCE[../../libfips.a]=cipher_aes_xts_fips.c
 SOURCE[../../libnonfips.a]=cipher_aes_xts_fips.c
 
+IF[{- !$disabled{siv} -}]
+  SOURCE[$SIV_GOAL]=\
+      cipher_aes_siv.c cipher_aes_siv_hw.c
+ENDIF
+
 IF[{- !$disabled{des} -}]
   SOURCE[$TDES_2_GOAL]=\
       cipher_tdes_default.c cipher_tdes_default_hw.c \
diff --git a/providers/implementations/ciphers/cipher_aes_siv.c b/providers/implementations/ciphers/cipher_aes_siv.c
new file mode 100644
index 0000000000..6a5d211a7d
--- /dev/null
+++ b/providers/implementations/ciphers/cipher_aes_siv.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * 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
+ */
+
+/* Dispatch functions for AES SIV mode */
+
+#include "cipher_aes_siv.h"
+#include "prov/implementations.h"
+#include "prov/providercommonerr.h"
+#include "prov/cipher_aead.h"
+
+#define siv_stream_update siv_cipher
+#define SIV_FLAGS AEAD_FLAGS
+
+static void *aes_siv_newctx(void *provctx, size_t keybits, unsigned int mode,
+                            uint64_t flags)
+{
+    PROV_AES_SIV_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
+
+    if (ctx != NULL) {
+        ctx->taglen = SIV_LEN;
+        ctx->mode = mode;
+        ctx->flags = flags;
+        ctx->keylen = keybits / 8;
+        ctx->hw = PROV_CIPHER_HW_aes_siv(keybits);
+    }
+    return ctx;
+}
+
+static void aes_siv_freectx(void *vctx)
+{
+    PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
+
+    if (ctx != NULL) {
+        ctx->hw->cleanup(ctx);
+        OPENSSL_clear_free(ctx,  sizeof(*ctx));
+    }
+}
+
+static int siv_init(void *vctx, const unsigned char *key, size_t keylen,
+                    const unsigned char *iv, size_t ivlen, int enc)
+{
+    PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
+
+    ctx->enc = enc;
+
+    if (iv != NULL)
+        return 0;
+
+    if (key != NULL) {
+        if (keylen != ctx->keylen) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+        return ctx->hw->initkey(ctx, key, ctx->keylen);
+    }
+    return 1;
+}
+
+static int siv_einit(void *vctx, const unsigned char *key, size_t keylen,
+                     const unsigned char *iv, size_t ivlen)
+{
+    return siv_init(vctx, key, keylen, iv, ivlen, 1);
+}
+
+static int siv_dinit(void *vctx, const unsigned char *key, size_t keylen,
+                     const unsigned char *iv, size_t ivlen)
+{
+    return siv_init(vctx, key, keylen, iv, ivlen, 0);
+}
+
+static int siv_cipher(void *vctx, unsigned char *out, size_t *outl,
+                      size_t outsize, const unsigned char *in, size_t inl)
+{
+    PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
+
+    if (outsize < inl) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL);
+        return 0;
+    }
+
+    if (ctx->hw->cipher(ctx, out, in, inl) <= 0)
+        return 0;
+
+    if (outl != NULL)
+        *outl = inl;
+    return 1;
+}
+
+static int siv_stream_final(void *vctx, unsigned char *out, size_t *outl,
+                            size_t outsize)
+{
+    PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
+
+    if (!ctx->hw->cipher(vctx, out, NULL, 0))
+        return 0;
+
+    if (outl != NULL)
+        *outl = 0;
+    return 1;
+}
+
+static int aes_siv_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+    PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
+    SIV128_CONTEXT *sctx = &ctx->siv;
+    OSSL_PARAM *p;
+
+    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAG);
+    if (p != NULL && p->data_type == OSSL_PARAM_OCTET_STRING) {
+        if (!ctx->enc
+            || p->data_size != ctx->taglen
+            || !OSSL_PARAM_set_octet_string(p, &sctx->tag.byte, ctx->taglen)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+            return 0;
+        }
+    }
+    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_AEAD_TAGLEN);
+    if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->taglen)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+        return 0;
+    }
+    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_KEYLEN);
+    if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->keylen)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+        return 0;
+    }
+    return 1;
+}
+
+static const OSSL_PARAM aes_siv_known_gettable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
+    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_AEAD_TAGLEN, NULL),
+    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_SPEED, NULL),
+    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *aes_siv_gettable_ctx_params(void)
+{
+    return aes_siv_known_gettable_ctx_params;
+}
+
+static int aes_siv_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
+    const OSSL_PARAM *p;
+    unsigned int speed = 0;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG);
+    if (p != NULL) {
+        if (ctx->enc)
+            return 1;
+        if (p->data_type != OSSL_PARAM_OCTET_STRING
+            || !ctx->hw->settag(ctx, p->data, p->data_size)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
+            return 0;
+        }
+    }
+    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_SPEED);
+    if (p != NULL) {
+        if (!OSSL_PARAM_get_uint(p, &speed)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
+            return 0;
+        }
+        ctx->hw->setspeed(ctx, (int)speed);
+    }
+    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_KEYLEN);
+    if (p != NULL) {
+        size_t keylen;
+
+        if (!OSSL_PARAM_get_size_t(p, &keylen)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
+            return 0;
+        }
+        /* The key length can not be modified */
+        if (keylen != ctx->keylen)
+            return 0;
+    }
+    return 1;
+}
+
+static const OSSL_PARAM aes_siv_known_settable_ctx_params[] = {
+    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
+    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_SPEED, NULL),
+    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_AEAD_TAG, NULL, 0),
+    OSSL_PARAM_END
+};
+static const OSSL_PARAM *aes_siv_settable_ctx_params(void)
+{
+    return aes_siv_known_settable_ctx_params;
+}
+
+#define IMPLEMENT_cipher(alg, lc, UCMODE, flags, kbits, blkbits, ivbits)       \
+static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lc##_get_params;         \
+static int alg##_##kbits##_##lc##_get_params(OSSL_PARAM params[])              \
+{                                                                              \
+    return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE,         \
+                                     flags, 2*kbits, blkbits, ivbits);         \
+}                                                                              \
+static OSSL_OP_cipher_newctx_fn alg##kbits##lc##_newctx;                       \
+static void * alg##kbits##lc##_newctx(void *provctx)                           \
+{                                                                              \
+    return alg##_##lc##_newctx(provctx, 2*kbits, EVP_CIPH_##UCMODE##_MODE,     \
+                               flags);                                         \
+}                                                                              \
+const OSSL_DISPATCH alg##kbits##lc##_functions[] = {                           \
+    { OSSL_FUNC_CIPHER_NEWCTX, (void (*)(void))alg##kbits##lc##_newctx },      \
+    { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_##lc##_freectx },        \
+    { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void)) lc##_einit },            \
+    { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void)) lc##_dinit },            \
+    { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void)) lc##_stream_update },          \
+    { OSSL_FUNC_CIPHER_FINAL, (void (*)(void)) lc##_stream_final },            \
+    { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void)) lc##_cipher },                 \
+    { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
+      (void (*)(void)) alg##_##kbits##_##lc##_get_params },                    \
+    { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
+      (void (*)(void))cipher_generic_gettable_params },                        \
+    { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                         \
+      (void (*)(void)) alg##_##lc##_get_ctx_params },                          \
+    { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
+      (void (*)(void)) alg##_##lc##_gettable_ctx_params },                     \
+    { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
+      (void (*)(void)) alg##_##lc##_set_ctx_params },                          \
+    { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
+      (void (*)(void)) alg##_##lc##_settable_ctx_params },                     \
+    { 0, NULL }                                                                \
+};
+
+IMPLEMENT_cipher(aes, siv, SIV, SIV_FLAGS, 128, 8, 0)
+IMPLEMENT_cipher(aes, siv, SIV, SIV_FLAGS, 192, 8, 0)
+IMPLEMENT_cipher(aes, siv, SIV, SIV_FLAGS, 256, 8, 0)
diff --git a/providers/implementations/ciphers/cipher_aes_siv.h b/providers/implementations/ciphers/cipher_aes_siv.h
new file mode 100644
index 0000000000..8f35d757dc
--- /dev/null
+++ b/providers/implementations/ciphers/cipher_aes_siv.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * 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 "prov/ciphercommon.h"
+#include "include/crypto/siv.h"
+
+typedef struct prov_cipher_hw_aes_siv_st {
+    int (*initkey)(void *ctx, const uint8_t *key, size_t keylen);
+    int (*cipher)(void *ctx, unsigned char *out, const unsigned char *in,
+                  size_t len);
+    void (*setspeed)(void *ctx, int speed);
+    int (*settag)(void *ctx, const unsigned char *tag, size_t tagl);
+    void (*cleanup)(void *ctx);
+} PROV_CIPHER_HW_AES_SIV;
+
+typedef struct prov_siv_ctx_st {
+    unsigned int mode;       /* The mode that we are using */
+    unsigned int enc : 1;    /* Set to 1 if we are encrypting or 0 otherwise */
+    uint64_t flags;
+    size_t keylen;           /* The input keylength (twice the alg key length) */
+    size_t taglen;           /* the taglen is the same as the sivlen */
+    SIV128_CONTEXT siv;
+    EVP_CIPHER *ctr;        /* These are fetched - so we need to free them */
+    EVP_CIPHER *cbc;
+    const PROV_CIPHER_HW_AES_SIV *hw;
+} PROV_AES_SIV_CTX;
+
+const PROV_CIPHER_HW_AES_SIV *PROV_CIPHER_HW_aes_siv(size_t keybits);
diff --git a/providers/implementations/ciphers/cipher_aes_siv_hw.c b/providers/implementations/ciphers/cipher_aes_siv_hw.c
new file mode 100644
index 0000000000..b8fbc61a63
--- /dev/null
+++ b/providers/implementations/ciphers/cipher_aes_siv_hw.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * 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 "cipher_aes_siv.h"
+
+static int aes_siv_initkey(void *vctx, const unsigned char *key, size_t keylen)
+{
+    PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
+    SIV128_CONTEXT *sctx = &ctx->siv;
+    size_t klen  = keylen / 2;
+
+    switch (klen) {
+    case 16:
+        ctx->cbc = EVP_CIPHER_fetch(NULL, "AES-128-CBC", "");
+        ctx->ctr = EVP_CIPHER_fetch(NULL, "AES-128-CTR", "");
+        break;
+    case 24:
+        ctx->cbc = EVP_CIPHER_fetch(NULL, "AES-192-CBC", "");
+        ctx->ctr = EVP_CIPHER_fetch(NULL, "AES-192-CTR", "");
+        break;
+    case 32:
+        ctx->cbc = EVP_CIPHER_fetch(NULL, "AES-256-CBC", "");
+        ctx->ctr = EVP_CIPHER_fetch(NULL, "AES-256-CTR", "");
+        break;
+    default:
+        return 0;
+    }
+    /*
+     * klen is the length of the underlying cipher, not the input key,
+     * which should be twice as long
+     */
+    return CRYPTO_siv128_init(sctx, key, klen, ctx->cbc, ctx->ctr);
+}
+
+static int aes_siv_settag(void *vctx, const unsigned char *tag, size_t tagl)
+{
+    PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
+    SIV128_CONTEXT *sctx = &ctx->siv;
+
+    return CRYPTO_siv128_set_tag(sctx, tag, tagl);
+}
+
+static void aes_siv_setspeed(void *vctx, int speed)
+{
+    PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
+    SIV128_CONTEXT *sctx = &ctx->siv;
+
+    CRYPTO_siv128_speed(sctx, (int)speed);
+}
+
+static void aes_siv_cleanup(void *vctx)
+{
+    PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
+    SIV128_CONTEXT *sctx = &ctx->siv;
+
+    CRYPTO_siv128_cleanup(sctx);
+    EVP_CIPHER_free(ctx->cbc);
+    EVP_CIPHER_free(ctx->ctr);
+}
+
+static int aes_siv_cipher(void *vctx, unsigned char *out,
+                          const unsigned char *in, size_t len)
+{
+    PROV_AES_SIV_CTX *ctx = (PROV_AES_SIV_CTX *)vctx;
+    SIV128_CONTEXT *sctx = &ctx->siv;
+
+    /* EncryptFinal or DecryptFinal */
+    if (in == NULL)
+        return CRYPTO_siv128_finish(sctx) == 0;
+
+    /* Deal with associated data */
+    if (out == NULL)
+        return (CRYPTO_siv128_aad(sctx, in, len) == 1);
+
+    if (ctx->enc)
+        return CRYPTO_siv128_encrypt(sctx, in, out, len) > 0;
+
+    return CRYPTO_siv128_decrypt(sctx, in, out, len) > 0;
+}
+
+static const PROV_CIPHER_HW_AES_SIV aes_siv_hw =
+{
+    aes_siv_initkey,
+    aes_siv_cipher,
+    aes_siv_setspeed,
+    aes_siv_settag,
+    aes_siv_cleanup
+};
+
+const PROV_CIPHER_HW_AES_SIV *PROV_CIPHER_HW_aes_siv(size_t keybits)
+{
+    return &aes_siv_hw;
+}
diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h
index ded3ef97f7..9aef2c3768 100644
--- a/providers/implementations/include/prov/implementations.h
+++ b/providers/implementations/include/prov/implementations.h
@@ -211,6 +211,12 @@ extern const OSSL_DISPATCH chacha20_poly1305_functions[];
 #endif /* OPENSSL_NO_CHACHA */
 
 
+#ifndef OPENSSL_NO_SIV
+extern const OSSL_DISPATCH aes128siv_functions[];
+extern const OSSL_DISPATCH aes192siv_functions[];
+extern const OSSL_DISPATCH aes256siv_functions[];
+#endif /* OPENSSL_NO_SIV */
+
 /* MACs */
 extern const OSSL_DISPATCH blake2bmac_functions[];
 extern const OSSL_DISPATCH blake2smac_functions[];
diff --git a/test/recipes/30-test_evp.t b/test/recipes/30-test_evp.t
index 28029e765c..a5060971fc 100644
--- a/test/recipes/30-test_evp.t
+++ b/test/recipes/30-test_evp.t
@@ -33,11 +33,13 @@ push @configs, 'fips.cnf' unless $no_fips;
 
 my @files = qw( evpciph.txt evpdigest.txt );
 my @defltfiles = qw( evpencod.txt evpkdf.txt evppkey_kdf.txt evpmac.txt
-    evppbe.txt evppkey.txt evppkey_ecc.txt evpcase.txt evpaessiv.txt
-    evpccmcavs.txt );
+    evppbe.txt evppkey.txt evppkey_ecc.txt evpcase.txt evpccmcavs.txt );
 my @ideafiles = qw( evpciph_idea.txt );
 push @defltfiles, @ideafiles unless disabled("idea");
 
+my @sivfiles = qw( evpaessiv.txt );
+push @defltfiles, @sivfiles unless disabled("siv");
+
 my @castfiles = qw( evpciph_cast5.txt );
 push @defltfiles, @castfiles unless disabled("cast");
 


More information about the openssl-commits mailing list