-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Description
Test coverage for cryptographic assembly is worthless, because branches are intentionally avoided for constant timedness, and control flow and edge cases are hidden with CMOV and ADC instructions. A few years ago I tried dynamic instrumentation to observe flag states, but it quickly turned unwidely, and it's not portable.
Mutation testing provides effectively a coverage replacement: if we mutate a CMOV first to a MOV, and then to a NOP, and tests fail in both cases, it means we are covering both "branches".
Applying mutations to the assembler input is difficult due to macro expansion, so it'd be best to have assembler support.
I propose adding a -mutlist
flag which prints an instruction listing to stderr in format asm: mutlist: FILEPATH:LINE: PC INSTR
with virtual PCs (the potential targets) and a mutually exclusive -mut
flag which accepts a mutation in the format FILEPATH:PC=INSTR[;INSTR]
.
$ go test crypto/ed25519 -asmflags=crypto/internal/fips140/edwards25519/field=-mutlist -c
# crypto/internal/fips140/edwards25519/field
asm: mutlist: $GOROOT/src/crypto/internal/fips140/edwards25519/field/fe_amd64.s:8: 00001 TEXT crypto/internal/fips140/edwards25519/field.feMul(SB), NOSPLIT, $0-24
[...]
asm: mutlist: $GOROOT/src/crypto/internal/fips140/edwards25519/field/fe_amd64.s:23: 00012 ADDQ AX, DI
asm: mutlist: $GOROOT/src/crypto/internal/fips140/edwards25519/field/fe_amd64.s:24: 00013 ADCQ DX, SI
asm: mutlist: $GOROOT/src/crypto/internal/fips140/edwards25519/field/fe_amd64.s:27: 00014 MOVQ 16(CX), DX
[...]
$ go test crypto/ed25519 -asmflags=crypto/internal/fips140/edwards25519/field='"-mut=$GOROOT/src/crypto/internal/fips140/edwards25519/field/fe_amd64.s:13=STC;ADCQ DX, SI"'
--- FAIL: TestGenerateKey (0.00s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered, repanicked]
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x5a900de]
The PCs need to be virtual to avoid having to recompute them after inserting/mutating instructions.
There is an implementation in CL 665375, and a mutation test framework that uses it in CL 666395. I wrote more about the use case here.
/cc @golang/compiler
Metadata
Metadata
Assignees
Labels
Type
Projects
Status