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