xref: /freebsd/crypto/openssl/crypto/evp/e_rc2.c (revision b077aed33b7b6aefca7b17ddb250cf521f938613)
1e71b7053SJung-uk Kim /*
2*b077aed3SPierre Pronchery  * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
3ddd58736SKris Kennaway  *
4*b077aed3SPierre Pronchery  * Licensed under the Apache License 2.0 (the "License").  You may not use
5e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
6e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
8ddd58736SKris Kennaway  */
9ddd58736SKris Kennaway 
10*b077aed3SPierre Pronchery /*
11*b077aed3SPierre Pronchery  * RC2 low level APIs are deprecated for public use, but still ok for internal
12*b077aed3SPierre Pronchery  * use.
13*b077aed3SPierre Pronchery  */
14*b077aed3SPierre Pronchery #include "internal/deprecated.h"
15*b077aed3SPierre Pronchery 
16ddd58736SKris Kennaway #include <stdio.h>
17e71b7053SJung-uk Kim #include "internal/cryptlib.h"
183b4e3dcbSSimon L. B. Nielsen 
193b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_RC2
203b4e3dcbSSimon L. B. Nielsen 
21ddd58736SKris Kennaway # include <openssl/evp.h>
22ddd58736SKris Kennaway # include <openssl/objects.h>
2317f01e99SJung-uk Kim # include "crypto/evp.h"
245c87c606SMark Murray # include <openssl/rc2.h>
25*b077aed3SPierre Pronchery # include "evp_local.h"
26ddd58736SKris Kennaway 
27ddd58736SKris Kennaway static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
28ddd58736SKris Kennaway                         const unsigned char *iv, int enc);
29ddd58736SKris Kennaway static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx);
30ddd58736SKris Kennaway static int rc2_magic_to_meth(int i);
31ddd58736SKris Kennaway static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
32ddd58736SKris Kennaway static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
33ddd58736SKris Kennaway static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
34ddd58736SKris Kennaway 
356f9291ceSJung-uk Kim typedef struct {
365c87c606SMark Murray     int key_bits;               /* effective key bits */
375c87c606SMark Murray     RC2_KEY ks;                 /* key schedule */
385c87c606SMark Murray } EVP_RC2_KEY;
395c87c606SMark Murray 
40e71b7053SJung-uk Kim # define data(ctx)       EVP_C_DATA(EVP_RC2_KEY,ctx)
415c87c606SMark Murray 
425c87c606SMark Murray IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2,
43ddd58736SKris Kennaway                        8,
445c87c606SMark Murray                        RC2_KEY_LENGTH, 8, 64,
45ddd58736SKris Kennaway                        EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
46ddd58736SKris Kennaway                        rc2_init_key, NULL,
47ddd58736SKris Kennaway                        rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv,
48ddd58736SKris Kennaway                        rc2_ctrl)
49ddd58736SKris Kennaway # define RC2_40_MAGIC    0xa0
50ddd58736SKris Kennaway # define RC2_64_MAGIC    0x78
51ddd58736SKris Kennaway # define RC2_128_MAGIC   0x3a
526f9291ceSJung-uk Kim static const EVP_CIPHER r2_64_cbc_cipher = {
53ddd58736SKris Kennaway     NID_rc2_64_cbc,
54ddd58736SKris Kennaway     8, 8 /* 64 bit */ , 8,
55ddd58736SKris Kennaway     EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
56*b077aed3SPierre Pronchery     EVP_ORIG_GLOBAL,
57ddd58736SKris Kennaway     rc2_init_key,
58ddd58736SKris Kennaway     rc2_cbc_cipher,
59ddd58736SKris Kennaway     NULL,
605c87c606SMark Murray     sizeof(EVP_RC2_KEY),
61ddd58736SKris Kennaway     rc2_set_asn1_type_and_iv,
62ddd58736SKris Kennaway     rc2_get_asn1_type_and_iv,
63ddd58736SKris Kennaway     rc2_ctrl,
64ddd58736SKris Kennaway     NULL
65ddd58736SKris Kennaway };
66ddd58736SKris Kennaway 
676f9291ceSJung-uk Kim static const EVP_CIPHER r2_40_cbc_cipher = {
68ddd58736SKris Kennaway     NID_rc2_40_cbc,
69ddd58736SKris Kennaway     8, 5 /* 40 bit */ , 8,
70ddd58736SKris Kennaway     EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
71*b077aed3SPierre Pronchery     EVP_ORIG_GLOBAL,
72ddd58736SKris Kennaway     rc2_init_key,
73ddd58736SKris Kennaway     rc2_cbc_cipher,
74ddd58736SKris Kennaway     NULL,
755c87c606SMark Murray     sizeof(EVP_RC2_KEY),
76ddd58736SKris Kennaway     rc2_set_asn1_type_and_iv,
77ddd58736SKris Kennaway     rc2_get_asn1_type_and_iv,
78ddd58736SKris Kennaway     rc2_ctrl,
79ddd58736SKris Kennaway     NULL
80ddd58736SKris Kennaway };
81ddd58736SKris Kennaway 
EVP_rc2_64_cbc(void)825c87c606SMark Murray const EVP_CIPHER *EVP_rc2_64_cbc(void)
83ddd58736SKris Kennaway {
84e71b7053SJung-uk Kim     return &r2_64_cbc_cipher;
85ddd58736SKris Kennaway }
86ddd58736SKris Kennaway 
EVP_rc2_40_cbc(void)875c87c606SMark Murray const EVP_CIPHER *EVP_rc2_40_cbc(void)
88ddd58736SKris Kennaway {
89e71b7053SJung-uk Kim     return &r2_40_cbc_cipher;
90ddd58736SKris Kennaway }
91ddd58736SKris Kennaway 
rc2_init_key(EVP_CIPHER_CTX * ctx,const unsigned char * key,const unsigned char * iv,int enc)92ddd58736SKris Kennaway static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
93ddd58736SKris Kennaway                         const unsigned char *iv, int enc)
94ddd58736SKris Kennaway {
95*b077aed3SPierre Pronchery     RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_get_key_length(ctx),
965c87c606SMark Murray                 key, data(ctx)->key_bits);
97ddd58736SKris Kennaway     return 1;
98ddd58736SKris Kennaway }
99ddd58736SKris Kennaway 
rc2_meth_to_magic(EVP_CIPHER_CTX * e)100ddd58736SKris Kennaway static int rc2_meth_to_magic(EVP_CIPHER_CTX *e)
101ddd58736SKris Kennaway {
102ddd58736SKris Kennaway     int i;
103ddd58736SKris Kennaway 
104c9cf7b5cSJung-uk Kim     if (EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i) <= 0)
105c9cf7b5cSJung-uk Kim         return 0;
1066f9291ceSJung-uk Kim     if (i == 128)
107e71b7053SJung-uk Kim         return RC2_128_MAGIC;
1086f9291ceSJung-uk Kim     else if (i == 64)
109e71b7053SJung-uk Kim         return RC2_64_MAGIC;
1106f9291ceSJung-uk Kim     else if (i == 40)
111e71b7053SJung-uk Kim         return RC2_40_MAGIC;
1126f9291ceSJung-uk Kim     else
113e71b7053SJung-uk Kim         return 0;
114ddd58736SKris Kennaway }
115ddd58736SKris Kennaway 
rc2_magic_to_meth(int i)116ddd58736SKris Kennaway static int rc2_magic_to_meth(int i)
117ddd58736SKris Kennaway {
1186f9291ceSJung-uk Kim     if (i == RC2_128_MAGIC)
1196f9291ceSJung-uk Kim         return 128;
1206f9291ceSJung-uk Kim     else if (i == RC2_64_MAGIC)
1216f9291ceSJung-uk Kim         return 64;
1226f9291ceSJung-uk Kim     else if (i == RC2_40_MAGIC)
1236f9291ceSJung-uk Kim         return 40;
1246f9291ceSJung-uk Kim     else {
125*b077aed3SPierre Pronchery         ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_SIZE);
126e71b7053SJung-uk Kim         return 0;
127ddd58736SKris Kennaway     }
128ddd58736SKris Kennaway }
129ddd58736SKris Kennaway 
rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX * c,ASN1_TYPE * type)130ddd58736SKris Kennaway static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
131ddd58736SKris Kennaway {
132ddd58736SKris Kennaway     long num = 0;
1333b4e3dcbSSimon L. B. Nielsen     int i = 0;
134ddd58736SKris Kennaway     int key_bits;
1353b4e3dcbSSimon L. B. Nielsen     unsigned int l;
136ddd58736SKris Kennaway     unsigned char iv[EVP_MAX_IV_LENGTH];
137ddd58736SKris Kennaway 
1386f9291ceSJung-uk Kim     if (type != NULL) {
139*b077aed3SPierre Pronchery         l = EVP_CIPHER_CTX_get_iv_length(c);
1403b4e3dcbSSimon L. B. Nielsen         OPENSSL_assert(l <= sizeof(iv));
141ddd58736SKris Kennaway         i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l);
1423b4e3dcbSSimon L. B. Nielsen         if (i != (int)l)
143e71b7053SJung-uk Kim             return -1;
144ddd58736SKris Kennaway         key_bits = rc2_magic_to_meth((int)num);
145ddd58736SKris Kennaway         if (!key_bits)
146e71b7053SJung-uk Kim             return -1;
1471f13597dSJung-uk Kim         if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1))
1481f13597dSJung-uk Kim             return -1;
149c9cf7b5cSJung-uk Kim         if (EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits,
150c9cf7b5cSJung-uk Kim                                 NULL) <= 0
151c9cf7b5cSJung-uk Kim                 || EVP_CIPHER_CTX_set_key_length(c, key_bits / 8) <= 0)
152e71b7053SJung-uk Kim             return -1;
153ddd58736SKris Kennaway     }
154e71b7053SJung-uk Kim     return i;
155ddd58736SKris Kennaway }
156ddd58736SKris Kennaway 
rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX * c,ASN1_TYPE * type)157ddd58736SKris Kennaway static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
158ddd58736SKris Kennaway {
159ddd58736SKris Kennaway     long num;
160ddd58736SKris Kennaway     int i = 0, j;
161ddd58736SKris Kennaway 
1626f9291ceSJung-uk Kim     if (type != NULL) {
163ddd58736SKris Kennaway         num = rc2_meth_to_magic(c);
164*b077aed3SPierre Pronchery         j = EVP_CIPHER_CTX_get_iv_length(c);
165*b077aed3SPierre Pronchery         i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j);
166ddd58736SKris Kennaway     }
167e71b7053SJung-uk Kim     return i;
168ddd58736SKris Kennaway }
169ddd58736SKris Kennaway 
rc2_ctrl(EVP_CIPHER_CTX * c,int type,int arg,void * ptr)170ddd58736SKris Kennaway static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
171ddd58736SKris Kennaway {
1726f9291ceSJung-uk Kim     switch (type) {
173ddd58736SKris Kennaway     case EVP_CTRL_INIT:
174*b077aed3SPierre Pronchery         data(c)->key_bits = EVP_CIPHER_CTX_get_key_length(c) * 8;
175ddd58736SKris Kennaway         return 1;
176ddd58736SKris Kennaway 
177ddd58736SKris Kennaway     case EVP_CTRL_GET_RC2_KEY_BITS:
1785c87c606SMark Murray         *(int *)ptr = data(c)->key_bits;
179ddd58736SKris Kennaway         return 1;
180ddd58736SKris Kennaway 
181ddd58736SKris Kennaway     case EVP_CTRL_SET_RC2_KEY_BITS:
1826f9291ceSJung-uk Kim         if (arg > 0) {
1835c87c606SMark Murray             data(c)->key_bits = arg;
184ddd58736SKris Kennaway             return 1;
185ddd58736SKris Kennaway         }
186ddd58736SKris Kennaway         return 0;
1871f13597dSJung-uk Kim # ifdef PBE_PRF_TEST
1881f13597dSJung-uk Kim     case EVP_CTRL_PBE_PRF_NID:
1891f13597dSJung-uk Kim         *(int *)ptr = NID_hmacWithMD5;
1901f13597dSJung-uk Kim         return 1;
1911f13597dSJung-uk Kim # endif
192ddd58736SKris Kennaway 
193ddd58736SKris Kennaway     default:
194ddd58736SKris Kennaway         return -1;
195ddd58736SKris Kennaway     }
196ddd58736SKris Kennaway }
197ddd58736SKris Kennaway 
198ddd58736SKris Kennaway #endif
199