diff options
author | djm@openbsd.org <djm@openbsd.org> | 2016-07-08 03:44:42 +0000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2016-07-08 13:50:03 +1000 |
commit | 6d31193d0baa3da339c196ac49625b7ba1c2ecc7 (patch) | |
tree | 83c1b9c11099ff8577178f702f2cb34765229d9b /mac.c | |
parent | 71f5598f06941f645a451948c4a5125c83828e1c (diff) |
upstream commit
Improve crypto ordering for Encrypt-then-MAC (EtM) mode
MAC algorithms.
Previously we were computing the MAC, decrypting the packet and then
checking the MAC. This gave rise to the possibility of creating a
side-channel oracle in the decryption step, though no such oracle has
been identified.
This adds a mac_check() function that computes and checks the MAC in
one pass, and uses it to advance MAC checking for EtM algorithms to
before payload decryption.
Reported by Jean Paul Degabriele, Kenny Paterson, Torben Hansen and
Martin Albrecht. feedback and ok markus@
Upstream-ID: 1999bb67cab47dda5b10b80d8155fe83d4a1867b
Diffstat (limited to 'mac.c')
-rw-r--r-- | mac.c | 23 |
1 files changed, 21 insertions, 2 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: mac.c,v 1.32 2015/01/15 18:32:54 naddy Exp $ */ | 1 | /* $OpenBSD: mac.c,v 1.33 2016/07/08 03:44:42 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -167,7 +167,8 @@ mac_init(struct sshmac *mac) | |||
167 | } | 167 | } |
168 | 168 | ||
169 | int | 169 | int |
170 | mac_compute(struct sshmac *mac, u_int32_t seqno, const u_char *data, int datalen, | 170 | mac_compute(struct sshmac *mac, u_int32_t seqno, |
171 | const u_char *data, int datalen, | ||
171 | u_char *digest, size_t dlen) | 172 | u_char *digest, size_t dlen) |
172 | { | 173 | { |
173 | static union { | 174 | static union { |
@@ -211,6 +212,24 @@ mac_compute(struct sshmac *mac, u_int32_t seqno, const u_char *data, int datalen | |||
211 | return 0; | 212 | return 0; |
212 | } | 213 | } |
213 | 214 | ||
215 | int | ||
216 | mac_check(struct sshmac *mac, u_int32_t seqno, | ||
217 | const u_char *data, size_t dlen, | ||
218 | const u_char *theirmac, size_t mlen) | ||
219 | { | ||
220 | u_char ourmac[SSH_DIGEST_MAX_LENGTH]; | ||
221 | int r; | ||
222 | |||
223 | if (mac->mac_len > mlen) | ||
224 | return SSH_ERR_INVALID_ARGUMENT; | ||
225 | if ((r = mac_compute(mac, seqno, data, dlen, | ||
226 | ourmac, sizeof(ourmac))) != 0) | ||
227 | return r; | ||
228 | if (timingsafe_bcmp(ourmac, theirmac, mac->mac_len) != 0) | ||
229 | return SSH_ERR_MAC_INVALID; | ||
230 | return 0; | ||
231 | } | ||
232 | |||
214 | void | 233 | void |
215 | mac_clear(struct sshmac *mac) | 234 | mac_clear(struct sshmac *mac) |
216 | { | 235 | { |