CVE-2019-1547: research data and tooling
Creators
- 1. Tampere University
Description
This dataset and software tool are for reproducing the research results related to CVE-2019-1547, resulting from the manuscript "Certified Side Channels". The data was used to produce Figure 4 in the paper and is part of the remote timing attack data in Section 4.1.
Data description
The file timings.json
contains a single JSON array. Each entry is a dictionary representation of one digital signature. A description of the dictionary fields follows.
hash_function
: string denoting the hash function for the digital signature.hash
: the output of said hash function, i.e. hash of the message digitally signed.order
: the order of the generator.private_key
: the ECDSA private key.public_key
: the corresponding public key.sig_r
: ther
component of the ECDSA signature.sig_s
: thes
component of the ECDSA signature.sig_nonce
: the ground truth nonce generated during ECDSA signing.nonce_bits
: the ground truth number of bits in said nonce.latency
: the measured wall clock time (CPU clock cycles) to produce the digital signature.
Prerequisites
OpenSSL 1.1.1a, 1.1.1b, or 1.1.1.c.
sudo apt install python-ijson jq
Data setup
Extract the JSON:
tar xf timings.tar.xz
Key setup
Generate the public key (public.pem
here) from the provided private key (private.pem
here):
$ openssl pkey -in private.pem -pubout -out public.pem
Examine the keys if you want.
$ openssl pkey -in private.pem -text -noout
$ openssl pkey -in public.pem -text -noout -pubin
Example: Verify key material
$ grep --max-count=1 'private_key' timings.json
"private_key":"0x6b76cc816dce9a8ebc6ff190bcf0555310d1fb0824047f703f627f338bcf5435",
$ grep --max-count=1 'public_key' timings.json
"public_key":"0x04396d7ae480016df31f84f80439e320b0638e024014a5d8e14923eea76948afb25a321ccadabd8a4295a1e8823879b9b65369bd49d337086850b3c799c7352828",
$ openssl pkey -in private.pem -text -noout
Private-Key: (256 bit)
priv:
6b:76:cc:81:6d:ce:9a:8e:bc:6f:f1:90:bc:f0:55:
53:10:d1:fb:08:24:04:7f:70:3f:62:7f:33:8b:cf:
54:35
pub:
04:39:6d:7a:e4:80:01:6d:f3:1f:84:f8:04:39:e3:
20:b0:63:8e:02:40:14:a5:d8:e1:49:23:ee:a7:69:
48:af:b2:5a:32:1c:ca:da:bd:8a:42:95:a1:e8:82:
38:79:b9:b6:53:69:bd:49:d3:37:08:68:50:b3:c7:
99:c7:35:28:28
Field Type: prime-field
Prime:
00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
ff:ff:ff
A:
00:ff:ff:ff:ff:00:00:00:01:00:00:00:00:00:00:
00:00:00:00:00:00:ff:ff:ff:ff:ff:ff:ff:ff:ff:
ff:ff:fc
B:
5a:c6:35:d8:aa:3a:93:e7:b3:eb:bd:55:76:98:86:
bc:65:1d:06:b0:cc:53:b0:f6:3b:ce:3c:3e:27:d2:
60:4b
Generator (uncompressed):
04:6b:17:d1:f2:e1:2c:42:47:f8:bc:e6:e5:63:a4:
40:f2:77:03:7d:81:2d:eb:33:a0:f4:a1:39:45:d8:
98:c2:96:4f:e3:42:e2:fe:1a:7f:9b:8e:e7:eb:4a:
7c:0f:9e:16:2b:ce:33:57:6b:31:5e:ce:cb:b6:40:
68:37:bf:51:f5
Order:
00:ff:ff:ff:ff:00:00:00:00:ff:ff:ff:ff:ff:ff:
ff:ff:bc:e6:fa:ad:a7:17:9e:84:f3:b9:ca:c2:fc:
63:25:51
Cofactor: 0
Seed:
c4:9d:36:08:86:e7:04:93:6a:66:78:e1:13:9d:26:
b7:81:9f:7e:90
Three things to note in the output:
- The private key bytes match (
private_key
andpriv
byte strings are equal) - The public key bytes match (
public_key
andpub
byte strings are equal) - This is an explicit parameters key, with the
Cofactor
parameter missing or zero, as described in the manuscript.
Example: Extract a single entry
Here we use the python script pickone.py
to extract the entry at index 2 (starting from 0).
$ python2 pickone.py timings.json 2 | jq . > 2.json
$ cat 2.json
{
"public_key": "0x04396d7ae480016df31f84f80439e320b0638e024014a5d8e14923eea76948afb25a321ccadabd8a4295a1e8823879b9b65369bd49d337086850b3c799c7352828",
"private_key": "0x6b76cc816dce9a8ebc6ff190bcf0555310d1fb0824047f703f627f338bcf5435",
"hash": "0xf36d0481e14869fc558b39ae4c747bc6c089a0271b23cfd92bc0b8aa7ed2c3aa",
"latency": 21565213,
"nonce_bits": 253,
"sig_nonce": "0x1b88c7802ea000ccb21116575c38004579b55f1f9c4f81ed321896b1e1034237",
"hash_function": "sha256",
"sig_s": "0x8c83417891547224006723169de9745a81fa8de7176428e1cd8e6110408f45da",
"sig_r": "0xf922d9ba4f65d207300cc7eaaa15564e60a2b1f208d1389057ff1a1ec52dc653",
"order": "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551"
}
Example: Dump hash to binary file
Extract the hash
field from the target JSON and dump it as binary.
$ sed -n 's/^ "hash": "0x\(.*\)",$/\1/p' 2.json | xxd -r -p > 2.hash
$ xxd -g1 2.hash
00000000: f3 6d 04 81 e1 48 69 fc 55 8b 39 ae 4c 74 7b c6 .m...Hi.U.9.Lt{.
00000010: c0 89 a0 27 1b 23 cf d9 2b c0 b8 aa 7e d2 c3 aa ...'.#..+...~...
Note the xxd
output matches the hash
byte string from the target JSON.
Example: Dump signature to DER
The hex2der.sh
script takes as an argument the target JSON filename, and outputs the DER-encoded ECDSA signature to stdout by extracting the sig_r
and sig_s
fields from the target JSON.
$ ./hex2der.sh 2.json > 2.der
$ openssl asn1parse -in 2.der -inform DER
0:d=0 hl=2 l= 70 cons: SEQUENCE
2:d=1 hl=2 l= 33 prim: INTEGER :F922D9BA4F65D207300CC7EAAA15564E60A2B1F208D1389057FF1A1EC52DC653
37:d=1 hl=2 l= 33 prim: INTEGER :8C83417891547224006723169DE9745A81FA8DE7176428E1CD8E6110408F45DA
Note the asn1parse
output contains a sequence with two integers, matching the sig_r
and sig_s
fields from the target JSON.
Example: Verify the signature
We use pkeyutl
here to verify the raw hash directly, in contrast to dgst
that will only verify by recomputing the hash itself.
$ openssl pkeyutl -in 2.hash -inkey public.pem -pubin -verify -sigfile 2.der
Signature Verified Successfully
Note it fails for other hashes (messages), a fundamental security property for digital signatures:
$ dd if=/dev/urandom of=bad.hash bs=1 count=32
32+0 records in
32+0 records out
32 bytes copied, 0.00129336 s, 24.7 kB/s
$ openssl pkeyutl -in bad.hash -inkey public.pem -pubin -verify -sigfile 2.der
Signature Verification Failure
Example: Statistics
The stats.py
script shows how to extract the desired fields from the JSON. It computes the median latency over each nonce bit length.
$ python2 stats.py timings.json
Len Median
238 20592060
239 20251286
240 20706144
241 20658896
242 20820100
243 20762304
244 20907332
245 20973536
246 20972244
247 21057788
248 21115419
249 21157888
250 21210560
251 21266378
252 21322146
253 21370608
254 21425454
255 21479105
256 21532532
You can verify these medians are consistent with Figure 4 in the paper.
The stats.py
script can be easily modified for more advanced analysis.
Credits
Authors
- Cesar Pereida García (Tampere University, Tampere, Finland)
- Sohaib ul Hassan (Tampere University, Tampere, Finland)
- Iaroslav Gridin (Tampere University, Tampere, Finland)
- Nicola Tuveri (Tampere University, Tampere, Finland)
- Alejandro Cabrera Aldaya (Tampere University, Tampere, Finland)
- Billy Bob Brumley (Tampere University, Tampere, Finland)
Funding
This project has received funding from the European Research Council (ERC) under the European Union’s Horizon 2020 research and innovation programme (grant agreement No 804476).
License
This project is distributed under MIT license.
Files
README.md
Files
(144.9 MB)
Name | Size | Download all |
---|---|---|
md5:cb135cd4cf7ee4e99625b910b5c3f883
|
1.6 kB | Download |
md5:b6b6465a3dbce306eec3ad531e4e4504
|
1.2 kB | Download |
md5:2c230951aae87a34bb52e454851a46d1
|
1.6 kB | Download |
md5:6357a88e6c4d81e039e1c13198b2264e
|
472 Bytes | Download |
md5:33195a0552d962d815938e0fab23d1ae
|
7.6 kB | Preview Download |
md5:7da7d4470ef175f98e267a7d12b33cab
|
2.0 kB | Download |
md5:93aac2e7568710873db9e66ba2ac7f97
|
144.9 MB | Download |
Additional details
Related works
- Is cited by
- Conference paper: arXiv:1909.01785 (arXiv)