]> git.ipfire.org Git - thirdparty/openssl.git/blob - ssl/record/methods/ssl3_meth.c
Remove some final references to the SSL object in the record layer
[thirdparty/openssl.git] / ssl / record / methods / ssl3_meth.c
1 /*
2 * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the Apache License 2.0 (the "License"). You may not use
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
8 */
9
10 #include <openssl/evp.h>
11 #include <openssl/core_names.h>
12 #include "../../ssl_local.h"
13 #include "../record_local.h"
14 #include "recmethod_local.h"
15
16 /* TODO(RECLAYER): Handle OPENSSL_NO_COMP */
17 static int ssl3_set_crypto_state(OSSL_RECORD_LAYER *rl, int level,
18 unsigned char *key, size_t keylen,
19 unsigned char *iv, size_t ivlen,
20 unsigned char *mackey, size_t mackeylen,
21 const EVP_CIPHER *ciph,
22 size_t taglen,
23 /* TODO(RECLAYER): This probably should not be an int */
24 int mactype,
25 const EVP_MD *md,
26 const SSL_COMP *comp)
27 {
28 EVP_CIPHER_CTX *ciph_ctx;
29
30 if (md == NULL) {
31 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
32 return OSSL_RECORD_RETURN_FATAL;
33 }
34
35 if ((rl->enc_ctx = EVP_CIPHER_CTX_new()) == NULL) {
36 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
37 return OSSL_RECORD_RETURN_FATAL;
38 }
39 ciph_ctx = rl->enc_ctx;
40
41 rl->md_ctx = EVP_MD_CTX_new();
42 if (rl->md_ctx == NULL) {
43 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
44 return OSSL_RECORD_RETURN_FATAL;
45 }
46 #ifndef OPENSSL_NO_COMP
47 if (comp != NULL) {
48 rl->expand = COMP_CTX_new(comp->method);
49 if (rl->expand == NULL) {
50 ERR_raise(ERR_LIB_SSL, SSL_R_COMPRESSION_LIBRARY_ERROR);
51 return OSSL_RECORD_RETURN_FATAL;
52 }
53 }
54 #endif
55
56 if (!EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, key, iv)) {
57 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
58 return OSSL_RECORD_RETURN_FATAL;
59 }
60
61 if (EVP_CIPHER_get0_provider(ciph) != NULL
62 && !ossl_set_tls_provider_parameters(rl, ciph_ctx, ciph, md)) {
63 return OSSL_RECORD_RETURN_FATAL;
64 }
65
66 if (mackeylen > sizeof(rl->mac_secret)) {
67 ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR);
68 return OSSL_RECORD_RETURN_FATAL;
69 }
70 memcpy(rl->mac_secret, mackey, mackeylen);
71
72 return OSSL_RECORD_RETURN_SUCCESS;
73 }
74
75 /*
76 * ssl3_cipher encrypts/decrypts |n_recs| records in |inrecs|. Calls RLAYERfatal
77 * on internal error, but not otherwise. It is the responsibility of the caller
78 * to report a bad_record_mac
79 *
80 * Returns:
81 * 0: if the record is publicly invalid, or an internal error
82 * 1: Success or Mac-then-encrypt decryption failed (MAC will be randomised)
83 */
84 static int ssl3_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *inrecs, size_t n_recs,
85 int sending, SSL_MAC_BUF *mac, size_t macsize)
86 {
87 SSL3_RECORD *rec;
88 EVP_CIPHER_CTX *ds;
89 size_t l, i;
90 size_t bs;
91 const EVP_CIPHER *enc;
92 int provided;
93
94 rec = inrecs;
95 /*
96 * We shouldn't ever be called with more than one record in the SSLv3 case
97 */
98 if (n_recs != 1)
99 return 0;
100
101 ds = rl->enc_ctx;
102 if (rl->enc_ctx == NULL)
103 enc = NULL;
104 else
105 enc = EVP_CIPHER_CTX_get0_cipher(rl->enc_ctx);
106
107 provided = (EVP_CIPHER_get0_provider(enc) != NULL);
108
109 l = rec->length;
110 bs = EVP_CIPHER_CTX_get_block_size(ds);
111
112 /* COMPRESS */
113
114 if ((bs != 1) && sending && !provided) {
115 /*
116 * We only do this for legacy ciphers. Provided ciphers add the
117 * padding on the provider side.
118 */
119 i = bs - (l % bs);
120
121 /* we need to add 'i-1' padding bytes */
122 l += i;
123 /*
124 * the last of these zero bytes will be overwritten with the
125 * padding length.
126 */
127 memset(&rec->input[rec->length], 0, i);
128 rec->length += i;
129 rec->input[l - 1] = (unsigned char)(i - 1);
130 }
131
132 if (!sending) {
133 if (l == 0 || l % bs != 0) {
134 /* Publicly invalid */
135 return 0;
136 }
137 /* otherwise, rec->length >= bs */
138 }
139
140 if (provided) {
141 int outlen;
142
143 if (!EVP_CipherUpdate(ds, rec->data, &outlen, rec->input,
144 (unsigned int)l))
145 return 0;
146 rec->length = outlen;
147
148 if (!sending && mac != NULL) {
149 /* Now get a pointer to the MAC */
150 OSSL_PARAM params[2], *p = params;
151
152 /* Get the MAC */
153 mac->alloced = 0;
154
155 *p++ = OSSL_PARAM_construct_octet_ptr(OSSL_CIPHER_PARAM_TLS_MAC,
156 (void **)&mac->mac,
157 macsize);
158 *p = OSSL_PARAM_construct_end();
159
160 if (!EVP_CIPHER_CTX_get_params(ds, params)) {
161 /* Shouldn't normally happen */
162 RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
163 return 0;
164 }
165 }
166 } else {
167 if (EVP_Cipher(ds, rec->data, rec->input, (unsigned int)l) < 1) {
168 /* Shouldn't happen */
169 RLAYERfatal(rl, SSL_AD_BAD_RECORD_MAC, ERR_R_INTERNAL_ERROR);
170 return 0;
171 }
172
173 if (!sending)
174 return ssl3_cbc_remove_padding_and_mac(&rec->length,
175 rec->orig_len,
176 rec->data,
177 (mac != NULL) ? &mac->mac : NULL,
178 (mac != NULL) ? &mac->alloced : NULL,
179 bs,
180 macsize,
181 rl->libctx);
182 }
183
184 return 1;
185 }
186
187 static const unsigned char ssl3_pad_1[48] = {
188 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
189 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
190 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
191 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
192 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
193 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
194 };
195
196 static const unsigned char ssl3_pad_2[48] = {
197 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
198 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
199 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
200 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
201 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
202 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c
203 };
204
205 static int ssl3_mac(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, unsigned char *md,
206 int sending)
207 {
208 unsigned char *mac_sec, *seq = rl->sequence;
209 const EVP_MD_CTX *hash;
210 unsigned char *p, rec_char;
211 size_t md_size;
212 size_t npad;
213 int t;
214
215 mac_sec = &(rl->mac_secret[0]);
216 hash = rl->md_ctx;
217
218 t = EVP_MD_CTX_get_size(hash);
219 if (t < 0)
220 return 0;
221 md_size = t;
222 npad = (48 / md_size) * md_size;
223
224 if (!sending
225 && EVP_CIPHER_CTX_get_mode(rl->enc_ctx) == EVP_CIPH_CBC_MODE
226 && ssl3_cbc_record_digest_supported(hash)) {
227 #ifdef OPENSSL_NO_DEPRECATED_3_0
228 return 0;
229 #else
230 /*
231 * This is a CBC-encrypted record. We must avoid leaking any
232 * timing-side channel information about how many blocks of data we
233 * are hashing because that gives an attacker a timing-oracle.
234 */
235
236 /*-
237 * npad is, at most, 48 bytes and that's with MD5:
238 * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75.
239 *
240 * With SHA-1 (the largest hash speced for SSLv3) the hash size
241 * goes up 4, but npad goes down by 8, resulting in a smaller
242 * total size.
243 */
244 unsigned char header[75];
245 size_t j = 0;
246 memcpy(header + j, mac_sec, md_size);
247 j += md_size;
248 memcpy(header + j, ssl3_pad_1, npad);
249 j += npad;
250 memcpy(header + j, seq, 8);
251 j += 8;
252 header[j++] = rec->type;
253 header[j++] = (unsigned char)(rec->length >> 8);
254 header[j++] = (unsigned char)(rec->length & 0xff);
255
256 /* Final param == is SSLv3 */
257 if (ssl3_cbc_digest_record(EVP_MD_CTX_get0_md(hash),
258 md, &md_size,
259 header, rec->input,
260 rec->length, rec->orig_len,
261 mac_sec, md_size, 1) <= 0)
262 return 0;
263 #endif
264 } else {
265 unsigned int md_size_u;
266 /* Chop the digest off the end :-) */
267 EVP_MD_CTX *md_ctx = EVP_MD_CTX_new();
268
269 if (md_ctx == NULL)
270 return 0;
271
272 rec_char = rec->type;
273 p = md;
274 s2n(rec->length, p);
275 if (EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
276 || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
277 || EVP_DigestUpdate(md_ctx, ssl3_pad_1, npad) <= 0
278 || EVP_DigestUpdate(md_ctx, seq, 8) <= 0
279 || EVP_DigestUpdate(md_ctx, &rec_char, 1) <= 0
280 || EVP_DigestUpdate(md_ctx, md, 2) <= 0
281 || EVP_DigestUpdate(md_ctx, rec->input, rec->length) <= 0
282 || EVP_DigestFinal_ex(md_ctx, md, NULL) <= 0
283 || EVP_MD_CTX_copy_ex(md_ctx, hash) <= 0
284 || EVP_DigestUpdate(md_ctx, mac_sec, md_size) <= 0
285 || EVP_DigestUpdate(md_ctx, ssl3_pad_2, npad) <= 0
286 || EVP_DigestUpdate(md_ctx, md, md_size) <= 0
287 || EVP_DigestFinal_ex(md_ctx, md, &md_size_u) <= 0) {
288 EVP_MD_CTX_free(md_ctx);
289 return 0;
290 }
291
292 EVP_MD_CTX_free(md_ctx);
293 }
294
295 ssl3_record_sequence_update(seq);
296 return 1;
297 }
298
299 struct record_functions_st ssl_3_0_funcs = {
300 ssl3_set_crypto_state,
301 tls_default_read_n,
302 ssl3_cipher,
303 ssl3_mac,
304 tls_default_set_protocol_version,
305 tls_default_validate_record_header,
306 tls_default_post_process_record
307 };