Add blowfish ciphers to default provider
authorShane Lontis <shane.lontis@oracle.com>
Sun, 15 Sep 2019 10:06:28 +0000 (20:06 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Sun, 15 Sep 2019 10:06:28 +0000 (20:06 +1000)
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9887)

13 files changed:
crypto/evp/evp_enc.c
providers/common/ciphers/cipher_aes_xts.c
providers/common/ciphers/cipher_common.c
providers/common/ciphers/cipher_tdes.c
providers/common/include/internal/ciphers/cipher_tdes.h
providers/common/include/internal/ciphers/ciphercommon.h
providers/common/include/internal/provider_algs.h
providers/default/ciphers/build.info
providers/default/ciphers/cipher_blowfish.c [new file with mode: 0644]
providers/default/ciphers/cipher_blowfish.h [new file with mode: 0644]
providers/default/ciphers/cipher_blowfish_hw.c [new file with mode: 0644]
providers/default/ciphers/cipher_tdes_wrap.c
providers/default/defltprov.c

index 6d657f76cd51d83f95a302b22c75cdf5946ea040..9a4e40d9a9e73fc9f51f44ab4b2ea873a265b3b6 100644 (file)
@@ -231,6 +231,10 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
         case NID_des_ede_cfb64:
         case NID_desx_cbc:
         case NID_id_smime_alg_CMS3DESwrap:
+        case NID_bf_cbc:
+        case NID_bf_ecb:
+        case NID_bf_cfb64:
+        case NID_bf_ofb64:
             break;
         default:
             goto legacy;
index feaa36991fb410bcf93950ffa687721dae64bc4b..c85475442b404467fceb02149e04ff2ffb27448c 100644 (file)
@@ -106,13 +106,13 @@ static int aes_xts_dinit(void *vctx, const unsigned char *key, size_t keylen,
     return aes_xts_init(vctx, key, keylen, iv, ivlen, 0);
 }
 
-static void *aes_xts_newctx(void *provctx, unsigned int mode, size_t kbits,
-                            size_t blkbits, size_t ivbits)
+static void *aes_xts_newctx(void *provctx, unsigned int mode, uint64_t flags,
+                            size_t kbits, size_t blkbits, size_t ivbits)
 {
     PROV_AES_XTS_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));
 
     if (ctx != NULL) {
-        cipher_generic_initkey(&ctx->base, kbits, blkbits, ivbits, mode,
+        cipher_generic_initkey(&ctx->base, kbits, blkbits, ivbits, mode, flags,
                                PROV_CIPHER_HW_aes_xts(kbits), NULL);
     }
     return ctx;
@@ -255,7 +255,7 @@ static int aes_##kbits##_##lcmode##_get_params(OSSL_PARAM params[])            \
 static OSSL_OP_cipher_newctx_fn aes_##kbits##_xts_newctx;                      \
 static void *aes_##kbits##_xts_newctx(void *provctx)                           \
 {                                                                              \
-    return aes_xts_newctx(provctx, EVP_CIPH_##UCMODE##_MODE, 2 * kbits,        \
+    return aes_xts_newctx(provctx, EVP_CIPH_##UCMODE##_MODE, flags, 2 * kbits, \
                           AES_XTS_BLOCK_BITS, AES_XTS_IV_BITS);                \
 }                                                                              \
 const OSSL_DISPATCH aes##kbits##xts_functions[] = {                            \
index 18d6dd9ca52eb377cda9a9da1ee292a243adcd6c..3c45dd5b9ac8fdb86c7ba472844e66803faaed84 100644 (file)
@@ -124,9 +124,13 @@ static int cipher_generic_init_internal(PROV_CIPHER_CTX *ctx,
         memcpy(ctx->iv, iv, ctx->ivlen);
     }
     if (key != NULL) {
-        if (keylen != ctx->keylen) {
-            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEYLEN);
-            return 0;
+        if ((ctx->flags & EVP_CIPH_VARIABLE_LENGTH) == 0) {
+            if (keylen != ctx->keylen) {
+                ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEYLEN);
+                return 0;
+            }
+        } else {
+            ctx->keylen = keylen;
         }
         return ctx->hw->init(ctx, key, ctx->keylen);
     }
@@ -384,11 +388,12 @@ int cipher_generic_set_ctx_params(void *vctx, const OSSL_PARAM params[])
 }
 
 void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
-                            size_t ivbits, unsigned int mode,
+                            size_t ivbits, unsigned int mode, uint64_t flags,
                             const PROV_CIPHER_HW *hw, void *provctx)
 {
     PROV_CIPHER_CTX *ctx = (PROV_CIPHER_CTX *)vctx;
 
+    ctx->flags = flags;
     ctx->pad = 1;
     ctx->keylen = ((kbits) / 8);
     ctx->ivlen = ((ivbits) / 8);
index 91df2ce194bb7693bd18999cc713714f08adbc13..e3e80d186ab3c01152877a552aa1eac3b71502b3 100644 (file)
 #include "internal/providercommonerr.h"
 
 void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
-                  size_t ivbits, const PROV_CIPHER_HW *hw)
+                  size_t ivbits, uint64_t flags, const PROV_CIPHER_HW *hw)
 {
     PROV_TDES_CTX *tctx = OPENSSL_zalloc(sizeof(*tctx));
 
     if (tctx != NULL)
-        cipher_generic_initkey(tctx, kbits, blkbits, ivbits, mode, hw, provctx);
+        cipher_generic_initkey(tctx, kbits, blkbits, ivbits, mode, flags, hw,
+                               provctx);
     return tctx;
 }
 
index 0d3c90c0af6d9f0cde4d42fa28eb65693ee68ed4..120201d1ad5cfa3d2fcb46db68d1a63893323f6b 100644 (file)
@@ -35,7 +35,7 @@ static OSSL_OP_cipher_newctx_fn tdes_##type##_##lcmode##_newctx;               \
 static void *tdes_##type##_##lcmode##_newctx(void *provctx)                    \
 {                                                                              \
     return tdes_newctx(provctx, EVP_CIPH_##UCMODE##_MODE, kbits, blkbits,      \
-                       ivbits, PROV_CIPHER_HW_tdes_##type##_##lcmode());       \
+                       ivbits, flags, PROV_CIPHER_HW_tdes_##type##_##lcmode());\
 }                                                                              \
 static OSSL_OP_cipher_get_params_fn tdes_##type##_##lcmode##_get_params;       \
 static int tdes_##type##_##lcmode##_get_params(OSSL_PARAM params[])            \
@@ -68,7 +68,7 @@ const OSSL_DISPATCH tdes_##type##_##lcmode##_functions[] = {                   \
 }
 
 void *tdes_newctx(void *provctx, int mode, size_t kbits, size_t blkbits,
-                  size_t ivbits, const PROV_CIPHER_HW *hw);
+                  size_t ivbits, uint64_t flags, const PROV_CIPHER_HW *hw);
 OSSL_OP_cipher_freectx_fn tdes_freectx;
 OSSL_OP_cipher_encrypt_init_fn tdes_einit;
 OSSL_OP_cipher_decrypt_init_fn tdes_dinit;
index 5593447264f492756e904442b44417f6ef245d04..fe55342e192990d3af99e204e09e8fd76b0bd56a 100644 (file)
@@ -85,7 +85,7 @@ int cipher_generic_get_params(OSSL_PARAM params[], unsigned int md,
                               unsigned long flags,
                               size_t kbits, size_t blkbits, size_t ivbits);
 void cipher_generic_initkey(void *vctx, size_t kbits, size_t blkbits,
-                            size_t ivbits, unsigned int mode,
+                            size_t ivbits, unsigned int mode, uint64_t flags,
                             const PROV_CIPHER_HW *hw, void *provctx);
 
 #define IMPLEMENT_generic_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits,     \
@@ -102,7 +102,7 @@ static void * alg##_##kbits##_##lcmode##_newctx(void *provctx)                 \
      PROV_##UCALG##_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));                   \
      if (ctx != NULL) {                                                        \
          cipher_generic_initkey(ctx, kbits, blkbits, ivbits,                   \
-                                EVP_CIPH_##UCMODE##_MODE,                      \
+                                EVP_CIPH_##UCMODE##_MODE, flags,               \
                                 PROV_CIPHER_HW_##alg##_##lcmode(kbits), NULL); \
      }                                                                         \
      return ctx;                                                               \
@@ -147,4 +147,80 @@ PROV_CIPHER_HW_FN cipher_hw_chunked_ofb128;
 #define cipher_hw_chunked_ctr  cipher_hw_generic_ctr
 #define cipher_hw_chunked_cfb1 cipher_hw_generic_cfb1
 
-
+#define IMPLEMENT_CIPHER_HW_OFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX)   \
+static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx,            \
+                                         unsigned char *out,                   \
+                                         const unsigned char *in, size_t len)  \
+{                                                                              \
+    int num = ctx->num;                                                        \
+    KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks);                               \
+                                                                               \
+    while (len >= MAXCHUNK) {                                                  \
+        FUNC_PREFIX##_encrypt(in, out, MAXCHUNK, key, ctx->iv, &num);          \
+        len -= MAXCHUNK;                                                       \
+        in += MAXCHUNK;                                                        \
+        out += MAXCHUNK;                                                       \
+    }                                                                          \
+    if (len > 0) {                                                             \
+        FUNC_PREFIX##_encrypt(in, out, (long)len, key, ctx->iv, &num);         \
+    }                                                                          \
+    ctx->num = num;                                                            \
+    return 1;                                                                  \
+}
+
+#define IMPLEMENT_CIPHER_HW_ECB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX)   \
+static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx,            \
+                                         unsigned char *out,                   \
+                                         const unsigned char *in, size_t len)  \
+{                                                                              \
+    size_t i, bl = ctx->blocksize;                                             \
+    KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks);                               \
+                                                                               \
+    if (len < bl)                                                              \
+        return 1;                                                              \
+    for (i = 0, len -= bl; i <= len; i += bl)                                  \
+        FUNC_PREFIX##_encrypt(in + i, out + i, key, ctx->enc);                 \
+    return 1;                                                                  \
+}
+
+#define IMPLEMENT_CIPHER_HW_CBC(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX)   \
+static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx,            \
+                                         unsigned char *out,                   \
+                                         const unsigned char *in, size_t len)  \
+{                                                                              \
+    KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks);                               \
+                                                                               \
+    while (len >= MAXCHUNK) {                                                  \
+        FUNC_PREFIX##_encrypt(in, out, MAXCHUNK, key, ctx->iv, ctx->enc);      \
+        len -= MAXCHUNK;                                                       \
+        in += MAXCHUNK;                                                        \
+        out += MAXCHUNK;                                                       \
+    }                                                                          \
+    if (len > 0)                                                               \
+        FUNC_PREFIX##_encrypt(in, out, (long)len, key, ctx->iv, ctx->enc);     \
+    return 1;                                                                  \
+}
+
+#define IMPLEMENT_CIPHER_HW_CFB(MODE, NAME, CTX_NAME, KEY_NAME, FUNC_PREFIX)   \
+static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx,            \
+                                         unsigned char *out,                   \
+                                         const unsigned char *in, size_t len)  \
+{                                                                              \
+    size_t chunk = MAXCHUNK;                                                   \
+    KEY_NAME *key = &(((CTX_NAME *)ctx)->ks.ks);                               \
+    int num = ctx->num;                                                        \
+                                                                               \
+    if (len < chunk)                                                           \
+        chunk = len;                                                           \
+    while (len > 0 && len >= chunk) {                                          \
+        FUNC_PREFIX##_encrypt(in, out, (long)chunk, key, ctx->iv, &num,        \
+                              ctx->enc);                                       \
+        len -= chunk;                                                          \
+        in += chunk;                                                           \
+        out += chunk;                                                          \
+        if (len < chunk)                                                       \
+            chunk = len;                                                       \
+    }                                                                          \
+    ctx->num = num;                                                            \
+    return 1;                                                                  \
+}
index e6da5f32a8e28bcf987e8b21d084fa3a81698df5..5f54612b0a10c303a3332bf797db18e798eb75e5 100644 (file)
@@ -116,6 +116,12 @@ extern const OSSL_DISPATCH camellia256ctr_functions[];
 extern const OSSL_DISPATCH camellia192ctr_functions[];
 extern const OSSL_DISPATCH camellia128ctr_functions[];
 #endif /* OPENSSL_NO_CAMELLIA */
+#ifndef OPENSSL_NO_BF
+extern const OSSL_DISPATCH blowfish128ecb_functions[];
+extern const OSSL_DISPATCH blowfish128cbc_functions[];
+extern const OSSL_DISPATCH blowfish64ofb64_functions[];
+extern const OSSL_DISPATCH blowfish64cfb64_functions[];
+#endif /* OPENSSL_NO_BF */
 
 extern const OSSL_DISPATCH tdes_ede3_ecb_functions[];
 extern const OSSL_DISPATCH tdes_ede3_cbc_functions[];
index 92f87e0301eaa304893eb56bef4c4d593c2c9762..a4ca5cc6c889bb3bcaaa48bb40c27650853cb5ed 100644 (file)
@@ -19,4 +19,9 @@ IF[{- !$disabled{camellia} -}]
       cipher_camellia.c cipher_camellia_hw.c
 ENDIF
 
+IF[{- !$disabled{bf} -}]
+  SOURCE[../../../libcrypto]=\
+      cipher_blowfish.c cipher_blowfish_hw.c
+ENDIF
+
 INCLUDE[../../../libcrypto]=. ../../../crypto
diff --git a/providers/default/ciphers/cipher_blowfish.c b/providers/default/ciphers/cipher_blowfish.c
new file mode 100644 (file)
index 0000000..9e2920d
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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 Blowfish cipher modes ecb, cbc, ofb, cfb */
+
+#include "cipher_blowfish.h"
+#include "internal/provider_algs.h"
+
+static OSSL_OP_cipher_freectx_fn blowfish_freectx;
+static OSSL_OP_cipher_dupctx_fn blowfish_dupctx;
+
+static void blowfish_freectx(void *vctx)
+{
+    PROV_BLOWFISH_CTX *ctx = (PROV_BLOWFISH_CTX *)vctx;
+
+    OPENSSL_clear_free(ctx,  sizeof(*ctx));
+}
+
+static void *blowfish_dupctx(void *ctx)
+{
+    PROV_BLOWFISH_CTX *in = (PROV_BLOWFISH_CTX *)ctx;
+    PROV_BLOWFISH_CTX *ret = OPENSSL_malloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    *ret = *in;
+
+    return ret;
+}
+
+/* bf_ecb_functions */
+IMPLEMENT_generic_cipher(blowfish, BLOWFISH, ecb, ECB, EVP_CIPH_VARIABLE_LENGTH, 128, 64, 0, block)
+/* bf_cbc_functions */
+IMPLEMENT_generic_cipher(blowfish, BLOWFISH, cbc, CBC, EVP_CIPH_VARIABLE_LENGTH, 128, 64, 64, block)
+/* bf_ofb_functions */
+IMPLEMENT_generic_cipher(blowfish, BLOWFISH, ofb64, OFB, EVP_CIPH_VARIABLE_LENGTH, 64, 8, 64, stream)
+/* bf_cfb_functions */
+IMPLEMENT_generic_cipher(blowfish, BLOWFISH, cfb64,  CFB, EVP_CIPH_VARIABLE_LENGTH, 64, 8, 64, stream)
diff --git a/providers/default/ciphers/cipher_blowfish.h b/providers/default/ciphers/cipher_blowfish.h
new file mode 100644 (file)
index 0000000..819a61f
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * 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 <openssl/blowfish.h>
+#include "internal/ciphers/ciphercommon.h"
+
+typedef struct prov_blowfish_ctx_st {
+    PROV_CIPHER_CTX base;      /* Must be first */
+    union {
+        OSSL_UNION_ALIGN;
+        BF_KEY ks;
+    } ks;
+} PROV_BLOWFISH_CTX;
+
+const PROV_CIPHER_HW *PROV_CIPHER_HW_blowfish_cbc(size_t keybits);
+const PROV_CIPHER_HW *PROV_CIPHER_HW_blowfish_ecb(size_t keybits);
+const PROV_CIPHER_HW *PROV_CIPHER_HW_blowfish_ofb64(size_t keybits);
+const PROV_CIPHER_HW *PROV_CIPHER_HW_blowfish_cfb64(size_t keybits);
diff --git a/providers/default/ciphers/cipher_blowfish_hw.c b/providers/default/ciphers/cipher_blowfish_hw.c
new file mode 100644 (file)
index 0000000..137aeef
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * 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_blowfish.h"
+
+static int cipher_hw_blowfish_initkey(PROV_CIPHER_CTX *ctx,
+                                      const unsigned char *key, size_t keylen)
+{
+    PROV_BLOWFISH_CTX *bctx =  (PROV_BLOWFISH_CTX *)ctx;
+
+    BF_set_key(&bctx->ks.ks, keylen, key);
+    return 1;
+}
+
+# define PROV_CIPHER_HW_blowfish_mode(mode, UCMODE)                            \
+IMPLEMENT_CIPHER_HW_##UCMODE(mode, blowfish, PROV_BLOWFISH_CTX, BF_KEY,        \
+                             BF_##mode)                                        \
+static const PROV_CIPHER_HW bf_##mode = {                                      \
+    cipher_hw_blowfish_initkey,                                                \
+    cipher_hw_blowfish_##mode##_cipher                                         \
+};                                                                             \
+const PROV_CIPHER_HW *PROV_CIPHER_HW_blowfish_##mode(size_t keybits)           \
+{                                                                              \
+    return &bf_##mode;                                                         \
+}
+
+PROV_CIPHER_HW_blowfish_mode(cbc, CBC)
+PROV_CIPHER_HW_blowfish_mode(ecb, ECB)
+PROV_CIPHER_HW_blowfish_mode(ofb64, OFB)
+PROV_CIPHER_HW_blowfish_mode(cfb64, CFB)
index 833e18190a94d903cde9cd547960a68a4554e71b..08662dbdb026529efa78444b9536adce671ddeed 100644 (file)
@@ -165,7 +165,7 @@ static OSSL_OP_cipher_newctx_fn tdes_wrap_newctx;                              \
 static void *tdes_wrap_newctx(void *provctx)                                   \
 {                                                                              \
     return tdes_newctx(provctx, EVP_CIPH_WRAP_MODE, kbits, blkbits, ivbits,    \
-                       PROV_CIPHER_HW_tdes_wrap_cbc());                        \
+                       flags, PROV_CIPHER_HW_tdes_wrap_cbc());                 \
 }                                                                              \
 static OSSL_OP_cipher_get_params_fn tdes_wrap_get_params;                      \
 static int tdes_wrap_get_params(OSSL_PARAM params[])                           \
index e829dbfac01649241a2a1f12b640b0a267fd4550..59a7b60e8389efe4055cf6145de7000737811746 100644 (file)
@@ -189,6 +189,12 @@ static const OSSL_ALGORITHM deflt_ciphers[] = {
     { "DESX-CBC", "default=yes", tdes_desx_cbc_functions },
     { "id-smime-alg-CMS3DESwrap", "default=yes", tdes_wrap_cbc_functions },
 #endif /* OPENSSL_NO_DES */
+#ifndef OPENSSL_NO_BF
+    { "BF-ECB", "default=yes", blowfish128ecb_functions },
+    { "BF-CBC", "default=yes", blowfish128cbc_functions },
+    { "BF-OFB", "default=yes", blowfish64ofb64_functions },
+    { "BF-CFB", "default=yes", blowfish64cfb64_functions },
+#endif /* OPENSSL_NO_BF */
     { NULL, NULL, NULL }
 };