xref: /freebsd/crypto/openssl/crypto/evp/e_rc2.c (revision e71b70530d95c4f34d8bdbd78d1242df1ba4a945)
1*e71b7053SJung-uk Kim /*
2*e71b7053SJung-uk Kim  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3ddd58736SKris Kennaway  *
4*e71b7053SJung-uk Kim  * Licensed under the OpenSSL license (the "License").  You may not use
5*e71b7053SJung-uk Kim  * this file except in compliance with the License.  You can obtain a copy
6*e71b7053SJung-uk Kim  * in the file LICENSE in the source distribution or at
7*e71b7053SJung-uk Kim  * https://www.openssl.org/source/license.html
8ddd58736SKris Kennaway  */
9ddd58736SKris Kennaway 
10ddd58736SKris Kennaway #include <stdio.h>
11*e71b7053SJung-uk Kim #include "internal/cryptlib.h"
123b4e3dcbSSimon L. B. Nielsen 
133b4e3dcbSSimon L. B. Nielsen #ifndef OPENSSL_NO_RC2
143b4e3dcbSSimon L. B. Nielsen 
15ddd58736SKris Kennaway # include <openssl/evp.h>
16ddd58736SKris Kennaway # include <openssl/objects.h>
17*e71b7053SJung-uk Kim # include "internal/evp_int.h"
185c87c606SMark Murray # include <openssl/rc2.h>
19ddd58736SKris Kennaway 
20ddd58736SKris Kennaway static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
21ddd58736SKris Kennaway                         const unsigned char *iv, int enc);
22ddd58736SKris Kennaway static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx);
23ddd58736SKris Kennaway static int rc2_magic_to_meth(int i);
24ddd58736SKris Kennaway static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
25ddd58736SKris Kennaway static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type);
26ddd58736SKris Kennaway static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr);
27ddd58736SKris Kennaway 
286f9291ceSJung-uk Kim typedef struct {
295c87c606SMark Murray     int key_bits;               /* effective key bits */
305c87c606SMark Murray     RC2_KEY ks;                 /* key schedule */
315c87c606SMark Murray } EVP_RC2_KEY;
325c87c606SMark Murray 
33*e71b7053SJung-uk Kim # define data(ctx)       EVP_C_DATA(EVP_RC2_KEY,ctx)
345c87c606SMark Murray 
355c87c606SMark Murray IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2,
36ddd58736SKris Kennaway                        8,
375c87c606SMark Murray                        RC2_KEY_LENGTH, 8, 64,
38ddd58736SKris Kennaway                        EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
39ddd58736SKris Kennaway                        rc2_init_key, NULL,
40ddd58736SKris Kennaway                        rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv,
41ddd58736SKris Kennaway                        rc2_ctrl)
42ddd58736SKris Kennaway # define RC2_40_MAGIC    0xa0
43ddd58736SKris Kennaway # define RC2_64_MAGIC    0x78
44ddd58736SKris Kennaway # define RC2_128_MAGIC   0x3a
456f9291ceSJung-uk Kim static const EVP_CIPHER r2_64_cbc_cipher = {
46ddd58736SKris Kennaway     NID_rc2_64_cbc,
47ddd58736SKris Kennaway     8, 8 /* 64 bit */ , 8,
48ddd58736SKris Kennaway     EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
49ddd58736SKris Kennaway     rc2_init_key,
50ddd58736SKris Kennaway     rc2_cbc_cipher,
51ddd58736SKris Kennaway     NULL,
525c87c606SMark Murray     sizeof(EVP_RC2_KEY),
53ddd58736SKris Kennaway     rc2_set_asn1_type_and_iv,
54ddd58736SKris Kennaway     rc2_get_asn1_type_and_iv,
55ddd58736SKris Kennaway     rc2_ctrl,
56ddd58736SKris Kennaway     NULL
57ddd58736SKris Kennaway };
58ddd58736SKris Kennaway 
596f9291ceSJung-uk Kim static const EVP_CIPHER r2_40_cbc_cipher = {
60ddd58736SKris Kennaway     NID_rc2_40_cbc,
61ddd58736SKris Kennaway     8, 5 /* 40 bit */ , 8,
62ddd58736SKris Kennaway     EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
63ddd58736SKris Kennaway     rc2_init_key,
64ddd58736SKris Kennaway     rc2_cbc_cipher,
65ddd58736SKris Kennaway     NULL,
665c87c606SMark Murray     sizeof(EVP_RC2_KEY),
67ddd58736SKris Kennaway     rc2_set_asn1_type_and_iv,
68ddd58736SKris Kennaway     rc2_get_asn1_type_and_iv,
69ddd58736SKris Kennaway     rc2_ctrl,
70ddd58736SKris Kennaway     NULL
71ddd58736SKris Kennaway };
72ddd58736SKris Kennaway 
735c87c606SMark Murray const EVP_CIPHER *EVP_rc2_64_cbc(void)
74ddd58736SKris Kennaway {
75*e71b7053SJung-uk Kim     return &r2_64_cbc_cipher;
76ddd58736SKris Kennaway }
77ddd58736SKris Kennaway 
785c87c606SMark Murray const EVP_CIPHER *EVP_rc2_40_cbc(void)
79ddd58736SKris Kennaway {
80*e71b7053SJung-uk Kim     return &r2_40_cbc_cipher;
81ddd58736SKris Kennaway }
82ddd58736SKris Kennaway 
83ddd58736SKris Kennaway static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
84ddd58736SKris Kennaway                         const unsigned char *iv, int enc)
85ddd58736SKris Kennaway {
865c87c606SMark Murray     RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx),
875c87c606SMark Murray                 key, data(ctx)->key_bits);
88ddd58736SKris Kennaway     return 1;
89ddd58736SKris Kennaway }
90ddd58736SKris Kennaway 
91ddd58736SKris Kennaway static int rc2_meth_to_magic(EVP_CIPHER_CTX *e)
92ddd58736SKris Kennaway {
93ddd58736SKris Kennaway     int i;
94ddd58736SKris Kennaway 
95ddd58736SKris Kennaway     EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i);
966f9291ceSJung-uk Kim     if (i == 128)
97*e71b7053SJung-uk Kim         return RC2_128_MAGIC;
986f9291ceSJung-uk Kim     else if (i == 64)
99*e71b7053SJung-uk Kim         return RC2_64_MAGIC;
1006f9291ceSJung-uk Kim     else if (i == 40)
101*e71b7053SJung-uk Kim         return RC2_40_MAGIC;
1026f9291ceSJung-uk Kim     else
103*e71b7053SJung-uk Kim         return 0;
104ddd58736SKris Kennaway }
105ddd58736SKris Kennaway 
106ddd58736SKris Kennaway static int rc2_magic_to_meth(int i)
107ddd58736SKris Kennaway {
1086f9291ceSJung-uk Kim     if (i == RC2_128_MAGIC)
1096f9291ceSJung-uk Kim         return 128;
1106f9291ceSJung-uk Kim     else if (i == RC2_64_MAGIC)
1116f9291ceSJung-uk Kim         return 64;
1126f9291ceSJung-uk Kim     else if (i == RC2_40_MAGIC)
1136f9291ceSJung-uk Kim         return 40;
1146f9291ceSJung-uk Kim     else {
115ddd58736SKris Kennaway         EVPerr(EVP_F_RC2_MAGIC_TO_METH, EVP_R_UNSUPPORTED_KEY_SIZE);
116*e71b7053SJung-uk Kim         return 0;
117ddd58736SKris Kennaway     }
118ddd58736SKris Kennaway }
119ddd58736SKris Kennaway 
120ddd58736SKris Kennaway static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
121ddd58736SKris Kennaway {
122ddd58736SKris Kennaway     long num = 0;
1233b4e3dcbSSimon L. B. Nielsen     int i = 0;
124ddd58736SKris Kennaway     int key_bits;
1253b4e3dcbSSimon L. B. Nielsen     unsigned int l;
126ddd58736SKris Kennaway     unsigned char iv[EVP_MAX_IV_LENGTH];
127ddd58736SKris Kennaway 
1286f9291ceSJung-uk Kim     if (type != NULL) {
129ddd58736SKris Kennaway         l = EVP_CIPHER_CTX_iv_length(c);
1303b4e3dcbSSimon L. B. Nielsen         OPENSSL_assert(l <= sizeof(iv));
131ddd58736SKris Kennaway         i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l);
1323b4e3dcbSSimon L. B. Nielsen         if (i != (int)l)
133*e71b7053SJung-uk Kim             return -1;
134ddd58736SKris Kennaway         key_bits = rc2_magic_to_meth((int)num);
135ddd58736SKris Kennaway         if (!key_bits)
136*e71b7053SJung-uk Kim             return -1;
1371f13597dSJung-uk Kim         if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1))
1381f13597dSJung-uk Kim             return -1;
139ddd58736SKris Kennaway         EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
140*e71b7053SJung-uk Kim         if (EVP_CIPHER_CTX_set_key_length(c, key_bits / 8) <= 0)
141*e71b7053SJung-uk Kim             return -1;
142ddd58736SKris Kennaway     }
143*e71b7053SJung-uk Kim     return i;
144ddd58736SKris Kennaway }
145ddd58736SKris Kennaway 
146ddd58736SKris Kennaway static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type)
147ddd58736SKris Kennaway {
148ddd58736SKris Kennaway     long num;
149ddd58736SKris Kennaway     int i = 0, j;
150ddd58736SKris Kennaway 
1516f9291ceSJung-uk Kim     if (type != NULL) {
152ddd58736SKris Kennaway         num = rc2_meth_to_magic(c);
153ddd58736SKris Kennaway         j = EVP_CIPHER_CTX_iv_length(c);
154*e71b7053SJung-uk Kim         i = ASN1_TYPE_set_int_octetstring(type, num,
155*e71b7053SJung-uk Kim                                           (unsigned char *)EVP_CIPHER_CTX_original_iv(c),
156*e71b7053SJung-uk Kim                                           j);
157ddd58736SKris Kennaway     }
158*e71b7053SJung-uk Kim     return i;
159ddd58736SKris Kennaway }
160ddd58736SKris Kennaway 
161ddd58736SKris Kennaway static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
162ddd58736SKris Kennaway {
1636f9291ceSJung-uk Kim     switch (type) {
164ddd58736SKris Kennaway     case EVP_CTRL_INIT:
1655c87c606SMark Murray         data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8;
166ddd58736SKris Kennaway         return 1;
167ddd58736SKris Kennaway 
168ddd58736SKris Kennaway     case EVP_CTRL_GET_RC2_KEY_BITS:
1695c87c606SMark Murray         *(int *)ptr = data(c)->key_bits;
170ddd58736SKris Kennaway         return 1;
171ddd58736SKris Kennaway 
172ddd58736SKris Kennaway     case EVP_CTRL_SET_RC2_KEY_BITS:
1736f9291ceSJung-uk Kim         if (arg > 0) {
1745c87c606SMark Murray             data(c)->key_bits = arg;
175ddd58736SKris Kennaway             return 1;
176ddd58736SKris Kennaway         }
177ddd58736SKris Kennaway         return 0;
1781f13597dSJung-uk Kim # ifdef PBE_PRF_TEST
1791f13597dSJung-uk Kim     case EVP_CTRL_PBE_PRF_NID:
1801f13597dSJung-uk Kim         *(int *)ptr = NID_hmacWithMD5;
1811f13597dSJung-uk Kim         return 1;
1821f13597dSJung-uk Kim # endif
183ddd58736SKris Kennaway 
184ddd58736SKris Kennaway     default:
185ddd58736SKris Kennaway         return -1;
186ddd58736SKris Kennaway     }
187ddd58736SKris Kennaway }
188ddd58736SKris Kennaway 
189ddd58736SKris Kennaway #endif
190