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