Sun Jun 14 23:20:15 2020 UTC ()
padlock(4): Don't use prev msg's last block as IV for next msg in CBC.

This violates the security contract of the CBC construction, which
requires that the IV be unpredictable in advance; an adaptive adversary
can exploit this to verify plaintext guesses.

XXX Compile-tested only.


(riastradh)
diff -r1.28 -r1.29 src/sys/arch/x86/x86/via_padlock.c

cvs diff -r1.28 -r1.29 src/sys/arch/x86/x86/via_padlock.c (expand / switch to unified diff)

--- src/sys/arch/x86/x86/via_padlock.c 2020/03/07 13:28:45 1.28
+++ src/sys/arch/x86/x86/via_padlock.c 2020/06/14 23:20:15 1.29
@@ -1,36 +1,36 @@ @@ -1,36 +1,36 @@
1/* $OpenBSD: via.c,v 1.8 2006/11/17 07:47:56 tom Exp $ */ 1/* $OpenBSD: via.c,v 1.8 2006/11/17 07:47:56 tom Exp $ */
2/* $NetBSD: via_padlock.c,v 1.28 2020/03/07 13:28:45 maya Exp $ */ 2/* $NetBSD: via_padlock.c,v 1.29 2020/06/14 23:20:15 riastradh Exp $ */
3 3
4/*- 4/*-
5 * Copyright (c) 2003 Jason Wright 5 * Copyright (c) 2003 Jason Wright
6 * Copyright (c) 2003, 2004 Theo de Raadt 6 * Copyright (c) 2003, 2004 Theo de Raadt
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Permission to use, copy, modify, and distribute this software for any 9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above 10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies. 11 * copyright notice and this permission notice appear in all copies.
12 * 12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 */ 20 */
21 21
22#include <sys/cdefs.h> 22#include <sys/cdefs.h>
23__KERNEL_RCSID(0, "$NetBSD: via_padlock.c,v 1.28 2020/03/07 13:28:45 maya Exp $"); 23__KERNEL_RCSID(0, "$NetBSD: via_padlock.c,v 1.29 2020/06/14 23:20:15 riastradh Exp $");
24 24
25#include <sys/param.h> 25#include <sys/param.h>
26#include <sys/systm.h> 26#include <sys/systm.h>
27#include <sys/signalvar.h> 27#include <sys/signalvar.h>
28#include <sys/kernel.h> 28#include <sys/kernel.h>
29#include <sys/device.h> 29#include <sys/device.h>
30#include <sys/module.h> 30#include <sys/module.h>
31#include <sys/malloc.h> 31#include <sys/malloc.h>
32#include <sys/mbuf.h> 32#include <sys/mbuf.h>
33#include <sys/cpu.h> 33#include <sys/cpu.h>
34 34
35#include <x86/specialreg.h> 35#include <x86/specialreg.h>
36 36
@@ -181,27 +181,26 @@ via_padlock_crypto_newsession(void *arg, @@ -181,27 +181,26 @@ via_padlock_crypto_newsession(void *arg,
181 case 192: 181 case 192:
182 cw0 = C3_CRYPT_CWLO_KEY192; 182 cw0 = C3_CRYPT_CWLO_KEY192;
183 break; 183 break;
184 case 256: 184 case 256:
185 cw0 = C3_CRYPT_CWLO_KEY256; 185 cw0 = C3_CRYPT_CWLO_KEY256;
186 break; 186 break;
187 default: 187 default:
188 return (EINVAL); 188 return (EINVAL);
189 } 189 }
190 cw0 |= C3_CRYPT_CWLO_ALG_AES | 190 cw0 |= C3_CRYPT_CWLO_ALG_AES |
191 C3_CRYPT_CWLO_KEYGEN_SW | 191 C3_CRYPT_CWLO_KEYGEN_SW |
192 C3_CRYPT_CWLO_NORMAL; 192 C3_CRYPT_CWLO_NORMAL;
193 193
194 cprng_fast(ses->ses_iv, sizeof(ses->ses_iv)); 
195 ses->ses_klen = c->cri_klen; 194 ses->ses_klen = c->cri_klen;
196 ses->ses_cw0 = cw0; 195 ses->ses_cw0 = cw0;
197 196
198 /* Build expanded keys for both directions */ 197 /* Build expanded keys for both directions */
199 rijndaelKeySetupEnc(ses->ses_ekey, c->cri_key, 198 rijndaelKeySetupEnc(ses->ses_ekey, c->cri_key,
200 c->cri_klen); 199 c->cri_klen);
201 rijndaelKeySetupDec(ses->ses_dkey, c->cri_key, 200 rijndaelKeySetupDec(ses->ses_dkey, c->cri_key,
202 c->cri_klen); 201 c->cri_klen);
203 for (i = 0; i < 4 * (RIJNDAEL_MAXNR + 1); i++) { 202 for (i = 0; i < 4 * (RIJNDAEL_MAXNR + 1); i++) {
204 ses->ses_ekey[i] = ntohl(ses->ses_ekey[i]); 203 ses->ses_ekey[i] = ntohl(ses->ses_ekey[i]);
205 ses->ses_dkey[i] = ntohl(ses->ses_dkey[i]); 204 ses->ses_dkey[i] = ntohl(ses->ses_dkey[i]);
206 } 205 }
207 206
@@ -374,27 +373,27 @@ via_padlock_crypto_encdec(struct cryptop @@ -374,27 +373,27 @@ via_padlock_crypto_encdec(struct cryptop
374 if ((crd->crd_len % 16) != 0) 373 if ((crd->crd_len % 16) != 0)
375 return (EINVAL); 374 return (EINVAL);
376 375
377 sc->op_buf = malloc(crd->crd_len, M_DEVBUF, M_NOWAIT); 376 sc->op_buf = malloc(crd->crd_len, M_DEVBUF, M_NOWAIT);
378 if (sc->op_buf == NULL) 377 if (sc->op_buf == NULL)
379 return (ENOMEM); 378 return (ENOMEM);
380 379
381 if (crd->crd_flags & CRD_F_ENCRYPT) { 380 if (crd->crd_flags & CRD_F_ENCRYPT) {
382 sc->op_cw[0] = ses->ses_cw0 | C3_CRYPT_CWLO_ENCRYPT; 381 sc->op_cw[0] = ses->ses_cw0 | C3_CRYPT_CWLO_ENCRYPT;
383 key = ses->ses_ekey; 382 key = ses->ses_ekey;
384 if (crd->crd_flags & CRD_F_IV_EXPLICIT) 383 if (crd->crd_flags & CRD_F_IV_EXPLICIT)
385 memcpy(sc->op_iv, crd->crd_iv, 16); 384 memcpy(sc->op_iv, crd->crd_iv, 16);
386 else 385 else
387 memcpy(sc->op_iv, ses->ses_iv, 16); 386 cprng_fast(sc->op_iv, 16);
388 387
389 if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) { 388 if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
390 if (crp->crp_flags & CRYPTO_F_IMBUF) 389 if (crp->crp_flags & CRYPTO_F_IMBUF)
391 m_copyback((struct mbuf *)crp->crp_buf, 390 m_copyback((struct mbuf *)crp->crp_buf,
392 crd->crd_inject, 16, sc->op_iv); 391 crd->crd_inject, 16, sc->op_iv);
393 else if (crp->crp_flags & CRYPTO_F_IOV) 392 else if (crp->crp_flags & CRYPTO_F_IOV)
394 cuio_copyback((struct uio *)crp->crp_buf, 393 cuio_copyback((struct uio *)crp->crp_buf,
395 crd->crd_inject, 16, sc->op_iv); 394 crd->crd_inject, 16, sc->op_iv);
396 else 395 else
397 memcpy((char *)crp->crp_buf + crd->crd_inject, 396 memcpy((char *)crp->crp_buf + crd->crd_inject,
398 sc->op_iv, 16); 397 sc->op_iv, 16);
399 } 398 }
400 } else { 399 } else {
@@ -429,41 +428,26 @@ via_padlock_crypto_encdec(struct cryptop @@ -429,41 +428,26 @@ via_padlock_crypto_encdec(struct cryptop
429 via_padlock_cbc(&sc->op_cw, sc->op_buf, sc->op_buf, key, 428 via_padlock_cbc(&sc->op_cw, sc->op_buf, sc->op_buf, key,
430 crd->crd_len / 16, sc->op_iv); 429 crd->crd_len / 16, sc->op_iv);
431 430
432 if (crp->crp_flags & CRYPTO_F_IMBUF) 431 if (crp->crp_flags & CRYPTO_F_IMBUF)
433 m_copyback((struct mbuf *)crp->crp_buf, 432 m_copyback((struct mbuf *)crp->crp_buf,
434 crd->crd_skip, crd->crd_len, sc->op_buf); 433 crd->crd_skip, crd->crd_len, sc->op_buf);
435 else if (crp->crp_flags & CRYPTO_F_IOV) 434 else if (crp->crp_flags & CRYPTO_F_IOV)
436 cuio_copyback((struct uio *)crp->crp_buf, 435 cuio_copyback((struct uio *)crp->crp_buf,
437 crd->crd_skip, crd->crd_len, sc->op_buf); 436 crd->crd_skip, crd->crd_len, sc->op_buf);
438 else 437 else
439 memcpy((char *)crp->crp_buf + crd->crd_skip, sc->op_buf, 438 memcpy((char *)crp->crp_buf + crd->crd_skip, sc->op_buf,
440 crd->crd_len); 439 crd->crd_len);
441 440
442 /* copy out last block for use as next session IV */ 
443 if (crd->crd_flags & CRD_F_ENCRYPT) { 
444 if (crp->crp_flags & CRYPTO_F_IMBUF) 
445 m_copydata((struct mbuf *)crp->crp_buf, 
446 crd->crd_skip + crd->crd_len - 16, 16, 
447 ses->ses_iv); 
448 else if (crp->crp_flags & CRYPTO_F_IOV) 
449 cuio_copydata((struct uio *)crp->crp_buf, 
450 crd->crd_skip + crd->crd_len - 16, 16, 
451 ses->ses_iv); 
452 else 
453 memcpy(ses->ses_iv, (char *)crp->crp_buf + 
454 crd->crd_skip + crd->crd_len - 16, 16); 
455 } 
456 
457 if (sc->op_buf != NULL) { 441 if (sc->op_buf != NULL) {
458 memset(sc->op_buf, 0, crd->crd_len); 442 memset(sc->op_buf, 0, crd->crd_len);
459 free(sc->op_buf, M_DEVBUF); 443 free(sc->op_buf, M_DEVBUF);
460 sc->op_buf = NULL; 444 sc->op_buf = NULL;
461 } 445 }
462 446
463 return 0; 447 return 0;
464} 448}
465 449
466int 450int
467via_padlock_crypto_process(void *arg, struct cryptop *crp, int hint) 451via_padlock_crypto_process(void *arg, struct cryptop *crp, int hint)
468{ 452{
469 struct via_padlock_softc *sc = arg; 453 struct via_padlock_softc *sc = arg;