xref: /src/crypto/openssl/providers/implementations/ciphers/cipher_rc5.c (revision f25b8c9fb4f58cf61adb47d7570abe7caa6d385d)
1 /*
2  * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the Apache License 2.0 (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9 
10 /* Dispatch functions for RC5 cipher modes ecb, cbc, ofb, cfb */
11 
12 /*
13  * RC5 low level APIs are deprecated for public use, but still ok for internal
14  * use.
15  */
16 #include "internal/deprecated.h"
17 
18 #include <openssl/proverr.h>
19 #include "cipher_rc5.h"
20 #include "prov/implementations.h"
21 #include "prov/providercommon.h"
22 
23 #define RC5_FLAGS PROV_CIPHER_FLAG_VARIABLE_LENGTH
24 
25 static OSSL_FUNC_cipher_encrypt_init_fn rc5_einit;
26 static OSSL_FUNC_cipher_decrypt_init_fn rc5_dinit;
27 static OSSL_FUNC_cipher_freectx_fn rc5_freectx;
28 static OSSL_FUNC_cipher_dupctx_fn rc5_dupctx;
29 OSSL_FUNC_cipher_gettable_ctx_params_fn rc5_gettable_ctx_params;
30 OSSL_FUNC_cipher_settable_ctx_params_fn rc5_settable_ctx_params;
31 static OSSL_FUNC_cipher_set_ctx_params_fn rc5_set_ctx_params;
32 
rc5_freectx(void * vctx)33 static void rc5_freectx(void *vctx)
34 {
35     PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx;
36 
37     ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx);
38     OPENSSL_clear_free(ctx, sizeof(*ctx));
39 }
40 
rc5_dupctx(void * ctx)41 static void *rc5_dupctx(void *ctx)
42 {
43     PROV_RC5_CTX *in = (PROV_RC5_CTX *)ctx;
44     PROV_RC5_CTX *ret;
45 
46     if (!ossl_prov_is_running())
47         return NULL;
48 
49     ret = OPENSSL_malloc(sizeof(*ret));
50     if (ret == NULL)
51         return NULL;
52     *ret = *in;
53 
54     return ret;
55 }
56 
rc5_einit(void * ctx,const unsigned char * key,size_t keylen,const unsigned char * iv,size_t ivlen,const OSSL_PARAM params[])57 static int rc5_einit(void *ctx, const unsigned char *key, size_t keylen,
58     const unsigned char *iv, size_t ivlen,
59     const OSSL_PARAM params[])
60 {
61     if (!ossl_cipher_generic_einit(ctx, key, keylen, iv, ivlen, NULL))
62         return 0;
63     return rc5_set_ctx_params(ctx, params);
64 }
65 
rc5_dinit(void * ctx,const unsigned char * key,size_t keylen,const unsigned char * iv,size_t ivlen,const OSSL_PARAM params[])66 static int rc5_dinit(void *ctx, const unsigned char *key, size_t keylen,
67     const unsigned char *iv, size_t ivlen,
68     const OSSL_PARAM params[])
69 {
70     if (!ossl_cipher_generic_dinit(ctx, key, keylen, iv, ivlen, NULL))
71         return 0;
72     return rc5_set_ctx_params(ctx, params);
73 }
74 
rc5_set_ctx_params(void * vctx,const OSSL_PARAM params[])75 static int rc5_set_ctx_params(void *vctx, const OSSL_PARAM params[])
76 {
77     PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx;
78     const OSSL_PARAM *p;
79 
80     if (ossl_param_is_empty(params))
81         return 1;
82 
83     if (!ossl_cipher_var_keylen_set_ctx_params(vctx, params))
84         return 0;
85 
86     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_ROUNDS);
87     if (p != NULL) {
88         unsigned int rounds;
89 
90         if (!OSSL_PARAM_get_uint(p, &rounds)) {
91             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
92             return 0;
93         }
94         if (rounds != RC5_8_ROUNDS
95             && rounds != RC5_12_ROUNDS
96             && rounds != RC5_16_ROUNDS) {
97             ERR_raise(ERR_LIB_PROV, PROV_R_UNSUPPORTED_NUMBER_OF_ROUNDS);
98             return 0;
99         }
100         ctx->rounds = rounds;
101     }
102     return 1;
103 }
104 
105 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(rc5)
OSSL_PARAM_uint(OSSL_CIPHER_PARAM_ROUNDS,NULL)106 OSSL_PARAM_uint(OSSL_CIPHER_PARAM_ROUNDS, NULL),
107     CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(rc5)
108 
109         CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(rc5)
110             OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
111     OSSL_PARAM_uint(OSSL_CIPHER_PARAM_ROUNDS, NULL),
112     CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(rc5)
113 
114         static int rc5_get_ctx_params(void *vctx, OSSL_PARAM params[])
115 {
116     PROV_RC5_CTX *ctx = (PROV_RC5_CTX *)vctx;
117     OSSL_PARAM *p;
118 
119     if (!ossl_cipher_generic_get_ctx_params(vctx, params))
120         return 0;
121     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_ROUNDS);
122     if (p != NULL && !OSSL_PARAM_set_uint(p, ctx->rounds)) {
123         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
124         return 0;
125     }
126     return 1;
127 }
128 
129 #define IMPLEMENT_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits,                       \
130     blkbits, ivbits, typ)                                                                \
131     static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params;         \
132     static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[])                \
133     {                                                                                    \
134         return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE,          \
135             flags, kbits, blkbits, ivbits);                                              \
136     }                                                                                    \
137     static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx;                 \
138     static void *alg##_##kbits##_##lcmode##_newctx(void *provctx)                        \
139     {                                                                                    \
140         PROV_##UCALG##_CTX *ctx;                                                         \
141         if (!ossl_prov_is_running())                                                     \
142             return NULL;                                                                 \
143         ctx = OPENSSL_zalloc(sizeof(*ctx));                                              \
144         if (ctx != NULL) {                                                               \
145             ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits,                     \
146                 EVP_CIPH_##UCMODE##_MODE, flags,                                         \
147                 ossl_prov_cipher_hw_##alg##_##lcmode(kbits),                             \
148                 NULL);                                                                   \
149             ctx->rounds = RC5_12_ROUNDS;                                                 \
150         }                                                                                \
151         return ctx;                                                                      \
152     }                                                                                    \
153     const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = {                      \
154         { OSSL_FUNC_CIPHER_NEWCTX,                                                       \
155             (void (*)(void))alg##_##kbits##_##lcmode##_newctx },                         \
156         { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void))alg##_freectx },                     \
157         { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void))alg##_dupctx },                       \
158         { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))rc5_einit },                    \
159         { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))rc5_dinit },                    \
160         { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_cipher_generic_##typ##_update }, \
161         { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##typ##_final },   \
162         { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher },         \
163         { OSSL_FUNC_CIPHER_GET_PARAMS,                                                   \
164             (void (*)(void))alg##_##kbits##_##lcmode##_get_params },                     \
165         { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                              \
166             (void (*)(void))ossl_cipher_generic_gettable_params },                       \
167         { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                               \
168             (void (*)(void))rc5_get_ctx_params },                                        \
169         { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                          \
170             (void (*)(void))rc5_gettable_ctx_params },                                   \
171         { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                               \
172             (void (*)(void))rc5_set_ctx_params },                                        \
173         { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                          \
174             (void (*)(void))rc5_settable_ctx_params },                                   \
175         OSSL_DISPATCH_END                                                                \
176     };
177 
178 /* ossl_rc5128ecb_functions */
179 IMPLEMENT_cipher(rc5, RC5, ecb, ECB, RC5_FLAGS, 128, 64, 0, block)
180 /* ossl_rc5128cbc_functions */
181 IMPLEMENT_cipher(rc5, RC5, cbc, CBC, RC5_FLAGS, 128, 64, 64, block)
182 /* ossl_rc5128ofb64_functions */
183 IMPLEMENT_cipher(rc5, RC5, ofb64, OFB, RC5_FLAGS, 128, 8, 64, stream)
184 /* ossl_rc5128cfb64_functions */
185 IMPLEMENT_cipher(rc5, RC5, cfb64, CFB, RC5_FLAGS, 128, 8, 64, stream)
186