Update copyright year
[openssl.git] / providers / implementations / ciphers / cipher_rc2.c
1 /*
2  * Copyright 2019-2020 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 RC2 cipher modes ecb, cbc, ofb, cfb */
11
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
18 #include "cipher_rc2.h"
19 #include "prov/implementations.h"
20 #include "prov/providercommonerr.h"
21
22 #define RC2_40_MAGIC    0xa0
23 #define RC2_64_MAGIC    0x78
24 #define RC2_128_MAGIC   0x3a
25
26 static OSSL_OP_cipher_freectx_fn rc2_freectx;
27 static OSSL_OP_cipher_dupctx_fn rc2_dupctx;
28 static OSSL_OP_cipher_gettable_ctx_params_fn rc2_gettable_ctx_params;
29 static OSSL_OP_cipher_settable_ctx_params_fn rc2_settable_ctx_params;
30
31 static void rc2_freectx(void *vctx)
32 {
33     PROV_RC2_CTX *ctx = (PROV_RC2_CTX *)vctx;
34
35     OPENSSL_clear_free(ctx,  sizeof(*ctx));
36 }
37
38 static void *rc2_dupctx(void *ctx)
39 {
40     PROV_RC2_CTX *in = (PROV_RC2_CTX *)ctx;
41     PROV_RC2_CTX *ret = OPENSSL_malloc(sizeof(*ret));
42
43     if (ret == NULL) {
44         ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
45         return NULL;
46     }
47     *ret = *in;
48
49     return ret;
50 }
51
52 static int rc2_keybits_to_magic(int keybits)
53 {
54     switch (keybits) {
55     case 128:
56         return RC2_128_MAGIC;
57     case 64:
58         return RC2_64_MAGIC;
59     case 40:
60         return RC2_40_MAGIC;
61     }
62     ERR_raise(ERR_LIB_PROV, PROV_R_UNSUPPORTED_KEY_SIZE);
63     return 0;
64 }
65
66 static int rc2_magic_to_keybits(int magic)
67 {
68     switch (magic) {
69     case RC2_128_MAGIC:
70         return 128;
71     case RC2_64_MAGIC:
72         return 64;
73     case RC2_40_MAGIC:
74         return 40;
75     }
76     ERR_raise(ERR_LIB_PROV, PROV_R_UNSUPPORTED_KEY_SIZE);
77     return 0;
78 }
79
80 static int rc2_get_ctx_params(void *vctx, OSSL_PARAM params[])
81 {
82     PROV_RC2_CTX *ctx = (PROV_RC2_CTX *)vctx;
83     OSSL_PARAM *p;
84
85     if (!cipher_generic_get_ctx_params(vctx, params))
86         return 0;
87     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_RC2_KEYBITS);
88     if (p != NULL && !OSSL_PARAM_set_size_t(p, ctx->key_bits)) {
89         ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
90         return 0;
91     }
92     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_ALG_ID);
93     if (p != NULL) {
94         long num;
95         int i;
96         ASN1_TYPE *type;
97         unsigned char *d = p->data;
98         unsigned char **dd = d == NULL ? NULL : &d;
99
100         if (p->data_type != OSSL_PARAM_OCTET_STRING) {
101             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
102             return 0;
103         }
104         if ((type = ASN1_TYPE_new()) == NULL) {
105             ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
106             return 0;
107         }
108
109         /* Is this the original IV or the running IV? */
110         num = rc2_keybits_to_magic(ctx->key_bits);
111         if (!ASN1_TYPE_set_int_octetstring(type, num,
112                                            ctx->base.iv, ctx->base.ivlen)) {
113             ASN1_TYPE_free(type);
114             ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
115             return 0;
116         }
117         /*
118          * IF the caller has a buffer, we pray to the gods they got the
119          * size right.  There's no way to tell the i2d functions...
120          */
121         i = i2d_ASN1_TYPE(type, dd);
122         if (i >= 0)
123             p->return_size = (size_t)i;
124
125         ASN1_TYPE_free(type);
126         if (i < 0) {
127             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
128             return 0;
129         }
130     }
131     return 1;
132 }
133
134 static int rc2_set_ctx_params(void *vctx, OSSL_PARAM params[])
135 {
136     PROV_RC2_CTX *ctx = (PROV_RC2_CTX *)vctx;
137     const OSSL_PARAM *p;
138
139     if (!cipher_var_keylen_set_ctx_params(vctx, params))
140         return 0;
141     p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_RC2_KEYBITS);
142     if (p != NULL) {
143          if (!OSSL_PARAM_get_size_t(p, &ctx->key_bits)) {
144             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER);
145             return 0;
146         }
147     }
148     p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_ALG_ID);
149     if (p != NULL) {
150         ASN1_TYPE *type = NULL;
151         long num = 0;
152         const unsigned char *d = p->data;
153         int ret = 1;
154         unsigned char iv[16];
155
156         if (p->data_type != OSSL_PARAM_OCTET_STRING
157             || ctx->base.ivlen > sizeof(iv)
158             || (type = d2i_ASN1_TYPE(NULL, &d, p->data_size)) == NULL
159             || ((size_t)ASN1_TYPE_get_int_octetstring(type, &num, iv,
160                                                       ctx->base.ivlen)
161                 != ctx->base.ivlen)
162             || !cipher_generic_initiv(&ctx->base, iv, ctx->base.ivlen)
163             || (ctx->key_bits = rc2_magic_to_keybits(num)) == 0) {
164             ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER);
165             ret = 0;
166         }
167         ASN1_TYPE_free(type);
168         if (ret == 0)
169             return 0;
170         /*
171          * This code assumes that the caller will call
172          * EVP_CipherInit_ex() with a non NULL key in order to setup a key that
173          * uses the keylen and keybits that were set here.
174          */
175         ctx->base.keylen = ctx->key_bits / 8;
176     }
177     return 1;
178 }
179
180 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_START(rc2)
181 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_RC2_KEYBITS, NULL),
182 CIPHER_DEFAULT_GETTABLE_CTX_PARAMS_END(rc2)
183
184 CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_START(rc2)
185 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_KEYLEN, NULL),
186 OSSL_PARAM_size_t(OSSL_CIPHER_PARAM_RC2_KEYBITS, NULL),
187 CIPHER_DEFAULT_SETTABLE_CTX_PARAMS_END(rc2)
188
189 #define IMPLEMENT_cipher(alg, UCALG, lcmode, UCMODE, flags, kbits, blkbits,    \
190                          ivbits, typ)                                          \
191 static OSSL_OP_cipher_get_params_fn alg##_##kbits##_##lcmode##_get_params;     \
192 static int alg##_##kbits##_##lcmode##_get_params(OSSL_PARAM params[])          \
193 {                                                                              \
194     return cipher_generic_get_params(params, EVP_CIPH_##UCMODE##_MODE, flags,  \
195                                      kbits, blkbits, ivbits);                  \
196 }                                                                              \
197 static OSSL_OP_cipher_newctx_fn alg##_##kbits##_##lcmode##_newctx;             \
198 static void * alg##_##kbits##_##lcmode##_newctx(void *provctx)                 \
199 {                                                                              \
200      PROV_##UCALG##_CTX *ctx = OPENSSL_zalloc(sizeof(*ctx));                   \
201      if (ctx != NULL) {                                                        \
202          cipher_generic_initkey(ctx, kbits, blkbits, ivbits,                   \
203                                 EVP_CIPH_##UCMODE##_MODE, flags,               \
204                                 PROV_CIPHER_HW_##alg##_##lcmode(kbits), NULL); \
205          ctx->key_bits = kbits;                                                \
206      }                                                                         \
207      return ctx;                                                               \
208 }                                                                              \
209 const OSSL_DISPATCH alg##kbits##lcmode##_functions[] = {                       \
210     { OSSL_FUNC_CIPHER_NEWCTX,                                                 \
211       (void (*)(void)) alg##_##kbits##_##lcmode##_newctx },                    \
212     { OSSL_FUNC_CIPHER_FREECTX, (void (*)(void)) alg##_freectx },              \
213     { OSSL_FUNC_CIPHER_DUPCTX, (void (*)(void)) alg##_dupctx },                \
214     { OSSL_FUNC_CIPHER_ENCRYPT_INIT, (void (*)(void))cipher_generic_einit },   \
215     { OSSL_FUNC_CIPHER_DECRYPT_INIT, (void (*)(void))cipher_generic_dinit },   \
216     { OSSL_FUNC_CIPHER_UPDATE, (void (*)(void))cipher_generic_##typ##_update },\
217     { OSSL_FUNC_CIPHER_FINAL, (void (*)(void))cipher_generic_##typ##_final },  \
218     { OSSL_FUNC_CIPHER_CIPHER, (void (*)(void))cipher_generic_cipher },        \
219     { OSSL_FUNC_CIPHER_GET_PARAMS,                                             \
220       (void (*)(void)) alg##_##kbits##_##lcmode##_get_params },                \
221     { OSSL_FUNC_CIPHER_GETTABLE_PARAMS,                                        \
222       (void (*)(void))cipher_generic_gettable_params },                        \
223     { OSSL_FUNC_CIPHER_GET_CTX_PARAMS,                                         \
224       (void (*)(void))rc2_get_ctx_params },                                    \
225     { OSSL_FUNC_CIPHER_GETTABLE_CTX_PARAMS,                                    \
226       (void (*)(void))rc2_gettable_ctx_params },                               \
227     { OSSL_FUNC_CIPHER_SET_CTX_PARAMS,                                         \
228       (void (*)(void))rc2_set_ctx_params },                                    \
229     { OSSL_FUNC_CIPHER_SETTABLE_CTX_PARAMS,                                    \
230      (void (*)(void))rc2_settable_ctx_params },                                \
231     { 0, NULL }                                                                \
232 };
233
234 /* rc2128ecb_functions */
235 IMPLEMENT_cipher(rc2, RC2, ecb, ECB, EVP_CIPH_VARIABLE_LENGTH, 128, 64, 0, block)
236 /* rc2128cbc_functions */
237 IMPLEMENT_cipher(rc2, RC2, cbc, CBC, EVP_CIPH_VARIABLE_LENGTH, 128, 64, 64, block)
238 /* rc240cbc_functions */
239 IMPLEMENT_cipher(rc2, RC2, cbc, CBC, EVP_CIPH_VARIABLE_LENGTH, 40, 64, 64, block)
240 /* rc264cbc_functions */
241 IMPLEMENT_cipher(rc2, RC2, cbc, CBC, EVP_CIPH_VARIABLE_LENGTH, 64, 64, 64, block)
242
243 /* rc2128ofb128_functions */
244 IMPLEMENT_cipher(rc2, RC2, ofb128, OFB, EVP_CIPH_VARIABLE_LENGTH, 128, 8, 64, stream)
245 /* rc2128cfb128_functions */
246 IMPLEMENT_cipher(rc2, RC2, cfb128, CFB, EVP_CIPH_VARIABLE_LENGTH, 128, 8, 64, stream)