]>
Commit | Line | Data |
---|---|---|
f816aa47 | 1 | /* |
a28d06f3 | 2 | * Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved. |
f816aa47 SL |
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 RC2 cipher modes ecb, cbc, ofb, cfb */ | |
11 | ||
ee2993ab P |
12 | /* |
13 | * RC2 low level APIs are deprecated for public use, but still ok for internal | |
14 | * use. | |
15 | */ | |
16 | #include "internal/deprecated.h" | |
17 | ||
2741128e | 18 | #include <openssl/proverr.h> |
f816aa47 | 19 | #include "cipher_rc2.h" |
af3e7e1b | 20 | #include "prov/implementations.h" |
f99d3eed | 21 | #include "prov/providercommon.h" |
f816aa47 SL |
22 | |
23 | #define RC2_40_MAGIC 0xa0 | |
24 | #define RC2_64_MAGIC 0x78 | |
25 | #define RC2_128_MAGIC 0x3a | |
a054d15c | 26 | #define RC2_FLAGS PROV_CIPHER_FLAG_VARIABLE_LENGTH |
f816aa47 | 27 | |
8f42380a P |
28 | static OSSL_FUNC_cipher_encrypt_init_fn rc2_einit; |
29 | static OSSL_FUNC_cipher_decrypt_init_fn rc2_dinit; | |
363b1e5d DMSP |
30 | static OSSL_FUNC_cipher_freectx_fn rc2_freectx; |
31 | static OSSL_FUNC_cipher_dupctx_fn rc2_dupctx; | |
32 | static OSSL_FUNC_cipher_gettable_ctx_params_fn rc2_gettable_ctx_params; | |
33 | static OSSL_FUNC_cipher_settable_ctx_params_fn rc2_settable_ctx_params; | |
8f42380a | 34 | static OSSL_FUNC_cipher_set_ctx_params_fn rc2_set_ctx_params; |
f816aa47 SL |
35 | |
36 | static void rc2_freectx(void *vctx) | |
37 | { | |
38 | PROV_RC2_CTX *ctx = (PROV_RC2_CTX *)vctx; | |
39 | ||
592dcfd3 | 40 | ossl_cipher_generic_reset_ctx((PROV_CIPHER_CTX *)vctx); |
f816aa47 SL |
41 | OPENSSL_clear_free(ctx, sizeof(*ctx)); |
42 | } | |
43 | ||
44 | static void *rc2_dupctx(void *ctx) | |
45 | { | |
46 | PROV_RC2_CTX *in = (PROV_RC2_CTX *)ctx; | |
f99d3eed | 47 | PROV_RC2_CTX *ret; |
f816aa47 | 48 | |
f99d3eed P |
49 | if (!ossl_prov_is_running()) |
50 | return NULL; | |
51 | ||
52 | ret = OPENSSL_malloc(sizeof(*ret)); | |
e077455e | 53 | if (ret == NULL) |
f816aa47 | 54 | return NULL; |
f816aa47 SL |
55 | *ret = *in; |
56 | ||
57 | return ret; | |
58 | } | |
59 | ||
60 | static int rc2_keybits_to_magic(int keybits) | |
61 | { | |
62 | switch (keybits) { | |
63 | case 128: | |
64 | return RC2_128_MAGIC; | |
65 | case 64: | |
66 | return RC2_64_MAGIC; | |
67 | case 40: | |
68 | return RC2_40_MAGIC; | |
69 | } | |
70 | ERR_raise(ERR_LIB_PROV, PROV_R_UNSUPPORTED_KEY_SIZE); | |
71 | return 0; | |
72 | } | |
73 | ||
74 | static int rc2_magic_to_keybits(int magic) | |
75 | { | |
76 | switch (magic) { | |
77 | case RC2_128_MAGIC: | |
78 | return 128; | |
79 | case RC2_64_MAGIC: | |
80 | return 64; | |
81 | case RC2_40_MAGIC: | |
82 | return 40; | |
83 | } | |
84 | ERR_raise(ERR_LIB_PROV, PROV_R_UNSUPPORTED_KEY_SIZE); | |
85 | return 0; | |
86 | } | |
87 | ||
8f42380a P |
88 | static int rc2_einit(void *ctx, const unsigned char *key, size_t keylen, |
89 | const unsigned char *iv, size_t ivlen, | |
90 | const OSSL_PARAM params[]) | |
91 | { | |
92 | if (!ossl_cipher_generic_einit(ctx, key, keylen, iv, ivlen, NULL)) | |
93 | return 0; | |
94 | return rc2_set_ctx_params(ctx, params); | |
95 | } | |
96 | ||
97 | static int rc2_dinit(void *ctx, const unsigned char *key, size_t keylen, | |
98 | const unsigned char *iv, size_t ivlen, | |
99 | const OSSL_PARAM params[]) | |
100 | { | |
101 | if (!ossl_cipher_generic_dinit(ctx, key, keylen, iv, ivlen, NULL)) | |
102 | return 0; | |
103 | return rc2_set_ctx_params(ctx, params); | |
104 | } | |
105 | ||
f816aa47 SL |
106 | static int rc2_get_ctx_params(void *vctx, OSSL_PARAM params[]) |
107 | { | |
108 | PROV_RC2_CTX *ctx = (PROV_RC2_CTX *)vctx; | |
109 | OSSL_PARAM *p; | |
110 | ||
592dcfd3 | 111 | if (!ossl_cipher_generic_get_ctx_params(vctx, params)) |
f816aa47 SL |
112 | return 0; |
113 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RC2_KEYBITS); | |
114 | if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->key_bits)) { | |
115 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); | |
116 | return 0; | |
117 | } | |
592ea4ba | 118 | p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS); |
f816aa47 SL |
119 | if (p != NULL) { |
120 | long num; | |
121 | int i; | |
122 | ASN1_TYPE *type; | |
123 | unsigned char *d = p->data; | |
124 | unsigned char **dd = d == NULL ? NULL : &d; | |
125 | ||
126 | if (p->data_type != OSSL_PARAM_OCTET_STRING) { | |
127 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); | |
128 | return 0; | |
129 | } | |
130 | if ((type = ASN1_TYPE_new()) == NULL) { | |
e077455e | 131 | ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); |
f816aa47 SL |
132 | return 0; |
133 | } | |
134 | ||
135 | /* Is this the original IV or the running IV? */ | |
136 | num = rc2_keybits_to_magic(ctx->key_bits); | |
137 | if (!ASN1_TYPE_set_int_octetstring(type, num, | |
138 | ctx->base.iv, ctx->base.ivlen)) { | |
139 | ASN1_TYPE_free(type); | |
e077455e | 140 | ERR_raise(ERR_LIB_PROV, ERR_R_ASN1_LIB); |
f816aa47 SL |
141 | return 0; |
142 | } | |
143 | /* | |
144 | * IF the caller has a buffer, we pray to the gods they got the | |
145 | * size right. There's no way to tell the i2d functions... | |
146 | */ | |
147 | i = i2d_ASN1_TYPE(type, dd); | |
148 | if (i >= 0) | |
149 | p->return_size = (size_t)i; | |
150 | ||
151 | ASN1_TYPE_free(type); | |
152 | if (i < 0) { | |
153 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); | |
154 | return 0; | |
155 | } | |
156 | } | |
157 | return 1; | |
158 | } | |
159 | ||
8f42380a | 160 | static int rc2_set_ctx_params(void *vctx, const OSSL_PARAM params[]) |
f816aa47 SL |
161 | { |
162 | PROV_RC2_CTX *ctx = (PROV_RC2_CTX *)vctx; | |
163 | const OSSL_PARAM *p; | |
164 | ||
8f42380a P |
165 | if (params == NULL) |
166 | return 1; | |
167 | ||
592dcfd3 | 168 | if (!ossl_cipher_var_keylen_set_ctx_params(vctx, params)) |
f816aa47 SL |
169 | return 0; |
170 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_RC2_KEYBITS); | |
171 | if (p != NULL) { | |
172 | if (!OSSL_PARAM_get_size_t(p, &ctx->key_bits)) { | |
173 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); | |
174 | return 0; | |
175 | } | |
176 | } | |
592ea4ba | 177 | p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS); |
f816aa47 SL |
178 | if (p != NULL) { |
179 | ASN1_TYPE *type = NULL; | |
180 | long num = 0; | |
181 | const unsigned char *d = p->data; | |
182 | int ret = 1; | |
183 | unsigned char iv[16]; | |
184 | ||
185 | if (p->data_type != OSSL_PARAM_OCTET_STRING | |
186 | || ctx->base.ivlen > sizeof(iv) | |
187 | || (type = d2i_ASN1_TYPE(NULL, &d, p->data_size)) == NULL | |
188 | || ((size_t)ASN1_TYPE_get_int_octetstring(type, &num, iv, | |
189 | ctx->base.ivlen) | |
190 | != ctx->base.ivlen) | |
592dcfd3 | 191 | || !ossl_cipher_generic_initiv(&ctx->base, iv, ctx->base.ivlen) |
f816aa47 SL |
192 | || (ctx->key_bits = rc2_magic_to_keybits(num)) == 0) { |
193 | ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); | |
194 | ret = 0; | |
195 | } | |
196 | ASN1_TYPE_free(type); | |
197 | if (ret == 0) | |
198 | return 0; | |
199 | /* | |
200 | * This code assumes that the caller will call | |
201 | * EVP_CipherInit_ex() with a non NULL key in order to setup a key that | |
202 | * uses the keylen and keybits that were set here. | |
203 | */ | |
204 | ctx->base.keylen = ctx->key_bits / 8; | |
205 | } | |
206 | return 1; | |
207 | } | |
208 | ||
209 | CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(rc2) | |
210 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_RC2_KEYBITS, NULL), | |
592ea4ba | 211 | OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS, NULL, 0), |
f816aa47 SL |
212 | CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(rc2) |
213 | ||
214 | CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(rc2) | |
d23adad1 | 215 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL), |
f816aa47 | 216 | OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_RC2_KEYBITS, NULL), |
592ea4ba | 217 | OSSL_PARAM_octet_string(OSSL_CIPHER_PARAM_ALGORITHM_ID_PARAMS, NULL, 0), |
f816aa47 SL |
218 | CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(rc2) |
219 | ||
220 | #define IMPLEMENT_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, blkbits, \ | |
221 | ivbits, typ) \ | |
363b1e5d | 222 | static OSSL_FUNC_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params; \ |
f816aa47 SL |
223 | static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[]) \ |
224 | { \ | |
592dcfd3 P |
225 | return ossl_cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, \ |
226 | flags, kbits, blkbits, ivbits); \ | |
f816aa47 | 227 | } \ |
363b1e5d | 228 | static OSSL_FUNC_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx; \ |
f816aa47 SL |
229 | static void * alg##_##kbits##_##lcmode##_newctx(void *provctx) \ |
230 | { \ | |
f99d3eed | 231 | PROV_##UCALG##_CTX *ctx; \ |
592dcfd3 | 232 | if (!ossl_prov_is_running()) \ |
f99d3eed P |
233 | return NULL; \ |
234 | ctx = OPENSSL_zalloc(sizeof(*ctx)); \ | |
f816aa47 | 235 | if (ctx != NULL) { \ |
592dcfd3 | 236 | ossl_cipher_generic_initkey(ctx, kbits, blkbits, ivbits, \ |
f816aa47 | 237 | EVP_CIPH_##UCMODE##_MODE, flags, \ |
7d6766cb P |
238 | ossl_prov_cipher_hw_##alg##_##lcmode(kbits), \ |
239 | NULL); \ | |
f816aa47 SL |
240 | ctx->key_bits = kbits; \ |
241 | } \ | |
242 | return ctx; \ | |
243 | } \ | |
1be63951 | 244 | const OSSL_DISPATCH ossl_##alg##kbits##lcmode##_functions[] = { \ |
f816aa47 SL |
245 | { OSSL_FUNC_CIPHER_NEWCTX, \ |
246 | (void (*)(void)) alg##_##kbits##_##lcmode##_newctx }, \ | |
247 | { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx }, \ | |
248 | { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx }, \ | |
8f42380a P |
249 | { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))rc2_einit }, \ |
250 | { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))rc2_dinit }, \ | |
592dcfd3 P |
251 | { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))ossl_cipher_generic_##typ##_update },\ |
252 | { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))ossl_cipher_generic_##typ##_final }, \ | |
253 | { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))ossl_cipher_generic_cipher }, \ | |
f816aa47 SL |
254 | { OSSL_FUNC_CIPHER_GET_PARAMS, \ |
255 | (void (*)(void)) alg##_##kbits##_##lcmode##_get_params }, \ | |
256 | { OSSL_FUNC_CIPHER_GETTABLE_PARAMS, \ | |
592dcfd3 | 257 | (void (*)(void))ossl_cipher_generic_gettable_params }, \ |
f816aa47 SL |
258 | { OSSL_FUNC_CIPHER_GET_CTX_PARAMS, \ |
259 | (void (*)(void))rc2_get_ctx_params }, \ | |
260 | { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS, \ | |
261 | (void (*)(void))rc2_gettable_ctx_params }, \ | |
262 | { OSSL_FUNC_CIPHER_SET_CTX_PARAMS, \ | |
263 | (void (*)(void))rc2_set_ctx_params }, \ | |
264 | { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS, \ | |
265 | (void (*)(void))rc2_settable_ctx_params }, \ | |
266 | { 0, NULL } \ | |
267 | }; | |
268 | ||
1be63951 | 269 | /* ossl_rc2128ecb_functions */ |
a054d15c | 270 | IMPLEMENT_cipher(rc2, RC2, ecb, ECB, RC2_FLAGS, 128, 64, 0, block) |
1be63951 | 271 | /* ossl_rc2128cbc_functions */ |
a054d15c | 272 | IMPLEMENT_cipher(rc2, RC2, cbc, CBC, RC2_FLAGS, 128, 64, 64, block) |
1be63951 | 273 | /* ossl_rc240cbc_functions */ |
a054d15c | 274 | IMPLEMENT_cipher(rc2, RC2, cbc, CBC, RC2_FLAGS, 40, 64, 64, block) |
1be63951 | 275 | /* ossl_rc264cbc_functions */ |
a054d15c | 276 | IMPLEMENT_cipher(rc2, RC2, cbc, CBC, RC2_FLAGS, 64, 64, 64, block) |
f816aa47 | 277 | |
1be63951 | 278 | /* ossl_rc2128ofb128_functions */ |
a054d15c | 279 | IMPLEMENT_cipher(rc2, RC2, ofb128, OFB, RC2_FLAGS, 128, 8, 64, stream) |
1be63951 | 280 | /* ossl_rc2128cfb128_functions */ |
a054d15c | 281 | IMPLEMENT_cipher(rc2, RC2, cfb128, CFB, RC2_FLAGS, 128, 8, 64, stream) |