Skip to content

Commit

Permalink
ipsec_xvalid: clear scratch SIMD registers after setting patterns
Browse files Browse the repository at this point in the history
The cross validation tool sets patterns in buffers to search
for leftover sensitive data in various memory areas.
These patterns might be stored in SIMD registers, which might
be stored in stack when submitting jobs or expanding keys.
To avoid this problem, scratch SIMD registers are cleared
before calling the Multi Buffer API.

Change-Id: I304c04e21feba48f91c8cf34e4d047e9be17289a
  • Loading branch information
pablodelara committed Oct 23, 2019
1 parent 35d856f commit 2fcad13
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 0 deletions.
34 changes: 34 additions & 0 deletions LibTestApp/ipsec_xvalid.c
Original file line number Diff line number Diff line change
Expand Up @@ -1133,6 +1133,29 @@ perform_safe_checks(MB_MGR *mgr, const enum arch_type_e arch,
return 0;
}

static void
clear_scratch_simd(const enum arch_type_e arch)
{
switch (arch) {
case ARCH_SSE:
case ARCH_AESNI_EMU:
clear_scratch_xmms_sse();
break;
case ARCH_AVX:
clear_scratch_xmms_avx();
break;
case ARCH_AVX2:
clear_scratch_ymms();
break;
case ARCH_AVX512:
clear_scratch_zmms();
break;
default:
fprintf(stderr, "Invalid architecture\n");
exit(EXIT_FAILURE);
}
}

/* Performs test using AES_HMAC or DOCSIS */
static int
do_test(MB_MGR *enc_mb_mgr, const enum arch_type_e enc_arch,
Expand Down Expand Up @@ -1203,6 +1226,9 @@ do_test(MB_MGR *enc_mb_mgr, const enum arch_type_e enc_arch,
if (safe_check) {
uint8_t *rsp_ptr;

/* Clear scratch registers before expanding keys to prevent
* other functions from storing sensitive data in stack */
clear_scratch_simd(enc_arch);
if (prepare_keys(enc_mb_mgr, enc_keys, key, params, 0) < 0)
goto exit;

Expand Down Expand Up @@ -1252,6 +1278,10 @@ do_test(MB_MGR *enc_mb_mgr, const enum arch_type_e enc_arch,
/* Randomize memory for input digest */
generate_random_buf(in_digest, tag_size);

/* Clear scratch registers before submitting job to prevent
* other functions from storing sensitive data in stack */
if (safe_check)
clear_scratch_simd(enc_arch);
job = IMB_SUBMIT_JOB(enc_mb_mgr);

if (!job)
Expand Down Expand Up @@ -1294,6 +1324,10 @@ do_test(MB_MGR *enc_mb_mgr, const enum arch_type_e enc_arch,
buf_size, tag_size, DECRYPT, dec_keys, iv) < 0)
goto exit;

/* Clear scratch registers before submitting job to prevent
* other functions from storing sensitive data in stack */
if (safe_check)
clear_scratch_simd(dec_arch);
job = IMB_SUBMIT_JOB(dec_mb_mgr);

if (!job)
Expand Down
115 changes: 115 additions & 0 deletions LibTestApp/misc.asm
Original file line number Diff line number Diff line change
Expand Up @@ -134,3 +134,118 @@ dump_zmms:
%endrep

ret

;
; This function clears all scratch XMM registers
;
; void clear_scratch_xmms_sse(void)
MKGLOBAL(clear_scratch_xmms_sse,function,internal)
clear_scratch_xmms_sse:

%ifdef LINUX
%assign i 0
%rep 16
pxor xmm %+ i, xmm %+ i
%assign i (i+1)
%endrep
; On Windows, XMM0-XMM5 registers are scratch registers
%else
%assign i 0
%rep 6
pxor xmm %+ i, xmm %+ i
%assign i (i+1)
%endrep
%endif ; LINUX

ret

;
; This function clears all scratch XMM registers
;
; It should be called before restoring the XMM registers
; for Windows (XMM6-XMM15)
;
; void clear_scratch_xmms_avx(void)
MKGLOBAL(clear_scratch_xmms_avx,function,internal)
clear_scratch_xmms_avx:

%ifdef LINUX
vzeroall
; On Windows, XMM0-XMM5 registers are scratch registers
%else
%assign i 0
%rep 6
vpxor xmm %+ i, xmm %+ i
%assign i (i+1)
%endrep
%endif ; LINUX

ret

;
; This function clears all scratch YMM registers
;
; It should be called before restoring the XMM registers
; for Windows (XMM6-XMM15)
;
; void clear_scratch_ymms(void)
MKGLOBAL(clear_scratch_ymms,function,internal)
clear_scratch_ymms:
; On Linux, all YMM registers are scratch registers
%ifdef LINUX
vzeroall
; On Windows, YMM0-YMM5 registers are scratch registers.
; YMM6-YMM15 upper 128 bits are scratch registers too, but
; the lower 128 bits are to be restored after calling these function
; which clears the upper bits too.
%else
%assign i 0
%rep 6
vpxor ymm %+ i, ymm %+ i
%assign i (i+1)
%endrep
%endif ; LINUX

ret

;
; This function clears all scratch ZMM registers
;
; It should be called before restoring the XMM registers
; for Windows (XMM6-XMM15). YMM registers are used
; on purpose, since XOR'ing YMM registers is faster
; than XOR'ing ZMM registers, and the operation clears
; also the upper 256 bits
;
; void clear_scratch_zmms(void)
MKGLOBAL(clear_scratch_zmms,function,internal)
clear_scratch_zmms:

; On Linux, all ZMM registers are scratch registers
%ifdef LINUX
vzeroall
;; vzeroall only clears the first 16 ZMM registers
%assign i 16
%rep 16
vpxorq ymm %+ i, ymm %+ i
%assign i (i+1)
%endrep
; On Windows, ZMM0-ZMM5 and ZMM16-ZMM31 registers are scratch registers.
; ZMM6-ZMM15 upper 384 bits are scratch registers too, but
; the lower 128 bits are to be restored after calling these function
; which clears the upper bits too.
%else
%assign i 0
%rep 6
vpxorq ymm %+ i, ymm %+ i
%assign i (i+1)
%endrep

%assign i 16
%rep 16
vpxorq ymm %+ i, ymm %+ i
%assign i (i+1)
%endrep
%endif ; LINUX

ret
6 changes: 6 additions & 0 deletions LibTestApp/misc.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,10 @@ void dump_xmms_avx(void);
void dump_ymms(void);
void dump_zmms(void);

/* Functions to clear all scratch SIMD registers */
void clear_scratch_xmms_sse(void);
void clear_scratch_xmms_avx(void);
void clear_scratch_ymms(void);
void clear_scratch_zmms(void);

#endif /* XVALIDAPP_MISC_H */

0 comments on commit 2fcad13

Please sign in to comment.