Add rc5 ciphers to default provider
authorShane Lontis <shane.lontis@oracle.com>
Thu, 3 Oct 2019 06:05:49 +0000 (16:05 +1000)
committerShane Lontis <shane.lontis@oracle.com>
Thu, 3 Oct 2019 06:05:49 +0000 (16:05 +1000)
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/10006)

18 files changed:
crypto/err/openssl.txt
crypto/evp/evp_enc.c
doc/man7/provider-cipher.pod
include/openssl/core_names.h
providers/common/ciphers/cipher_common.c
providers/common/ciphers/cipher_local.h
providers/common/include/internal/ciphers/ciphercommon.h
providers/common/include/internal/provider_algs.h
providers/common/include/internal/providercommonerr.h
providers/common/provider_err.c
providers/default/ciphers/build.info
providers/default/ciphers/cipher_rc5.c [new file with mode: 0644]
providers/default/ciphers/cipher_rc5.h [new file with mode: 0644]
providers/default/ciphers/cipher_rc5_hw.c [new file with mode: 0644]
providers/default/defltprov.c
test/evp_test.c
test/recipes/30-test_evp.t
test/recipes/30-test_evp_data/evpciph_rc5.txt [new file with mode: 0644]

index c62728b2eab6b7c0267d9be47b9c8102eba77376..520ac1f9a48808072b8b7ac96c0e7d6ee09058eb 100644 (file)
@@ -2715,6 +2715,7 @@ PROV_R_UNABLE_TO_LOAD_SHA1:143:unable to load sha1
 PROV_R_UNABLE_TO_LOAD_SHA256:147:unable to load sha256
 PROV_R_UNSUPPORTED_CEK_ALG:145:unsupported cek alg
 PROV_R_UNSUPPORTED_MAC_TYPE:137:unsupported mac type
 PROV_R_UNABLE_TO_LOAD_SHA256:147:unable to load sha256
 PROV_R_UNSUPPORTED_CEK_ALG:145:unsupported cek alg
 PROV_R_UNSUPPORTED_MAC_TYPE:137:unsupported mac type
+PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS:152:unsupported number of rounds
 PROV_R_VALUE_ERROR:138:value error
 PROV_R_WRONG_FINAL_BLOCK_LENGTH:107:wrong final block length
 PROV_R_WRONG_OUTPUT_BUFFER_SIZE:139:wrong output buffer size
 PROV_R_VALUE_ERROR:138:value error
 PROV_R_WRONG_FINAL_BLOCK_LENGTH:107:wrong final block length
 PROV_R_WRONG_OUTPUT_BUFFER_SIZE:139:wrong output buffer size
index 09c49b6202dd8c56050a55201269c0ab4fe5fbaf..eb85b26e5ac04b4462b0a5989684b16b19d0e7a4 100644 (file)
@@ -269,7 +269,11 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
         case NID_sm4_ofb128:
         case NID_rc4:
         case NID_rc4_40:
         case NID_sm4_ofb128:
         case NID_rc4:
         case NID_rc4_40:
-        break;
+        case NID_rc5_cbc:
+        case NID_rc5_ecb:
+        case NID_rc5_cfb64:
+        case NID_rc5_ofb64:
+            break;
         default:
             goto legacy;
         }
         default:
             goto legacy;
         }
@@ -1069,6 +1073,7 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
     int ret = EVP_CTRL_RET_UNSUPPORTED;
     int set_params = 1;
     size_t sz = arg;
     int ret = EVP_CTRL_RET_UNSUPPORTED;
     int set_params = 1;
     size_t sz = arg;
+    unsigned int i;
     OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
 
     if (ctx == NULL || ctx->cipher == NULL) {
     OSSL_PARAM params[2] = { OSSL_PARAM_END, OSSL_PARAM_END };
 
     if (ctx == NULL || ctx->cipher == NULL) {
@@ -1109,6 +1114,14 @@ int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
             OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED,
                                               ptr, sz);
         break;
             OSSL_PARAM_construct_octet_string(OSSL_CIPHER_PARAM_AEAD_TLS1_IV_FIXED,
                                               ptr, sz);
         break;
+    case EVP_CTRL_GET_RC5_ROUNDS:
+        set_params = 0; /* Fall thru */
+    case EVP_CTRL_SET_RC5_ROUNDS:
+        if (arg < 0)
+            return 0;
+        i = (unsigned int)arg;
+        params[0] = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_ROUNDS, &i);
+        break;
     case EVP_CTRL_AEAD_GET_TAG:
         set_params = 0; /* Fall thru */
     case EVP_CTRL_AEAD_SET_TAG:
     case EVP_CTRL_AEAD_GET_TAG:
         set_params = 0; /* Fall thru */
     case EVP_CTRL_AEAD_SET_TAG:
index d5766f47a5707591364a44e2016f5e026fb8d4e7..3bae345b891501e2d19a1e4842d777963b6f8cce 100644 (file)
@@ -321,13 +321,18 @@ Gets a implementation specific randomly generated key for the associated
 cipher ctx. This is currently only supported by 3DES (which sets the key to
 odd parity).
 
 cipher ctx. This is currently only supported by 3DES (which sets the key to
 odd parity).
 
-=item "alg_id_param" (B<OSSL_CIPHER_PARAM_ALG_ID>) (octet string)
+=item "alg_id_param" (B<OSSL_CIPHER_PARAM_ALG_ID>) <octet string>
 
 Used to pass the DER encoded AlgorithmIdentifier parameter to or from
 the cipher implementation.  Functions like L<EVP_CIPHER_param_to_asn1(3)>
 and L<EVP_CIPHER_asn1_to_param(3)> use this parameter for any implementation
 that has the flag B<EVP_CIPH_FLAG_CUSTOM_ASN1> set.
 
 
 Used to pass the DER encoded AlgorithmIdentifier parameter to or from
 the cipher implementation.  Functions like L<EVP_CIPHER_param_to_asn1(3)>
 and L<EVP_CIPHER_asn1_to_param(3)> use this parameter for any implementation
 that has the flag B<EVP_CIPH_FLAG_CUSTOM_ASN1> set.
 
+=item "rounds" (B<OSSL_CIPHER_PARAM_ROUNDS>) <unsigned integer>
+
+Sets or gets the number of rounds to be used for a cipher.
+This is used by the RC5 cipher.
+
 =back
 
 =head1 RETURN VALUES
 =back
 
 =head1 RETURN VALUES
index 4659d1f08dff15e906d56989aa5e4e2f62b38e50..837c89b60d12018db400c704a6157037dc74f592 100644 (file)
@@ -59,6 +59,7 @@ extern "C" {
 #define OSSL_CIPHER_PARAM_IVLEN     "ivlen"      /* size_t */
 #define OSSL_CIPHER_PARAM_IV        "iv"         /* octet_string OR octet_ptr */
 #define OSSL_CIPHER_PARAM_NUM       "num"        /* uint */
 #define OSSL_CIPHER_PARAM_IVLEN     "ivlen"      /* size_t */
 #define OSSL_CIPHER_PARAM_IV        "iv"         /* octet_string OR octet_ptr */
 #define OSSL_CIPHER_PARAM_NUM       "num"        /* uint */
+#define OSSL_CIPHER_PARAM_ROUNDS    "rounds"     /* uint */
 #define OSSL_CIPHER_PARAM_AEAD_TAG           "tag"        /* octet_string */
 #define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD      "tlsaad"     /* octet_string */
 #define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD  "tlsaadpad"  /* size_t */
 #define OSSL_CIPHER_PARAM_AEAD_TAG           "tag"        /* octet_string */
 #define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD      "tlsaad"     /* octet_string */
 #define OSSL_CIPHER_PARAM_AEAD_TLS1_AAD_PAD  "tlsaadpad"  /* size_t */
index 34407879e60399176fde6b23cdbfb135397c405f..bc8776d87473f1dd8d2389cb1360d143c258c81e 100644 (file)
@@ -68,16 +68,8 @@ int cipher_generic_get_params(OSSL_PARAM params[], unsigned int md,
 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(cipher_generic)
 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(cipher_generic)
 
 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(cipher_generic)
 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(cipher_generic)
 
-static const OSSL_PARAM cipher_known_settable_ctx_params[] = {
-    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
-    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL),
-    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL),
-    OSSL_PARAM_END
-};
-const OSSL_PARAM *cipher_generic_settable_ctx_params(void)
-{
-    return cipher_known_settable_ctx_params;
-}
+CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(cipher_generic)
+CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(cipher_generic)
 
 /*-
  * AEAD cipher functions for OSSL_PARAM gettables and settables
 
 /*-
  * AEAD cipher functions for OSSL_PARAM gettables and settables
index cc37a348ed2a96aa88e663ffb5e838e09c5d3b23..898c99b1d3e7299e6d3eaf2c01cca2b8dddac387 100644 (file)
@@ -9,21 +9,5 @@
 
 #include "internal/ciphers/ciphercommon.h"
 
 
 #include "internal/ciphers/ciphercommon.h"
 
-#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name)                         \
-static const OSSL_PARAM name##_known_gettable_ctx_params[] = {                 \
-    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),                         \
-    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),                          \
-    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL),                          \
-    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL),                              \
-    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
-
-#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name)                           \
-    OSSL_PARAM_END                                                             \
-};                                                                             \
-const OSSL_PARAM * name##_gettable_ctx_params(void)                            \
-{                                                                              \
-    return name##_known_gettable_ctx_params;                                   \
-}
-
 void padblock(unsigned char *buf, size_t *buflen, size_t blocksize);
 int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize);
 void padblock(unsigned char *buf, size_t *buflen, size_t blocksize);
 int unpadblock(unsigned char *buf, size_t *buflen, size_t blocksize);
index 9a01abf6cba0b2c387e3bfdb4803b714431ba34c..e30af4dfbf86720ebbdd5b81acc627c6a651e7fd 100644 (file)
@@ -225,6 +225,35 @@ static int cipher_hw_##NAME##_##MODE##_cipher(PROV_CIPHER_CTX *ctx,            \
     return 1;                                                                  \
 }
 
     return 1;                                                                  \
 }
 
+#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(name)                         \
+static const OSSL_PARAM name##_known_gettable_ctx_params[] = {                 \
+    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),                         \
+    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_IVLEN, NULL),                          \
+    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL),                          \
+    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL),                              \
+    OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_IV, NULL, 0),
+
+#define CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(name)                           \
+    OSSL_PARAM_END                                                             \
+};                                                                             \
+const OSSL_PARAM * name##_gettable_ctx_params(void)                            \
+{                                                                              \
+    return name##_known_gettable_ctx_params;                                   \
+}
+
+#define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(name)                         \
+static const OSSL_PARAM name##_known_settable_ctx_params[] = {                 \
+    OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),                         \
+    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_PADDING, NULL),                          \
+    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_NUM, NULL),
+#define CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(name)                           \
+    OSSL_PARAM_END                                                             \
+};                                                                             \
+const OSSL_PARAM * name##_settable_ctx_params(void)                            \
+{                                                                              \
+    return name##_known_settable_ctx_params;                                   \
+}
+
 size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
                  const unsigned char **in, size_t *inlen);
 int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
 size_t fillblock(unsigned char *buf, size_t *buflen, size_t blocksize,
                  const unsigned char **in, size_t *inlen);
 int trailingdata(unsigned char *buf, size_t *buflen, size_t blocksize,
index 3e237886983261218c27785df32b22fb02b05fb6..08cc7062daf68b9efd72896a5de5d0229f8dd3f2 100644 (file)
@@ -159,6 +159,12 @@ extern const OSSL_DISPATCH sm4128ctr_functions[];
 extern const OSSL_DISPATCH sm4128ofb128_functions[];
 extern const OSSL_DISPATCH sm4128cfb128_functions[];
 #endif /* OPENSSL_NO_SM4 */
 extern const OSSL_DISPATCH sm4128ofb128_functions[];
 extern const OSSL_DISPATCH sm4128cfb128_functions[];
 #endif /* OPENSSL_NO_SM4 */
+#ifndef OPENSSL_NO_RC5
+extern const OSSL_DISPATCH rc5128ecb_functions[];
+extern const OSSL_DISPATCH rc5128cbc_functions[];
+extern const OSSL_DISPATCH rc5128ofb64_functions[];
+extern const OSSL_DISPATCH rc5128cfb64_functions[];
+#endif /* OPENSSL_NO_RC5 */
 
 #ifndef OPENSSL_NO_DES
 extern const OSSL_DISPATCH tdes_ede3_ecb_functions[];
 
 #ifndef OPENSSL_NO_DES
 extern const OSSL_DISPATCH tdes_ede3_ecb_functions[];
index 5ce5f32e7d7c7d5eea46ec5a6778f971a7370d5d..e813099051350bbd44def28c01bba9b93a9d0cfc 100644 (file)
@@ -8,8 +8,8 @@
  * https://www.openssl.org/source/license.html
  */
 
  * https://www.openssl.org/source/license.html
  */
 
-#ifndef OSSL_PROVIDERS_PROVIDERCOMMONERR_H
-# define OSSL_PROVIDERS_PROVIDERCOMMONERR_H
+#ifndef OPENSSL_PROVERR_H
+# define OPENSSL_PROVERR_H
 
 # include <openssl/opensslconf.h>
 # include <openssl/symhacks.h>
 
 # include <openssl/opensslconf.h>
 # include <openssl/symhacks.h>
@@ -96,6 +96,7 @@ int ERR_load_PROV_strings(void);
 # define PROV_R_UNABLE_TO_LOAD_SHA256                     147
 # define PROV_R_UNSUPPORTED_CEK_ALG                       145
 # define PROV_R_UNSUPPORTED_MAC_TYPE                      137
 # define PROV_R_UNABLE_TO_LOAD_SHA256                     147
 # define PROV_R_UNSUPPORTED_CEK_ALG                       145
 # define PROV_R_UNSUPPORTED_MAC_TYPE                      137
+# define PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS              152
 # define PROV_R_VALUE_ERROR                               138
 # define PROV_R_WRONG_FINAL_BLOCK_LENGTH                  107
 # define PROV_R_WRONG_OUTPUT_BUFFER_SIZE                  139
 # define PROV_R_VALUE_ERROR                               138
 # define PROV_R_WRONG_FINAL_BLOCK_LENGTH                  107
 # define PROV_R_WRONG_OUTPUT_BUFFER_SIZE                  139
index 27d6837af3c22cf58513052616f0ffb6cbb3da18..7d4b1ceb018b07e61b963f9f20509916080d88be 100644 (file)
@@ -44,6 +44,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY_LEN), "invalid key len"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY_LENGTH),
     "invalid key length"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY_LEN), "invalid key len"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_KEY_LENGTH),
     "invalid key length"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MAC), "invalid mac"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MODE), "invalid mode"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MODE_INT), "invalid mode int"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SALT_LENGTH),
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MODE), "invalid mode"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_MODE_INT), "invalid mode int"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_SALT_LENGTH),
@@ -52,6 +53,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAGLEN), "invalid taglen"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CEK_ALG), "missing cek alg"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_KEY), "missing key"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INVALID_TAGLEN), "invalid taglen"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_CEK_ALG), "missing cek alg"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_KEY), "missing key"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MAC), "missing mac"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MESSAGE_DIGEST),
     "missing message digest"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_PASS), "missing pass"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_MESSAGE_DIGEST),
     "missing message digest"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_MISSING_PASS), "missing pass"},
@@ -78,6 +80,8 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
     "unsupported cek alg"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_MAC_TYPE),
     "unsupported mac type"},
     "unsupported cek alg"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_MAC_TYPE),
     "unsupported mac type"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS),
+    "unsupported number of rounds"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_VALUE_ERROR), "value error"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_WRONG_FINAL_BLOCK_LENGTH),
     "wrong final block length"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_VALUE_ERROR), "value error"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_WRONG_FINAL_BLOCK_LENGTH),
     "wrong final block length"},
index 76a5135aacac6b16e08a9519ae117eb103c8a701..a42a31325efdda00c51d2d4c7fb478137954e0d0 100644 (file)
@@ -55,4 +55,9 @@ IF[{- !$disabled{rc4} -}]
       cipher_rc4.c cipher_rc4_hw.c
 ENDIF
 
       cipher_rc4.c cipher_rc4_hw.c
 ENDIF
 
+IF[{- !$disabled{rc5} -}]
+  SOURCE[../../../libcrypto]=\
+      cipher_rc5.c cipher_rc5_hw.c
+ENDIF
+
 INCLUDE[../../../libcrypto]=. ../../../crypto
 INCLUDE[../../../libcrypto]=. ../../../crypto
diff --git a/providers/default/ciphers/cipher_rc5.c b/providers/default/ciphers/cipher_rc5.c
new file mode 100644 (file)
index 0000000..645a6b8
--- /dev/null
@@ -0,0 +1,145 @@
+/*
+ * 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 RC5 cipher modes ecb, cbc, ofb, cfb */
+
+#include "cipher_rc5.h"
+#include "internal/provider_algs.h"
+#include "internal/providercommonerr.h"
+
+static OSSL_OP_cipher_freectx_fn rc5_freectx;
+static OSSL_OP_cipher_dupctx_fn rc5_dupctx;
+OSSL_OP_cipher_gettable_ctx_params_fn rc5_gettable_ctx_params;
+OSSL_OP_cipher_settable_ctx_params_fn rc5_settable_ctx_params;
+
+static void rc5_freectx(void *vctx)
+{
+    PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx;
+
+    OPENSSL_clear_free(ctx,  sizeof(*ctx));
+}
+
+static void *rc5_dupctx(void *ctx)
+{
+    PROV_RC5_CTX *in = (PROV_RC5_CTX *)ctx;
+    PROV_RC5_CTX *ret = OPENSSL_malloc(sizeof(*ret));
+
+    if (ret == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
+        return NULL;
+    }
+    *ret = *in;
+
+    return ret;
+}
+
+static int rc5_set_ctx_params(void *vctx, const OSSL_PARAM params[])
+{
+    PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx;
+    const OSSL_PARAM *p;
+
+    if (!cipher_generic_set_ctx_params(vctx, params))
+        return 0;
+
+    p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_ROUNDS);
+    if (p != NULL) {
+        unsigned int rounds;
+
+        if (!OSSL_PARAM_get_uint(p, &rounds)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
+            return 0;
+        }
+        if (rounds != RC5_8_ROUNDS
+            && rounds != RC5_12_ROUNDS
+            && rounds != RC5_16_ROUNDS) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS);
+            return 0;
+        }
+        ctx->rounds = rounds;
+    }
+    return 1;
+}
+
+CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(rc5)
+    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_ROUNDS, NULL),
+CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(rc5)
+
+CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(rc5)
+    OSSL_PARAM_uint(OSSL_CIPHER_PARAM_ROUNDS, NULL),
+CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(rc5)
+
+
+static int rc5_get_ctx_params(void *vctx, OSSL_PARAM params[])
+{
+    PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx;
+    OSSL_PARAM *p;
+
+    if (!cipher_generic_get_ctx_params(vctx, params))
+        return 0;
+    p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_ROUNDS);
+    if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->rounds)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
+        return 0;
+    }
+    return 1;
+}
+
+#define IMPLEMENT_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits,             \
+                         blkbits, ivbits, typ)                                 \
+static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params;     \
+static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[])          \
+{                                                                              \
+    return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags,  \
+                                     kbits, blkbits, ivbits);                  \
+}                                                                              \
+static OSSL_OP_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx;             \
+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, flags,               \
+                                PROV_CIPHER_HW_##alg##_##lcmode(kbits), NULL); \
+         ctx->rounds = RC5_12_ROUNDS;                                          \
+     }                                                                         \
+     return ctx;                                                               \
+}                                                                              \
+const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = {                       \
+    { OSSL_FUNC_CIPHER_NEWCTX,                                                 \
+      (void (*)(void)) alg##_##kbits##_##lcmode##_newctx },                    \
+    { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx },              \
+    { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx },                \
+    { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))cipher_generic_einit },   \
+    { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))cipher_generic_dinit },   \
+    { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))cipher_generic_##typ##_update },\
+    { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##typ##_final },  \
+    { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher },        \
+    { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
+      (void (*)(void)) alg##_##kbits##_##lcmode##_get_params },                \
+    { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
+      (void (*)(void))cipher_generic_gettable_params },                        \
+    { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                         \
+      (void (*)(void))rc5_get_ctx_params },                                    \
+    { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
+      (void (*)(void))rc5_gettable_ctx_params },                               \
+    { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
+      (void (*)(void))rc5_set_ctx_params },                                    \
+    { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
+     (void (*)(void))rc5_settable_ctx_params },                                \
+    { 0, NULL }                                                                \
+};
+
+/* rc5128ecb_functions */
+IMPLEMENT_cipher(rc5, RC5, ecb, ECB, EVP_CIPH_VARIABLE_LENGTH, 128, 64, 0, block)
+/* rc5128cbc_functions */
+IMPLEMENT_cipher(rc5, RC5, cbc, CBC, EVP_CIPH_VARIABLE_LENGTH, 128, 64, 64, block)
+/* rc5128ofb64_functions */
+IMPLEMENT_cipher(rc5, RC5, ofb64, OFB, EVP_CIPH_VARIABLE_LENGTH, 128, 8, 64, stream)
+/* rc5128cfb64_functions */
+IMPLEMENT_cipher(rc5, RC5, cfb64,  CFB, EVP_CIPH_VARIABLE_LENGTH, 128, 8, 64, stream)
diff --git a/providers/default/ciphers/cipher_rc5.h b/providers/default/ciphers/cipher_rc5.h
new file mode 100644 (file)
index 0000000..c415e18
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * 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/rc5.h>
+#include "internal/ciphers/ciphercommon.h"
+
+typedef struct prov_blowfish_ctx_st {
+    PROV_CIPHER_CTX base;      /* Must be first */
+    union {
+        OSSL_UNION_ALIGN;
+        RC5_32_KEY ks;         /* key schedule */
+    } ks;
+    unsigned int rounds;       /* number of rounds */
+} PROV_RC5_CTX;
+
+const PROV_CIPHER_HW *PROV_CIPHER_HW_rc5_cbc(size_t keybits);
+const PROV_CIPHER_HW *PROV_CIPHER_HW_rc5_ecb(size_t keybits);
+const PROV_CIPHER_HW *PROV_CIPHER_HW_rc5_ofb64(size_t keybits);
+const PROV_CIPHER_HW *PROV_CIPHER_HW_rc5_cfb64(size_t keybits);
diff --git a/providers/default/ciphers/cipher_rc5_hw.c b/providers/default/ciphers/cipher_rc5_hw.c
new file mode 100644 (file)
index 0000000..a9a05ba
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * 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_rc5.h"
+
+static int cipher_hw_rc5_initkey(PROV_CIPHER_CTX *ctx,
+                                 const unsigned char *key, size_t keylen)
+{
+    PROV_RC5_CTX *rctx = (PROV_RC5_CTX *)ctx;
+
+    return RC5_32_set_key(&rctx->ks.ks, keylen, key, rctx->rounds);
+}
+
+# define PROV_CIPHER_HW_rc5_mode(mode, UCMODE)                                 \
+IMPLEMENT_CIPHER_HW_##UCMODE(mode, rc5, PROV_RC5_CTX, RC5_32_KEY,              \
+                             RC5_32_##mode)                                    \
+static const PROV_CIPHER_HW rc5_##mode = {                                     \
+    cipher_hw_rc5_initkey,                                                     \
+    cipher_hw_rc5_##mode##_cipher                                              \
+};                                                                             \
+const PROV_CIPHER_HW *PROV_CIPHER_HW_rc5_##mode(size_t keybits)                \
+{                                                                              \
+    return &rc5_##mode;                                                        \
+}
+
+PROV_CIPHER_HW_rc5_mode(cbc, CBC)
+PROV_CIPHER_HW_rc5_mode(ecb, ECB)
+PROV_CIPHER_HW_rc5_mode(ofb64, OFB)
+PROV_CIPHER_HW_rc5_mode(cfb64, CFB)
index 7cfec618cef39a5f54ad6d0c006244c34e46c0fc..bcb897ba1c63e697aab9bbe3d8ca46804aeead7b 100644 (file)
@@ -241,6 +241,12 @@ static const OSSL_ALGORITHM deflt_ciphers[] = {
     { "RC4", "default=yes", rc4128_functions },
     { "RC4-40", "default=yes", rc440_functions },
 #endif /* OPENSSL_NO_RC4 */
     { "RC4", "default=yes", rc4128_functions },
     { "RC4-40", "default=yes", rc440_functions },
 #endif /* OPENSSL_NO_RC4 */
+#ifndef OPENSSL_NO_RC5
+    { "RC5-ECB", "default=yes", rc5128ecb_functions },
+    { "RC5-CBC", "default=yes", rc5128cbc_functions },
+    { "RC5-OFB", "default=yes", rc5128ofb64_functions },
+    { "RC5-CFB", "default=yes", rc5128cfb64_functions },
+#endif /* OPENSSL_NO_RC5 */
     { NULL, NULL, NULL }
 };
 
     { NULL, NULL, NULL }
 };
 
index 03581ff44756483b859a590a5bcef2f0576d8f05..04519545f1051692a680d04650c6958fb10121e2 100644 (file)
@@ -486,6 +486,7 @@ typedef struct cipher_data_st {
     unsigned char *key;
     size_t key_len;
     unsigned char *iv;
     unsigned char *key;
     size_t key_len;
     unsigned char *iv;
+    unsigned int rounds;
     size_t iv_len;
     unsigned char *plaintext;
     size_t plaintext_len;
     size_t iv_len;
     unsigned char *plaintext;
     size_t plaintext_len;
@@ -559,6 +560,13 @@ static int cipher_test_parse(EVP_TEST *t, const char *keyword,
 
     if (strcmp(keyword, "Key") == 0)
         return parse_bin(value, &cdat->key, &cdat->key_len);
 
     if (strcmp(keyword, "Key") == 0)
         return parse_bin(value, &cdat->key, &cdat->key_len);
+    if (strcmp(keyword, "Rounds") == 0) {
+        i = atoi(value);
+        if (i < 0)
+            return -1;
+        cdat->rounds = (unsigned int)i;
+        return 1;
+    }
     if (strcmp(keyword, "IV") == 0)
         return parse_bin(value, &cdat->iv, &cdat->iv_len);
     if (strcmp(keyword, "Plaintext") == 0)
     if (strcmp(keyword, "IV") == 0)
         return parse_bin(value, &cdat->iv, &cdat->iv_len);
     if (strcmp(keyword, "Plaintext") == 0)
@@ -683,6 +691,15 @@ static int cipher_test_enc(EVP_TEST *t, int enc,
         }
     }
 
         }
     }
 
+    if (expected->rounds > 0) {
+        int  rounds = (int)expected->rounds;
+
+        if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC5_ROUNDS, rounds, NULL)) {
+            t->err = "INVALID_ROUNDS";
+            goto err;
+        }
+    }
+
     if (!EVP_CIPHER_CTX_set_key_length(ctx, expected->key_len)) {
         t->err = "INVALID_KEY_LENGTH";
         goto err;
     if (!EVP_CIPHER_CTX_set_key_length(ctx, expected->key_len)) {
         t->err = "INVALID_KEY_LENGTH";
         goto err;
index e60f82415b524cff6be1184ffeda4c85660dfbec..7ff3a14e3ee62239abe6f9637b4b38eae75f50de 100644 (file)
@@ -53,6 +53,9 @@ push @defltfiles, @desfiles unless disabled("des");
 my @rc4files = qw( evpciph_rc4.txt );
 push @defltfiles, @rc4files unless disabled("rc4");
 
 my @rc4files = qw( evpciph_rc4.txt );
 push @defltfiles, @rc4files unless disabled("rc4");
 
+my @rc5files = qw( evpciph_rc5.txt );
+push @defltfiles, @rc5files unless disabled("rc5");
+
 plan tests =>
     ($no_fips ? 0 : 1)          # FIPS install test
     + (scalar(@configs) * scalar(@files))
 plan tests =>
     ($no_fips ? 0 : 1)          # FIPS install test
     + (scalar(@configs) * scalar(@files))
diff --git a/test/recipes/30-test_evp_data/evpciph_rc5.txt b/test/recipes/30-test_evp_data/evpciph_rc5.txt
new file mode 100644 (file)
index 0000000..300201b
--- /dev/null
@@ -0,0 +1,86 @@
+#
+# 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
+
+#The following tests were generated using legacy code, to ensure that the
+#provider ciphers have identical results.
+Title = RC5 Tests
+
+Cipher = RC5-ECB
+Key = 00000000000000000000000000000000
+Plaintext = 0000000000000000
+Ciphertext = 21a5dbee154b8f6d
+
+Cipher = RC5-ECB
+Key = 00000000000000000000000000000000
+Plaintext = 000102030405060708090A0B0C0D0E0F
+Ciphertext = d9d37019aec1161b27d7ad56b21f0f42
+
+Cipher = RC5-CBC
+Key = 00000000000000000000000000000000
+IV = 0000000000000000
+Plaintext = 0000000000000000
+Ciphertext = 21a5dbee154b8f6d
+
+Cipher = RC5-CBC
+Key = 0102030405060708090A0B0C0D0E0F10
+IV = 0102030405060708
+Plaintext = 000102030405060708090A0B0C0D0E0F
+Ciphertext = eeebae12d768ac9e5b3d6072a9c76c65
+
+Cipher = RC5-OFB
+Key = 00000000000000000000000000000000
+IV = 0000000000000000
+Plaintext = 0000000000000000
+Ciphertext = 21a5dbee154b8f6d
+
+Cipher = RC5-OFB
+Key = 0102030405060708090A0B0C0D0E0F10
+IV = 0102030405060708
+Plaintext = 000102030405060708090A0B0C0D0E0F
+Ciphertext = c0ad101b40fc7ffdfc386ea5ecf458b7
+
+Cipher = RC5-CFB
+Key = 00000000000000000000000000000000
+IV = 0000000000000000
+Plaintext = 0000000000000000
+Ciphertext = 21a5dbee154b8f6d
+
+Cipher = RC5-CFB
+Key = 0102030405060708090A0B0C0D0E0F10
+IV = 0102030405060708
+Plaintext = 000102030405060708090A0B0C0D0E0F
+Ciphertext = c0ad101b40fc7ffdeb97c6173bf2987e
+
+Cipher = RC5-CFB
+Key = 0102030405060708090A0B0C0D0E0F10
+IV = 0102030405060708
+Rounds = 8
+Plaintext = 000102030405060708090A0B0C0D0E0F
+Ciphertext = 439945301dfa830885ac2f3cf5e61d0e
+
+Cipher = RC5-CFB
+Key = 0102030405060708090A0B0C0D0E0F10
+IV = 0102030405060708
+Rounds = 16
+Plaintext = 000102030405060708090A0B0C0D0E0F
+Ciphertext = 5ad80530f4a19e622d03cd4f2b165730
+
+#Bad rounds
+Cipher = RC5-CFB
+Key = 0102030405060708090A0B0C0D0E0F10
+IV = 0102030405060708
+Rounds = 9
+Plaintext = 000102030405060708090A0B0C0D0E0F
+Result = INVALID_ROUNDS
+
+#bigger key
+Cipher = RC5-CFB
+Key = 0102030405060708090A0B0C0D0E0F101213141516
+IV = 0102030405060708
+Plaintext = 000102030405060708090A0B0C0D0E0F
+Ciphertext = b3724d2d9d1b9285e1338fd266c2277d