1*9bac3682Sbeck /* $OpenBSD: e_rc2.c,v 1.29 2024/04/09 13:52:41 beck Exp $ */
2c109e398Sbeck /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3c109e398Sbeck * All rights reserved.
4c109e398Sbeck *
5c109e398Sbeck * This package is an SSL implementation written
6c109e398Sbeck * by Eric Young (eay@cryptsoft.com).
7c109e398Sbeck * The implementation was written so as to conform with Netscapes SSL.
8c109e398Sbeck *
9c109e398Sbeck * This library is free for commercial and non-commercial use as long as
10c109e398Sbeck * the following conditions are aheared to. The following conditions
11c109e398Sbeck * apply to all code found in this distribution, be it the RC4, RSA,
12c109e398Sbeck * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13c109e398Sbeck * included with this distribution is covered by the same copyright terms
14c109e398Sbeck * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15c109e398Sbeck *
16c109e398Sbeck * Copyright remains Eric Young's, and as such any Copyright notices in
17c109e398Sbeck * the code are not to be removed.
18c109e398Sbeck * If this package is used in a product, Eric Young should be given attribution
19c109e398Sbeck * as the author of the parts of the library used.
20c109e398Sbeck * This can be in the form of a textual message at program startup or
21c109e398Sbeck * in documentation (online or textual) provided with the package.
22c109e398Sbeck *
23c109e398Sbeck * Redistribution and use in source and binary forms, with or without
24c109e398Sbeck * modification, are permitted provided that the following conditions
25c109e398Sbeck * are met:
26c109e398Sbeck * 1. Redistributions of source code must retain the copyright
27c109e398Sbeck * notice, this list of conditions and the following disclaimer.
28c109e398Sbeck * 2. Redistributions in binary form must reproduce the above copyright
29c109e398Sbeck * notice, this list of conditions and the following disclaimer in the
30c109e398Sbeck * documentation and/or other materials provided with the distribution.
31c109e398Sbeck * 3. All advertising materials mentioning features or use of this software
32c109e398Sbeck * must display the following acknowledgement:
33c109e398Sbeck * "This product includes cryptographic software written by
34c109e398Sbeck * Eric Young (eay@cryptsoft.com)"
35c109e398Sbeck * The word 'cryptographic' can be left out if the rouines from the library
36c109e398Sbeck * being used are not cryptographic related :-).
37c109e398Sbeck * 4. If you include any Windows specific code (or a derivative thereof) from
38c109e398Sbeck * the apps directory (application code) you must include an acknowledgement:
39c109e398Sbeck * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40c109e398Sbeck *
41c109e398Sbeck * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42c109e398Sbeck * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43c109e398Sbeck * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44c109e398Sbeck * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45c109e398Sbeck * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46c109e398Sbeck * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47c109e398Sbeck * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48c109e398Sbeck * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49c109e398Sbeck * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50c109e398Sbeck * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51c109e398Sbeck * SUCH DAMAGE.
52c109e398Sbeck *
53c109e398Sbeck * The licence and distribution terms for any publically available version or
54c109e398Sbeck * derivative of this code cannot be changed. i.e. this code cannot simply be
55c109e398Sbeck * copied and put under another distribution licence
56c109e398Sbeck * [including the GNU Public Licence.]
57c109e398Sbeck */
58c109e398Sbeck
59b76ab7f9Sjsing #include <limits.h>
60c109e398Sbeck #include <stdio.h>
618cf4d6a6Sjsing
628cf4d6a6Sjsing #include <openssl/opensslconf.h>
638cf4d6a6Sjsing
644fcf65c5Sdjm #ifndef OPENSSL_NO_RC2
654fcf65c5Sdjm
66b6ab114eSjsing #include <openssl/err.h>
67c109e398Sbeck #include <openssl/evp.h>
68c109e398Sbeck #include <openssl/objects.h>
69da347917Sbeck #include <openssl/rc2.h>
70c109e398Sbeck
71c9675a23Stb #include "evp_local.h"
72b6ab114eSjsing
73c109e398Sbeck static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
74c109e398Sbeck const unsigned char *iv, int enc);
75c109e398Sbeck static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx);
76c109e398Sbeck static int rc2_magic_to_meth(int i);
77c109e398Sbeck static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
78c109e398Sbeck static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
79c109e398Sbeck static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
80c109e398Sbeck
81ba3920edSjsing typedef struct {
82da347917Sbeck int key_bits; /* effective key bits */
83da347917Sbeck RC2_KEY ks; /* key schedule */
84da347917Sbeck } EVP_RC2_KEY;
85da347917Sbeck
86da347917Sbeck #define data(ctx) ((EVP_RC2_KEY *)(ctx)->cipher_data)
87da347917Sbeck
888892d6c1Sjsing static int
rc2_cbc_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)898892d6c1Sjsing rc2_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
908892d6c1Sjsing {
91fa590012Sjsing size_t chunk = LONG_MAX & ~0xff;
92b76ab7f9Sjsing
93fa590012Sjsing while (inl >= chunk) {
94fa590012Sjsing RC2_cbc_encrypt(in, out, (long)chunk, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
95fa590012Sjsing inl -= chunk;
96fa590012Sjsing in += chunk;
97fa590012Sjsing out += chunk;
988892d6c1Sjsing }
998892d6c1Sjsing
1008892d6c1Sjsing if (inl)
1018892d6c1Sjsing RC2_cbc_encrypt(in, out, (long)inl, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, ctx->encrypt);
1028892d6c1Sjsing
1038892d6c1Sjsing return 1;
1048892d6c1Sjsing }
1058892d6c1Sjsing
1068892d6c1Sjsing static int
rc2_cfb64_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)1078892d6c1Sjsing rc2_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
1088892d6c1Sjsing {
109fa590012Sjsing size_t chunk = LONG_MAX & ~0xff;
110b76ab7f9Sjsing
1118892d6c1Sjsing if (inl < chunk)
1128892d6c1Sjsing chunk = inl;
1138892d6c1Sjsing
1148892d6c1Sjsing while (inl && inl >= chunk) {
1157a606269Sjsing RC2_cfb64_encrypt(in, out, (long)chunk, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num, ctx->encrypt);
1168892d6c1Sjsing inl -= chunk;
1178892d6c1Sjsing in += chunk;
1188892d6c1Sjsing out += chunk;
1198892d6c1Sjsing if (inl < chunk)
1208892d6c1Sjsing chunk = inl;
1218892d6c1Sjsing }
1228892d6c1Sjsing
1238892d6c1Sjsing return 1;
1248892d6c1Sjsing }
1258892d6c1Sjsing
1268892d6c1Sjsing static int
rc2_ecb_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)1278892d6c1Sjsing rc2_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
1288892d6c1Sjsing {
1298892d6c1Sjsing size_t i, bl;
1308892d6c1Sjsing
1318892d6c1Sjsing bl = ctx->cipher->block_size;
1328892d6c1Sjsing
1338892d6c1Sjsing if (inl < bl)
1348892d6c1Sjsing return 1;
1358892d6c1Sjsing
1368892d6c1Sjsing inl -= bl;
1378892d6c1Sjsing
1388892d6c1Sjsing for (i = 0; i <= inl; i += bl)
1398892d6c1Sjsing RC2_ecb_encrypt(in + i, out + i, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->encrypt);
1408892d6c1Sjsing
1418892d6c1Sjsing return 1;
1428892d6c1Sjsing }
1438892d6c1Sjsing
1448892d6c1Sjsing static int
rc2_ofb_cipher(EVP_CIPHER_CTX * ctx,unsigned char * out,const unsigned char * in,size_t inl)1458892d6c1Sjsing rc2_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl)
1468892d6c1Sjsing {
147fa590012Sjsing size_t chunk = LONG_MAX & ~0xff;
148b76ab7f9Sjsing
149fa590012Sjsing while (inl >= chunk) {
150fa590012Sjsing RC2_ofb64_encrypt(in, out, (long)chunk, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
151fa590012Sjsing inl -= chunk;
152fa590012Sjsing in += chunk;
153fa590012Sjsing out += chunk;
1548892d6c1Sjsing }
1558892d6c1Sjsing
1568892d6c1Sjsing if (inl)
1578892d6c1Sjsing RC2_ofb64_encrypt(in, out, (long)inl, &((EVP_RC2_KEY *)ctx->cipher_data)->ks, ctx->iv, &ctx->num);
1588892d6c1Sjsing
1598892d6c1Sjsing return 1;
1608892d6c1Sjsing }
1618892d6c1Sjsing
1628892d6c1Sjsing static const EVP_CIPHER rc2_cbc = {
1638892d6c1Sjsing .nid = NID_rc2_cbc,
1648892d6c1Sjsing .block_size = 8,
1658892d6c1Sjsing .key_len = RC2_KEY_LENGTH,
1668892d6c1Sjsing .iv_len = 8,
1678892d6c1Sjsing .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT | EVP_CIPH_CBC_MODE,
1688892d6c1Sjsing .init = rc2_init_key,
1698892d6c1Sjsing .do_cipher = rc2_cbc_cipher,
1708892d6c1Sjsing .cleanup = NULL,
1718892d6c1Sjsing .ctx_size = sizeof(EVP_RC2_KEY),
1728892d6c1Sjsing .set_asn1_parameters = rc2_set_asn1_type_and_iv,
1738892d6c1Sjsing .get_asn1_parameters = rc2_get_asn1_type_and_iv,
1748892d6c1Sjsing .ctrl = rc2_ctrl,
1758892d6c1Sjsing };
1768892d6c1Sjsing
1778892d6c1Sjsing const EVP_CIPHER *
EVP_rc2_cbc(void)1788892d6c1Sjsing EVP_rc2_cbc(void)
1798892d6c1Sjsing {
1808892d6c1Sjsing return &rc2_cbc;
1818892d6c1Sjsing }
182*9bac3682Sbeck LCRYPTO_ALIAS(EVP_rc2_cbc);
1838892d6c1Sjsing
1848892d6c1Sjsing static const EVP_CIPHER rc2_cfb64 = {
1858892d6c1Sjsing .nid = NID_rc2_cfb64,
1868892d6c1Sjsing .block_size = 1,
1878892d6c1Sjsing .key_len = RC2_KEY_LENGTH,
1888892d6c1Sjsing .iv_len = 8,
1898892d6c1Sjsing .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT | EVP_CIPH_CFB_MODE,
1908892d6c1Sjsing .init = rc2_init_key,
1918892d6c1Sjsing .do_cipher = rc2_cfb64_cipher,
1928892d6c1Sjsing .cleanup = NULL,
1938892d6c1Sjsing .ctx_size = sizeof(EVP_RC2_KEY),
1948892d6c1Sjsing .set_asn1_parameters = rc2_set_asn1_type_and_iv,
1958892d6c1Sjsing .get_asn1_parameters = rc2_get_asn1_type_and_iv,
1968892d6c1Sjsing .ctrl = rc2_ctrl,
1978892d6c1Sjsing };
1988892d6c1Sjsing
1998892d6c1Sjsing const EVP_CIPHER *
EVP_rc2_cfb64(void)2008892d6c1Sjsing EVP_rc2_cfb64(void)
2018892d6c1Sjsing {
2028892d6c1Sjsing return &rc2_cfb64;
2038892d6c1Sjsing }
204*9bac3682Sbeck LCRYPTO_ALIAS(EVP_rc2_cfb64);
2058892d6c1Sjsing
2068892d6c1Sjsing static const EVP_CIPHER rc2_ofb = {
2078892d6c1Sjsing .nid = NID_rc2_ofb64,
2088892d6c1Sjsing .block_size = 1,
2098892d6c1Sjsing .key_len = RC2_KEY_LENGTH,
2108892d6c1Sjsing .iv_len = 8,
2118892d6c1Sjsing .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT | EVP_CIPH_OFB_MODE,
2128892d6c1Sjsing .init = rc2_init_key,
2138892d6c1Sjsing .do_cipher = rc2_ofb_cipher,
2148892d6c1Sjsing .cleanup = NULL,
2158892d6c1Sjsing .ctx_size = sizeof(EVP_RC2_KEY),
2168892d6c1Sjsing .set_asn1_parameters = rc2_set_asn1_type_and_iv,
2178892d6c1Sjsing .get_asn1_parameters = rc2_get_asn1_type_and_iv,
2188892d6c1Sjsing .ctrl = rc2_ctrl,
2198892d6c1Sjsing };
2208892d6c1Sjsing
2218892d6c1Sjsing const EVP_CIPHER *
EVP_rc2_ofb(void)2228892d6c1Sjsing EVP_rc2_ofb(void)
2238892d6c1Sjsing {
2248892d6c1Sjsing return &rc2_ofb;
2258892d6c1Sjsing }
226*9bac3682Sbeck LCRYPTO_ALIAS(EVP_rc2_ofb);
2278892d6c1Sjsing
2288892d6c1Sjsing static const EVP_CIPHER rc2_ecb = {
2298892d6c1Sjsing .nid = NID_rc2_ecb,
2308892d6c1Sjsing .block_size = 8,
2318892d6c1Sjsing .key_len = RC2_KEY_LENGTH,
2328892d6c1Sjsing .iv_len = 0,
2338892d6c1Sjsing .flags = EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT | EVP_CIPH_ECB_MODE,
2348892d6c1Sjsing .init = rc2_init_key,
2358892d6c1Sjsing .do_cipher = rc2_ecb_cipher,
2368892d6c1Sjsing .cleanup = NULL,
2378892d6c1Sjsing .ctx_size = sizeof(EVP_RC2_KEY),
2388892d6c1Sjsing .set_asn1_parameters = rc2_set_asn1_type_and_iv,
2398892d6c1Sjsing .get_asn1_parameters = rc2_get_asn1_type_and_iv,
2408892d6c1Sjsing .ctrl = rc2_ctrl,
2418892d6c1Sjsing };
2428892d6c1Sjsing
2438892d6c1Sjsing const EVP_CIPHER *
EVP_rc2_ecb(void)2448892d6c1Sjsing EVP_rc2_ecb(void)
2458892d6c1Sjsing {
2468892d6c1Sjsing return &rc2_ecb;
2478892d6c1Sjsing }
248*9bac3682Sbeck LCRYPTO_ALIAS(EVP_rc2_ecb);
249c109e398Sbeck
250c109e398Sbeck #define RC2_40_MAGIC 0xa0
251c109e398Sbeck #define RC2_64_MAGIC 0x78
252c109e398Sbeck #define RC2_128_MAGIC 0x3a
253c109e398Sbeck
254ba3920edSjsing static const EVP_CIPHER r2_64_cbc_cipher = {
255fd227519Stb .nid = NID_rc2_64_cbc,
256fd227519Stb .block_size = 8,
257fd227519Stb .key_len = 8,
258fd227519Stb .iv_len = 8,
259fd227519Stb .flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
260fd227519Stb .init = rc2_init_key,
261fd227519Stb .do_cipher = rc2_cbc_cipher,
262fd227519Stb .cleanup = NULL,
263fd227519Stb .ctx_size = sizeof(EVP_RC2_KEY),
264fd227519Stb .set_asn1_parameters = rc2_set_asn1_type_and_iv,
265fd227519Stb .get_asn1_parameters = rc2_get_asn1_type_and_iv,
266fd227519Stb .ctrl = rc2_ctrl,
267c109e398Sbeck };
268c109e398Sbeck
269ba3920edSjsing static const EVP_CIPHER r2_40_cbc_cipher = {
270fd227519Stb .nid = NID_rc2_40_cbc,
271fd227519Stb .block_size = 8,
272fd227519Stb .key_len = 5,
273fd227519Stb .iv_len = 8,
274fd227519Stb .flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
275fd227519Stb .init = rc2_init_key,
276fd227519Stb .do_cipher = rc2_cbc_cipher,
277fd227519Stb .cleanup = NULL,
278fd227519Stb .ctx_size = sizeof(EVP_RC2_KEY),
279fd227519Stb .set_asn1_parameters = rc2_set_asn1_type_and_iv,
280fd227519Stb .get_asn1_parameters = rc2_get_asn1_type_and_iv,
281fd227519Stb .ctrl = rc2_ctrl,
282c109e398Sbeck };
283c109e398Sbeck
284ba3920edSjsing const EVP_CIPHER *
EVP_rc2_64_cbc(void)285ba3920edSjsing EVP_rc2_64_cbc(void)
286c109e398Sbeck {
287c109e398Sbeck return (&r2_64_cbc_cipher);
288c109e398Sbeck }
289*9bac3682Sbeck LCRYPTO_ALIAS(EVP_rc2_64_cbc);
290c109e398Sbeck
291ba3920edSjsing const EVP_CIPHER *
EVP_rc2_40_cbc(void)292ba3920edSjsing EVP_rc2_40_cbc(void)
293c109e398Sbeck {
294c109e398Sbeck return (&r2_40_cbc_cipher);
295c109e398Sbeck }
296*9bac3682Sbeck LCRYPTO_ALIAS(EVP_rc2_40_cbc);
297c109e398Sbeck
298ba3920edSjsing static int
rc2_init_key(EVP_CIPHER_CTX * ctx,const unsigned char * key,const unsigned char * iv,int enc)299ba3920edSjsing rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
300c109e398Sbeck const unsigned char *iv, int enc)
301c109e398Sbeck {
302da347917Sbeck RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
303da347917Sbeck key, data(ctx)->key_bits);
304c109e398Sbeck return 1;
305c109e398Sbeck }
306c109e398Sbeck
307ba3920edSjsing static int
rc2_meth_to_magic(EVP_CIPHER_CTX * e)308ba3920edSjsing rc2_meth_to_magic(EVP_CIPHER_CTX *e)
309c109e398Sbeck {
310c109e398Sbeck int i;
311c109e398Sbeck
312ae001e8fSinoguchi if (EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i) <= 0)
313ae001e8fSinoguchi return (0);
314ba3920edSjsing if (i == 128)
315ba3920edSjsing return (RC2_128_MAGIC);
316ba3920edSjsing else if (i == 64)
317ba3920edSjsing return (RC2_64_MAGIC);
318ba3920edSjsing else if (i == 40)
319ba3920edSjsing return (RC2_40_MAGIC);
320ba3920edSjsing else
321ba3920edSjsing return (0);
322c109e398Sbeck }
323c109e398Sbeck
324ba3920edSjsing static int
rc2_magic_to_meth(int i)325ba3920edSjsing rc2_magic_to_meth(int i)
326c109e398Sbeck {
327ba3920edSjsing if (i == RC2_128_MAGIC)
328ba3920edSjsing return 128;
329ba3920edSjsing else if (i == RC2_64_MAGIC)
330ba3920edSjsing return 64;
331ba3920edSjsing else if (i == RC2_40_MAGIC)
332ba3920edSjsing return 40;
333ba3920edSjsing else {
3345067ae9fSbeck EVPerror(EVP_R_UNSUPPORTED_KEY_SIZE);
335c109e398Sbeck return (0);
336c109e398Sbeck }
337c109e398Sbeck }
338c109e398Sbeck
339ba3920edSjsing static int
rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX * c,ASN1_TYPE * type)340ba3920edSjsing rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
341c109e398Sbeck {
342c109e398Sbeck long num = 0;
3434fcf65c5Sdjm int i = 0;
344c109e398Sbeck int key_bits;
34506f72c83Stb int l;
346c109e398Sbeck unsigned char iv[EVP_MAX_IV_LENGTH];
347c109e398Sbeck
348ba3920edSjsing if (type != NULL) {
349c109e398Sbeck l = EVP_CIPHER_CTX_iv_length(c);
3500a5044deStb if (l < 0 || l > sizeof(iv)) {
3515067ae9fSbeck EVPerror(EVP_R_IV_TOO_LARGE);
3528ad85bf2Smiod return -1;
3538ad85bf2Smiod }
354c109e398Sbeck i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l);
35506f72c83Stb if (i != l)
356c109e398Sbeck return (-1);
357c109e398Sbeck key_bits = rc2_magic_to_meth((int)num);
358c109e398Sbeck if (!key_bits)
359c109e398Sbeck return (-1);
3605cdd308eSdjm if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1))
3615cdd308eSdjm return -1;
362ae001e8fSinoguchi if (EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS,
363ae001e8fSinoguchi key_bits, NULL) <= 0)
364ae001e8fSinoguchi return -1;
3655cf727f3Sinoguchi if (!EVP_CIPHER_CTX_set_key_length(c, key_bits / 8))
3665cf727f3Sinoguchi return -1;
367c109e398Sbeck }
368c109e398Sbeck return (i);
369c109e398Sbeck }
370c109e398Sbeck
371ba3920edSjsing static int
rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX * c,ASN1_TYPE * type)372ba3920edSjsing rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
373c109e398Sbeck {
374c109e398Sbeck long num;
375c109e398Sbeck int i = 0, j;
376c109e398Sbeck
377ba3920edSjsing if (type != NULL) {
378c109e398Sbeck num = rc2_meth_to_magic(c);
379c109e398Sbeck j = EVP_CIPHER_CTX_iv_length(c);
3800a5044deStb if (j < 0 || j > sizeof(c->oiv))
3810a5044deStb return 0;
382c109e398Sbeck i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j);
383c109e398Sbeck }
384c109e398Sbeck return (i);
385c109e398Sbeck }
386c109e398Sbeck
387ba3920edSjsing static int
rc2_ctrl(EVP_CIPHER_CTX * c,int type,int arg,void * ptr)388ba3920edSjsing rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
389c109e398Sbeck {
390ba3920edSjsing switch (type) {
391c109e398Sbeck case EVP_CTRL_INIT:
392b62d6ce7Stb data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8;
393c109e398Sbeck return 1;
394c109e398Sbeck
395c109e398Sbeck case EVP_CTRL_GET_RC2_KEY_BITS:
396da347917Sbeck *(int *)ptr = data(c)->key_bits;
397c109e398Sbeck return 1;
398c109e398Sbeck
399c109e398Sbeck case EVP_CTRL_SET_RC2_KEY_BITS:
400ba3920edSjsing if (arg > 0) {
401da347917Sbeck data(c)->key_bits = arg;
402c109e398Sbeck return 1;
403c109e398Sbeck }
404c109e398Sbeck return 0;
405ba3920edSjsing
406c109e398Sbeck default:
407c109e398Sbeck return -1;
408c109e398Sbeck }
409c109e398Sbeck }
410c109e398Sbeck
411c109e398Sbeck #endif
412