]>
Commit | Line | Data |
---|---|---|
62867571 | 1 | /* |
f5afac4b | 2 | * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. |
d02b48c6 | 3 | * |
4a8b0c55 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
62867571 RS |
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 | |
d02b48c6 RE |
8 | */ |
9 | ||
ee2993ab P |
10 | /* |
11 | * RC2 low level APIs are deprecated for public use, but still ok for internal | |
12 | * use. | |
13 | */ | |
14 | #include "internal/deprecated.h" | |
15 | ||
d02b48c6 | 16 | #include <stdio.h> |
b39fc560 | 17 | #include "internal/cryptlib.h" |
c7e7fc3e RL |
18 | |
19 | #ifndef OPENSSL_NO_RC2 | |
20 | ||
0f113f3e MC |
21 | # include <openssl/evp.h> |
22 | # include <openssl/objects.h> | |
25f2138b | 23 | # include "crypto/evp.h" |
0f113f3e | 24 | # include <openssl/rc2.h> |
2f5c405a | 25 | # include "evp_local.h" |
d02b48c6 | 26 | |
1921eaad | 27 | static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
0f113f3e | 28 | const unsigned char *iv, int enc); |
49528751 DSH |
29 | static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx); |
30 | static int rc2_magic_to_meth(int i); | |
dfeab068 RE |
31 | static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); |
32 | static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); | |
49528751 | 33 | static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); |
dfeab068 | 34 | |
0f113f3e MC |
35 | typedef struct { |
36 | int key_bits; /* effective key bits */ | |
37 | RC2_KEY ks; /* key schedule */ | |
38 | } EVP_RC2_KEY; | |
dbad1690 | 39 | |
6435f0f6 | 40 | # define data(ctx) EVP_C_DATA(EVP_RC2_KEY,ctx) |
dbad1690 BL |
41 | |
42 | IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2, | |
0f113f3e MC |
43 | 8, |
44 | RC2_KEY_LENGTH, 8, 64, | |
45 | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, | |
46 | rc2_init_key, NULL, | |
47 | rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv, | |
48 | rc2_ctrl) | |
49 | # define RC2_40_MAGIC 0xa0 | |
50 | # define RC2_64_MAGIC 0x78 | |
51 | # define RC2_128_MAGIC 0x3a | |
52 | static const EVP_CIPHER r2_64_cbc_cipher = { | |
53 | NID_rc2_64_cbc, | |
54 | 8, 8 /* 64 bit */ , 8, | |
55 | EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, | |
f6c95e46 | 56 | EVP_ORIG_GLOBAL, |
0f113f3e MC |
57 | rc2_init_key, |
58 | rc2_cbc_cipher, | |
59 | NULL, | |
60 | sizeof(EVP_RC2_KEY), | |
61 | rc2_set_asn1_type_and_iv, | |
62 | rc2_get_asn1_type_and_iv, | |
63 | rc2_ctrl, | |
64 | NULL | |
65 | }; | |
66 | ||
67 | static const EVP_CIPHER r2_40_cbc_cipher = { | |
68 | NID_rc2_40_cbc, | |
69 | 8, 5 /* 40 bit */ , 8, | |
70 | EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, | |
f6c95e46 | 71 | EVP_ORIG_GLOBAL, |
0f113f3e MC |
72 | rc2_init_key, |
73 | rc2_cbc_cipher, | |
74 | NULL, | |
75 | sizeof(EVP_RC2_KEY), | |
76 | rc2_set_asn1_type_and_iv, | |
77 | rc2_get_asn1_type_and_iv, | |
78 | rc2_ctrl, | |
79 | NULL | |
80 | }; | |
d02b48c6 | 81 | |
13588350 | 82 | const EVP_CIPHER *EVP_rc2_64_cbc(void) |
0f113f3e | 83 | { |
26a7d938 | 84 | return &r2_64_cbc_cipher; |
0f113f3e | 85 | } |
dfeab068 | 86 | |
13588350 | 87 | const EVP_CIPHER *EVP_rc2_40_cbc(void) |
0f113f3e | 88 | { |
26a7d938 | 89 | return &r2_40_cbc_cipher; |
0f113f3e MC |
90 | } |
91 | ||
1921eaad | 92 | static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, |
0f113f3e MC |
93 | const unsigned char *iv, int enc) |
94 | { | |
ed576acd | 95 | RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_get_key_length(ctx), |
0f113f3e MC |
96 | key, data(ctx)->key_bits); |
97 | return 1; | |
98 | } | |
d02b48c6 | 99 | |
49528751 | 100 | static int rc2_meth_to_magic(EVP_CIPHER_CTX *e) |
0f113f3e MC |
101 | { |
102 | int i; | |
103 | ||
434893af MC |
104 | if (EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i) <= 0) |
105 | return 0; | |
0f113f3e | 106 | if (i == 128) |
26a7d938 | 107 | return RC2_128_MAGIC; |
0f113f3e | 108 | else if (i == 64) |
26a7d938 | 109 | return RC2_64_MAGIC; |
0f113f3e | 110 | else if (i == 40) |
26a7d938 | 111 | return RC2_40_MAGIC; |
0f113f3e | 112 | else |
26a7d938 | 113 | return 0; |
0f113f3e | 114 | } |
dfeab068 | 115 | |
49528751 | 116 | static int rc2_magic_to_meth(int i) |
0f113f3e MC |
117 | { |
118 | if (i == RC2_128_MAGIC) | |
119 | return 128; | |
120 | else if (i == RC2_64_MAGIC) | |
121 | return 64; | |
122 | else if (i == RC2_40_MAGIC) | |
123 | return 40; | |
124 | else { | |
9311d0c4 | 125 | ERR_raise(ERR_LIB_EVP, EVP_R_UNSUPPORTED_KEY_SIZE); |
26a7d938 | 126 | return 0; |
0f113f3e MC |
127 | } |
128 | } | |
dfeab068 | 129 | |
6b691a5c | 130 | static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) |
0f113f3e MC |
131 | { |
132 | long num = 0; | |
133 | int i = 0; | |
134 | int key_bits; | |
135 | unsigned int l; | |
136 | unsigned char iv[EVP_MAX_IV_LENGTH]; | |
137 | ||
138 | if (type != NULL) { | |
ed576acd | 139 | l = EVP_CIPHER_CTX_get_iv_length(c); |
0f113f3e MC |
140 | OPENSSL_assert(l <= sizeof(iv)); |
141 | i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l); | |
142 | if (i != (int)l) | |
d356dc56 | 143 | return -1; |
0f113f3e MC |
144 | key_bits = rc2_magic_to_meth((int)num); |
145 | if (!key_bits) | |
d356dc56 | 146 | return -1; |
0f113f3e MC |
147 | if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1)) |
148 | return -1; | |
434893af MC |
149 | if (EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, |
150 | NULL) <= 0 | |
151 | || EVP_CIPHER_CTX_set_key_length(c, key_bits / 8) <= 0) | |
d356dc56 | 152 | return -1; |
0f113f3e | 153 | } |
d356dc56 | 154 | return i; |
0f113f3e | 155 | } |
dfeab068 | 156 | |
6b691a5c | 157 | static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) |
0f113f3e MC |
158 | { |
159 | long num; | |
160 | int i = 0, j; | |
161 | ||
162 | if (type != NULL) { | |
163 | num = rc2_meth_to_magic(c); | |
ed576acd | 164 | j = EVP_CIPHER_CTX_get_iv_length(c); |
d91f902d | 165 | i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j); |
0f113f3e | 166 | } |
26a7d938 | 167 | return i; |
0f113f3e | 168 | } |
dfeab068 | 169 | |
49528751 | 170 | static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) |
0f113f3e MC |
171 | { |
172 | switch (type) { | |
173 | case EVP_CTRL_INIT: | |
ed576acd | 174 | data(c)->key_bits = EVP_CIPHER_CTX_get_key_length(c) * 8; |
0f113f3e MC |
175 | return 1; |
176 | ||
177 | case EVP_CTRL_GET_RC2_KEY_BITS: | |
178 | *(int *)ptr = data(c)->key_bits; | |
179 | return 1; | |
180 | ||
181 | case EVP_CTRL_SET_RC2_KEY_BITS: | |
182 | if (arg > 0) { | |
183 | data(c)->key_bits = arg; | |
184 | return 1; | |
185 | } | |
186 | return 0; | |
187 | # ifdef PBE_PRF_TEST | |
188 | case EVP_CTRL_PBE_PRF_NID: | |
189 | *(int *)ptr = NID_hmacWithMD5; | |
190 | return 1; | |
191 | # endif | |
192 | ||
193 | default: | |
194 | return -1; | |
195 | } | |
196 | } | |
49528751 | 197 | |
d02b48c6 | 198 | #endif |