]>
Commit | Line | Data |
---|---|---|
50023e9b MC |
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 | static int tls13_set_crypto_state(OSSL_RECORD_LAYER *rl, int level, | |
17 | unsigned char *key, size_t keylen, | |
18 | unsigned char *iv, size_t ivlen, | |
19 | unsigned char *mackey, size_t mackeylen, | |
20 | const EVP_CIPHER *ciph, | |
21 | size_t taglen, | |
22 | /* TODO(RECLAYER): This probably should not be an int */ | |
23 | int mactype, | |
24 | const EVP_MD *md, | |
25 | const SSL_COMP *comp, | |
26 | /* TODO(RECLAYER): Remove me */ | |
27 | SSL_CONNECTION *s) | |
28 | { | |
29 | EVP_CIPHER_CTX *ciph_ctx; | |
30 | int mode; | |
31 | ||
32 | if (ivlen > sizeof(rl->iv)) { | |
7c293999 MC |
33 | ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); |
34 | return OSSL_RECORD_RETURN_FATAL; | |
50023e9b MC |
35 | } |
36 | memcpy(rl->iv, iv, ivlen); | |
37 | ||
38 | ciph_ctx = rl->enc_read_ctx = EVP_CIPHER_CTX_new(); | |
39 | if (ciph_ctx == NULL) { | |
7c293999 MC |
40 | ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); |
41 | return OSSL_RECORD_RETURN_FATAL; | |
50023e9b MC |
42 | } |
43 | ||
50023e9b MC |
44 | rl->taglen = taglen; |
45 | ||
46 | mode = EVP_CIPHER_get_mode(ciph); | |
47 | ||
48 | if (EVP_DecryptInit_ex(ciph_ctx, ciph, NULL, NULL, NULL) <= 0 | |
49 | || EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL) <= 0 | |
50 | || (mode == EVP_CIPH_CCM_MODE | |
51 | && EVP_CIPHER_CTX_ctrl(ciph_ctx, EVP_CTRL_AEAD_SET_TAG, taglen, NULL) <= 0) | |
52 | || EVP_DecryptInit_ex(ciph_ctx, NULL, NULL, key, NULL) <= 0) { | |
7c293999 MC |
53 | ERR_raise(ERR_LIB_SSL, ERR_R_INTERNAL_ERROR); |
54 | return OSSL_RECORD_RETURN_FATAL; | |
50023e9b MC |
55 | } |
56 | ||
7c293999 | 57 | return OSSL_RECORD_RETURN_SUCCESS; |
50023e9b MC |
58 | } |
59 | ||
60 | static int tls13_cipher(OSSL_RECORD_LAYER *rl, SSL3_RECORD *recs, size_t n_recs, | |
61 | int sending, SSL_MAC_BUF *mac, size_t macsize, | |
62 | /* TODO(RECLAYER): Remove me */ SSL_CONNECTION *s) | |
63 | { | |
64 | EVP_CIPHER_CTX *ctx; | |
65 | unsigned char iv[EVP_MAX_IV_LENGTH], recheader[SSL3_RT_HEADER_LENGTH]; | |
66 | size_t ivlen, offset, loop, hdrlen; | |
67 | unsigned char *staticiv; | |
0755722c | 68 | unsigned char *seq = rl->sequence; |
50023e9b MC |
69 | int lenu, lenf; |
70 | SSL3_RECORD *rec = &recs[0]; | |
71 | WPACKET wpkt; | |
72 | const EVP_CIPHER *cipher; | |
73 | int mode; | |
74 | ||
75 | if (n_recs != 1) { | |
76 | /* Should not happen */ | |
77 | RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | |
78 | return 0; | |
79 | } | |
80 | ||
81 | if (sending) { | |
82 | ctx = s->enc_write_ctx; | |
83 | staticiv = s->write_iv; | |
50023e9b MC |
84 | } else { |
85 | ctx = rl->enc_read_ctx; | |
86 | staticiv = rl->iv; | |
50023e9b MC |
87 | } |
88 | ||
89 | cipher = EVP_CIPHER_CTX_get0_cipher(ctx); | |
90 | if (cipher == NULL) { | |
91 | RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | |
92 | return 0; | |
93 | } | |
94 | mode = EVP_CIPHER_get_mode(cipher); | |
95 | ||
96 | /* | |
97 | * If we're sending an alert and ctx != NULL then we must be forcing | |
98 | * plaintext alerts. If we're reading and ctx != NULL then we allow | |
99 | * plaintext alerts at certain points in the handshake. If we've got this | |
100 | * far then we have already validated that a plaintext alert is ok here. | |
101 | */ | |
102 | if (ctx == NULL || rec->type == SSL3_RT_ALERT) { | |
103 | memmove(rec->data, rec->input, rec->length); | |
104 | rec->input = rec->data; | |
105 | return 1; | |
106 | } | |
107 | ||
108 | ivlen = EVP_CIPHER_CTX_get_iv_length(ctx); | |
109 | ||
110 | if (!sending) { | |
111 | /* | |
112 | * Take off tag. There must be at least one byte of content type as | |
113 | * well as the tag | |
114 | */ | |
115 | if (rec->length < rl->taglen + 1) | |
116 | return 0; | |
117 | rec->length -= rl->taglen; | |
118 | } | |
119 | ||
120 | /* Set up IV */ | |
121 | if (ivlen < SEQ_NUM_SIZE) { | |
122 | /* Should not happen */ | |
123 | RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | |
124 | return 0; | |
125 | } | |
126 | offset = ivlen - SEQ_NUM_SIZE; | |
127 | memcpy(iv, staticiv, offset); | |
128 | for (loop = 0; loop < SEQ_NUM_SIZE; loop++) | |
129 | iv[offset + loop] = staticiv[offset + loop] ^ seq[loop]; | |
130 | ||
131 | /* Increment the sequence counter */ | |
132 | for (loop = SEQ_NUM_SIZE; loop > 0; loop--) { | |
133 | ++seq[loop - 1]; | |
134 | if (seq[loop - 1] != 0) | |
135 | break; | |
136 | } | |
137 | if (loop == 0) { | |
138 | /* Sequence has wrapped */ | |
139 | return 0; | |
140 | } | |
141 | ||
142 | if (EVP_CipherInit_ex(ctx, NULL, NULL, NULL, iv, sending) <= 0 | |
143 | || (!sending && EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, | |
144 | rl->taglen, | |
145 | rec->data + rec->length) <= 0)) { | |
146 | RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | |
147 | return 0; | |
148 | } | |
149 | ||
150 | /* Set up the AAD */ | |
151 | if (!WPACKET_init_static_len(&wpkt, recheader, sizeof(recheader), 0) | |
152 | || !WPACKET_put_bytes_u8(&wpkt, rec->type) | |
153 | || !WPACKET_put_bytes_u16(&wpkt, rec->rec_version) | |
154 | || !WPACKET_put_bytes_u16(&wpkt, rec->length + rl->taglen) | |
155 | || !WPACKET_get_total_written(&wpkt, &hdrlen) | |
156 | || hdrlen != SSL3_RT_HEADER_LENGTH | |
157 | || !WPACKET_finish(&wpkt)) { | |
158 | RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | |
159 | WPACKET_cleanup(&wpkt); | |
160 | return 0; | |
161 | } | |
162 | ||
163 | /* | |
164 | * For CCM we must explicitly set the total plaintext length before we add | |
165 | * any AAD. | |
166 | */ | |
167 | if ((mode == EVP_CIPH_CCM_MODE | |
168 | && EVP_CipherUpdate(ctx, NULL, &lenu, NULL, | |
169 | (unsigned int)rec->length) <= 0) | |
170 | || EVP_CipherUpdate(ctx, NULL, &lenu, recheader, | |
171 | sizeof(recheader)) <= 0 | |
172 | || EVP_CipherUpdate(ctx, rec->data, &lenu, rec->input, | |
173 | (unsigned int)rec->length) <= 0 | |
174 | || EVP_CipherFinal_ex(ctx, rec->data + lenu, &lenf) <= 0 | |
175 | || (size_t)(lenu + lenf) != rec->length) { | |
176 | return 0; | |
177 | } | |
178 | if (sending) { | |
179 | /* Add the tag */ | |
180 | if (EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, rl->taglen, | |
181 | rec->data + rec->length) <= 0) { | |
182 | RLAYERfatal(rl, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR); | |
183 | return 0; | |
184 | } | |
185 | rec->length += rl->taglen; | |
186 | } | |
187 | ||
188 | return 1; | |
189 | } | |
190 | ||
1853d20a MC |
191 | static int tls13_validate_record_header(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec) |
192 | { | |
193 | if (rec->type != SSL3_RT_APPLICATION_DATA | |
194 | && (rec->type != SSL3_RT_CHANGE_CIPHER_SPEC | |
195 | || !rl->is_first_handshake) | |
196 | && (rec->type != SSL3_RT_ALERT || !rl->allow_plain_alerts)) { | |
197 | RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, SSL_R_BAD_RECORD_TYPE); | |
198 | return 0; | |
199 | } | |
200 | ||
201 | if (rec->rec_version != TLS1_2_VERSION) { | |
202 | RLAYERfatal(rl, SSL_AD_DECODE_ERROR, SSL_R_WRONG_VERSION_NUMBER); | |
203 | return 0; | |
204 | } | |
205 | ||
206 | if (rec->length > SSL3_RT_MAX_TLS13_ENCRYPTED_LENGTH) { | |
207 | RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, | |
208 | SSL_R_ENCRYPTED_LENGTH_TOO_LONG); | |
209 | return 0; | |
210 | } | |
211 | return 1; | |
212 | } | |
213 | ||
214 | static int tls13_post_process_record(OSSL_RECORD_LAYER *rl, SSL3_RECORD *rec, | |
215 | SSL_CONNECTION *s) | |
216 | { | |
217 | /* Skip this if we've received a plaintext alert */ | |
218 | if (rec->type != SSL3_RT_ALERT) { | |
219 | size_t end; | |
220 | ||
221 | if (rec->length == 0 | |
222 | || rec->type != SSL3_RT_APPLICATION_DATA) { | |
223 | RLAYERfatal(rl, SSL_AD_UNEXPECTED_MESSAGE, | |
224 | SSL_R_BAD_RECORD_TYPE); | |
225 | return 0; | |
226 | } | |
227 | ||
228 | /* Strip trailing padding */ | |
229 | for (end = rec->length - 1; end > 0 && rec->data[end] == 0; | |
230 | end--) | |
231 | continue; | |
232 | ||
233 | rec->length = end; | |
234 | rec->type = rec->data[end]; | |
235 | } | |
236 | ||
237 | if (rec->length > SSL3_RT_MAX_PLAIN_LENGTH) { | |
238 | RLAYERfatal(rl, SSL_AD_RECORD_OVERFLOW, SSL_R_DATA_LENGTH_TOO_LONG); | |
239 | return 0; | |
240 | } | |
241 | ||
242 | if (!tls13_common_post_process_record(rl, rec, s)) { | |
243 | /* RLAYERfatal already called */ | |
244 | return 0; | |
245 | } | |
246 | ||
247 | return 1; | |
248 | } | |
249 | ||
50023e9b MC |
250 | struct record_functions_st tls_1_3_funcs = { |
251 | tls13_set_crypto_state, | |
1853d20a | 252 | tls_default_read_n, |
50023e9b | 253 | tls13_cipher, |
1853d20a MC |
254 | NULL, |
255 | tls_default_set_protocol_version, | |
256 | tls13_validate_record_header, | |
257 | tls13_post_process_record | |
50023e9b | 258 | }; |