1 |
diff -up openssl-fips-0.9.8e/ssl/d1_pkt.c.dtls-fixes2 openssl-fips-0.9.8e/ssl/d1_pkt.c |
2 |
--- openssl-fips-0.9.8e/ssl/d1_pkt.c.dtls-fixes2 2012-01-16 11:00:34.242797904 +0100 |
3 |
+++ openssl-fips-0.9.8e/ssl/d1_pkt.c 2012-01-18 15:45:25.144865068 +0100 |
4 |
@@ -134,7 +134,7 @@ static int dtls1_record_needs_buffering( |
5 |
unsigned short *priority, unsigned long *offset); |
6 |
#endif |
7 |
static int dtls1_buffer_record(SSL *s, record_pqueue *q, |
8 |
- PQ_64BIT priority); |
9 |
+ PQ_64BIT *priority); |
10 |
static int dtls1_process_record(SSL *s); |
11 |
#if PQ_64BIT_IS_INTEGER |
12 |
static PQ_64BIT bytes_to_long_long(unsigned char *bytes, PQ_64BIT *num); |
13 |
@@ -156,13 +156,16 @@ dtls1_copy_record(SSL *s, pitem *item) |
14 |
s->packet_length = rdata->packet_length; |
15 |
memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); |
16 |
memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); |
17 |
+ |
18 |
+ /* Set proper sequence number for mac calculation */ |
19 |
+ memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6); |
20 |
|
21 |
return(1); |
22 |
} |
23 |
|
24 |
|
25 |
static int |
26 |
-dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT priority) |
27 |
+dtls1_buffer_record(SSL *s, record_pqueue *queue, PQ_64BIT *priority) |
28 |
{ |
29 |
DTLS1_RECORD_DATA *rdata; |
30 |
pitem *item; |
31 |
@@ -172,7 +175,7 @@ dtls1_buffer_record(SSL *s, record_pqueu |
32 |
return 0; |
33 |
|
34 |
rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); |
35 |
- item = pitem_new(priority, rdata); |
36 |
+ item = pitem_new(*priority, rdata); |
37 |
if (rdata == NULL || item == NULL) |
38 |
{ |
39 |
if (rdata != NULL) OPENSSL_free(rdata); |
40 |
@@ -253,9 +256,6 @@ dtls1_process_buffered_records(SSL *s) |
41 |
item = pqueue_peek(s->d1->unprocessed_rcds.q); |
42 |
if (item) |
43 |
{ |
44 |
- DTLS1_RECORD_DATA *rdata; |
45 |
- rdata = (DTLS1_RECORD_DATA *)item->data; |
46 |
- |
47 |
/* Check if epoch is current. */ |
48 |
if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) |
49 |
return(1); /* Nothing to do. */ |
50 |
@@ -267,7 +267,7 @@ dtls1_process_buffered_records(SSL *s) |
51 |
if ( ! dtls1_process_record(s)) |
52 |
return(0); |
53 |
dtls1_buffer_record(s, &(s->d1->processed_rcds), |
54 |
- s->s3->rrec.seq_num); |
55 |
+ &s->s3->rrec.seq_num); |
56 |
} |
57 |
} |
58 |
|
59 |
@@ -328,13 +328,15 @@ dtls1_get_buffered_record(SSL *s) |
60 |
static int |
61 |
dtls1_process_record(SSL *s) |
62 |
{ |
63 |
- int i,al; |
64 |
+ int al; |
65 |
int clear=0; |
66 |
int enc_err; |
67 |
SSL_SESSION *sess; |
68 |
SSL3_RECORD *rr; |
69 |
unsigned int mac_size; |
70 |
unsigned char md[EVP_MAX_MD_SIZE]; |
71 |
+ int decryption_failed_or_bad_record_mac = 0; |
72 |
+ unsigned char *mac = NULL; |
73 |
|
74 |
|
75 |
rr= &(s->s3->rrec); |
76 |
@@ -369,12 +371,10 @@ dtls1_process_record(SSL *s) |
77 |
enc_err = s->method->ssl3_enc->enc(s,0); |
78 |
if (enc_err <= 0) |
79 |
{ |
80 |
- if (enc_err == 0) |
81 |
- /* SSLerr() and ssl3_send_alert() have been called */ |
82 |
- goto err; |
83 |
- |
84 |
- /* otherwise enc_err == -1 */ |
85 |
- goto decryption_failed_or_bad_record_mac; |
86 |
+ /* To minimize information leaked via timing, we will always |
87 |
+ * perform all computations before discarding the message. |
88 |
+ */ |
89 |
+ decryption_failed_or_bad_record_mac = 1; |
90 |
} |
91 |
|
92 |
#ifdef TLS_DEBUG |
93 |
@@ -400,28 +400,32 @@ if ( (sess == NULL) || |
94 |
SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_PRE_MAC_LENGTH_TOO_LONG); |
95 |
goto f_err; |
96 |
#else |
97 |
- goto decryption_failed_or_bad_record_mac; |
98 |
+ decryption_failed_or_bad_record_mac = 1; |
99 |
#endif |
100 |
} |
101 |
/* check the MAC for rr->input (it's in mac_size bytes at the tail) */ |
102 |
- if (rr->length < mac_size) |
103 |
+ if (rr->length >= mac_size) |
104 |
{ |
105 |
-#if 0 /* OK only for stream ciphers */ |
106 |
- al=SSL_AD_DECODE_ERROR; |
107 |
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_LENGTH_TOO_SHORT); |
108 |
- goto f_err; |
109 |
-#else |
110 |
- goto decryption_failed_or_bad_record_mac; |
111 |
-#endif |
112 |
+ rr->length -= mac_size; |
113 |
+ mac = &rr->data[rr->length]; |
114 |
} |
115 |
- rr->length-=mac_size; |
116 |
- i=s->method->ssl3_enc->mac(s,md,0); |
117 |
- if (memcmp(md,&(rr->data[rr->length]),mac_size) != 0) |
118 |
+ else |
119 |
+ rr->length = 0; |
120 |
+ s->method->ssl3_enc->mac(s,md,0); |
121 |
+ if (mac == NULL || memcmp(md, mac, mac_size) != 0) |
122 |
{ |
123 |
- goto decryption_failed_or_bad_record_mac; |
124 |
+ decryption_failed_or_bad_record_mac = 1; |
125 |
} |
126 |
} |
127 |
|
128 |
+ if (decryption_failed_or_bad_record_mac) |
129 |
+ { |
130 |
+ /* decryption failed, silently discard message */ |
131 |
+ rr->length = 0; |
132 |
+ s->packet_length = 0; |
133 |
+ goto err; |
134 |
+ } |
135 |
+ |
136 |
/* r->length is now just compressed */ |
137 |
if (s->expand != NULL) |
138 |
{ |
139 |
@@ -460,14 +464,6 @@ if ( (sess == NULL) || |
140 |
dtls1_record_bitmap_update(s, &(s->d1->bitmap));/* Mark receipt of record. */ |
141 |
return(1); |
142 |
|
143 |
-decryption_failed_or_bad_record_mac: |
144 |
- /* Separate 'decryption_failed' alert was introduced with TLS 1.0, |
145 |
- * SSL 3.0 only has 'bad_record_mac'. But unless a decryption |
146 |
- * failure is directly visible from the ciphertext anyway, |
147 |
- * we should not reveal which kind of error occured -- this |
148 |
- * might become visible to an attacker (e.g. via logfile) */ |
149 |
- al=SSL_AD_BAD_RECORD_MAC; |
150 |
- SSLerr(SSL_F_DTLS1_PROCESS_RECORD,SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); |
151 |
f_err: |
152 |
ssl3_send_alert(s,SSL3_AL_FATAL,al); |
153 |
err: |
154 |
@@ -486,22 +482,19 @@ err: |
155 |
/* used only by dtls1_read_bytes */ |
156 |
int dtls1_get_record(SSL *s) |
157 |
{ |
158 |
- int ssl_major,ssl_minor,al; |
159 |
+ int ssl_major,ssl_minor; |
160 |
int i,n; |
161 |
SSL3_RECORD *rr; |
162 |
- SSL_SESSION *sess; |
163 |
- unsigned char *p; |
164 |
+ unsigned char *p = NULL; |
165 |
unsigned short version; |
166 |
DTLS1_BITMAP *bitmap; |
167 |
unsigned int is_next_epoch; |
168 |
|
169 |
rr= &(s->s3->rrec); |
170 |
- sess=s->session; |
171 |
|
172 |
/* The epoch may have changed. If so, process all the |
173 |
* pending records. This is a non-blocking operation. */ |
174 |
- if ( ! dtls1_process_buffered_records(s)) |
175 |
- return 0; |
176 |
+ dtls1_process_buffered_records(s); |
177 |
|
178 |
/* if we're renegotiating, then there may be buffered records */ |
179 |
if (dtls1_get_processed_record(s)) |
180 |
@@ -517,7 +510,12 @@ again: |
181 |
/* read timeout is handled by dtls1_read_bytes */ |
182 |
if (n <= 0) return(n); /* error or non-blocking */ |
183 |
|
184 |
- OPENSSL_assert(s->packet_length == DTLS1_RT_HEADER_LENGTH); |
185 |
+ /* this packet contained a partial record, dump it */ |
186 |
+ if (s->packet_length != DTLS1_RT_HEADER_LENGTH) |
187 |
+ { |
188 |
+ s->packet_length = 0; |
189 |
+ goto again; |
190 |
+ } |
191 |
|
192 |
s->rstate=SSL_ST_READ_BODY; |
193 |
|
194 |
@@ -542,27 +540,28 @@ again: |
195 |
{ |
196 |
if (version != s->version && version != DTLS1_BAD_VER) |
197 |
{ |
198 |
- SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); |
199 |
- /* Send back error using their |
200 |
- * version number :-) */ |
201 |
- s->version=version; |
202 |
- al=SSL_AD_PROTOCOL_VERSION; |
203 |
- goto f_err; |
204 |
+ /* unexpected version, silently discard */ |
205 |
+ rr->length = 0; |
206 |
+ s->packet_length = 0; |
207 |
+ goto again; |
208 |
} |
209 |
} |
210 |
|
211 |
if ((version & 0xff00) != (DTLS1_VERSION & 0xff00) && |
212 |
(version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) |
213 |
{ |
214 |
- SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_WRONG_VERSION_NUMBER); |
215 |
- goto err; |
216 |
+ /* wrong version, silently discard record */ |
217 |
+ rr->length = 0; |
218 |
+ s->packet_length = 0; |
219 |
+ goto again; |
220 |
} |
221 |
|
222 |
if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) |
223 |
{ |
224 |
- al=SSL_AD_RECORD_OVERFLOW; |
225 |
- SSLerr(SSL_F_DTLS1_GET_RECORD,SSL_R_PACKET_LENGTH_TOO_LONG); |
226 |
- goto f_err; |
227 |
+ /* record too long, silently discard it */ |
228 |
+ rr->length = 0; |
229 |
+ s->packet_length = 0; |
230 |
+ goto again; |
231 |
} |
232 |
|
233 |
s->client_version = version; |
234 |
@@ -581,6 +580,7 @@ again: |
235 |
/* this packet contained a partial record, dump it */ |
236 |
if ( n != i) |
237 |
{ |
238 |
+ rr->length = 0; |
239 |
s->packet_length = 0; |
240 |
goto again; |
241 |
} |
242 |
@@ -594,6 +594,7 @@ again: |
243 |
bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); |
244 |
if ( bitmap == NULL) |
245 |
{ |
246 |
+ rr->length = 0; |
247 |
s->packet_length = 0; /* dump this record */ |
248 |
goto again; /* get another record */ |
249 |
} |
250 |
@@ -601,6 +602,7 @@ again: |
251 |
/* check whether this is a repeat, or aged record */ |
252 |
if ( ! dtls1_record_replay_check(s, bitmap, &(rr->seq_num))) |
253 |
{ |
254 |
+ rr->length = 0; |
255 |
s->packet_length=0; /* dump this record */ |
256 |
goto again; /* get another record */ |
257 |
} |
258 |
@@ -615,21 +617,22 @@ again: |
259 |
if (is_next_epoch) |
260 |
{ |
261 |
dtls1_record_bitmap_update(s, bitmap); |
262 |
- dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), rr->seq_num); |
263 |
+ dtls1_buffer_record(s, &(s->d1->unprocessed_rcds), &rr->seq_num); |
264 |
+ rr->length = 0; |
265 |
s->packet_length = 0; |
266 |
goto again; |
267 |
} |
268 |
|
269 |
- if ( ! dtls1_process_record(s)) |
270 |
- return(0); |
271 |
+ if (!dtls1_process_record(s)) |
272 |
+ { |
273 |
+ rr->length = 0; |
274 |
+ s->packet_length=0; /* dump this record */ |
275 |
+ goto again; /* get another record */ |
276 |
+ } |
277 |
|
278 |
dtls1_clear_timeouts(s); /* done waiting */ |
279 |
return(1); |
280 |
|
281 |
-f_err: |
282 |
- ssl3_send_alert(s,SSL3_AL_FATAL,al); |
283 |
-err: |
284 |
- return(0); |
285 |
} |
286 |
|
287 |
/* Return up to 'len' payload bytes received in 'type' records. |