CVE-2020-12399: research data and tooling
Description
This dataset and software tools are for reproducing the research results related to CVE-2020-12399, resulting from the manuscript "Déjà vu: Side-channel analysis of Mozilla's NSS", to appear at ACM CCS 2020.
- The data is from a remote timing attack against the NSS v3.51 implementation of DSA signing.
- The client machine was a 3.1 GHz 64-bit Intel i5-2400 CPU (Sandy Bridge).
- The server machine was a Raspberry Pi 3 Model B plus board containing a 1.4 GHz 64-bit quad-core Cortex-A53 processor.
- The client and server were connected by a Cisco 9300 series enterprise switch over Gbit Ethernet.
- The data contains pow(2,18) samples.
- The data was used to produce Figure 1 in the paper and contains all the remote timing attack data from Section 4.
Data description
The file remote_timings.json
contains a single JSON array. Each entry is a dictionary representation of one digital signature. A description of the dictionary fields follows.
p
: prime (DSA parameter).q
: generator order (DSA parameter).g
: generator (DSA parameter).x
: the DSA private key.y
: the corresponding public key.r
: first component of the DSA signature.s
: second component of the DSA signature.k
: the ground truth nonce generated during DSA signing.k_len
: the ground truth number of bits in said nonce.msg
: message digitally signed.h
: SHA-256 hash of said message. (Truncated to the same bitlen as q.)id
: ignored.latency
: the measured wall clock time (CPU clock cycles) to produce the digital signature.
Prerequisites
sudo apt install openssl python3-ijson xxd jq
Data setup
Extract the JSON:
tar xf remote_timings_rpi.tar.gz
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
$ openssl pkey -in private.pem -text -noout
Private-Key: (2048 bit)
priv:
1f:87:68:eb:57:e1:f4:f1:29:a6:c8:ca:03:c8:db:
49:1d:8e:2b:81:bd:72:92:64:0c:1c:d6:6d
pub:
00:9d:fa:bc:47:00:cb:11:fa:51:45:c1:bd:b1:88:
2d:dd:a2:79:5b:c3:43:0a:af:bb:83:e2:d5:84:d1:
07:01:ab:f9:ae:76:2d:dd:f2:a5:75:f5:3e:94:4d:
3b:c6:f6:ce:17:c6:60:09:5b:49:3d:cb:a0:db:ec:
29:91:85:8b:c3:f5:6c:6a:3c:01:87:12:85:ae:fc:
9e:bf:67:81:1b:1d:b1:9d:12:bd:79:8c:54:08:48:
11:13:6d:ab:b0:16:ef:11:4a:27:a7:0a:80:b3:db:
72:c1:cc:1e:e8:4a:39:b7:00:ca:97:b7:3a:6e:e9:
25:22:2e:5c:57:ee:62:be:23:d0:5e:53:a3:9f:05:
d4:7d:7f:b5:b6:cb:4b:27:90:14:79:72:a5:43:97:
c6:6a:7d:f7:32:b3:67:58:90:fc:c3:65:34:57:89:
1b:43:28:68:43:24:12:5e:f1:43:76:3c:e9:bc:9c:
5d:7d:ae:d6:3a:31:32:ca:df:a4:07:88:a2:55:6e:
a4:8c:da:13:c8:30:b7:2a:1c:23:0f:32:da:9e:7f:
e1:f7:3d:2d:1c:58:f5:1d:f2:7d:fb:67:45:8d:dd:
84:eb:83:c4:b0:00:a6:c2:09:b0:48:48:f9:4e:a8:
d7:ab:e1:c6:e8:bf:5c:fa:e3:f2:cd:c6:f1:e7:f2:
2c:90
P:
00:e5:4e:f4:32:f8:4a:ec:28:3c:dd:32:a8:05:e3:
5a:fa:a5:81:47:98:d9:a7:94:ba:34:b0:f9:7b:20:
c5:fb:52:12:3e:82:d7:6e:6f:f5:50:be:5e:9f:df:
82:9b:4e:0c:9d:a2:9f:3f:0a:f3:72:c2:55:7c:46:
6e:fe:48:00:88:b6:4e:4f:9b:19:8c:98:3b:71:42:
56:d2:b4:1c:47:69:6e:fc:f0:e6:26:04:0e:e2:63:
ed:06:0f:fb:a8:a9:94:73:e1:41:e0:6b:5a:b4:d9:
86:cd:7b:46:d3:39:ba:18:13:da:f2:3a:7b:dc:41:
21:83:e8:0d:25:13:31:90:5d:bd:82:41:9b:ea:6b:
8a:ba:8a:48:b1:1d:d2:3d:5e:c4:1b:29:5e:7f:b6:
56:1b:e6:91:65:ec:84:82:c2:f6:a1:b0:14:1b:0b:
08:d8:2b:2a:06:17:d7:2a:9b:c3:aa:fb:28:26:14:
3f:5d:0a:48:1a:48:45:c0:fd:ea:ec:90:6c:ec:93:
c8:af:a3:31:4b:3a:d8:cd:20:ae:8f:14:58:26:49:
18:1f:7a:99:c9:da:c3:f0:76:b8:52:8d:eb:b2:e2:
98:6b:a5:47:15:c3:ff:c8:e7:6c:d3:db:c7:fb:4c:
36:3e:15:eb:45:e1:4a:5d:01:ed:3b:87:f7:69:c1:
31:59
Q:
00:ca:6d:df:fc:7b:96:2e:35:30:27:4f:1f:cf:57:
2f:e9:4c:40:97:53:a1:fa:d0:89:56:8d:2c:25
G:
43:26:04:66:b3:80:c3:3f:8d:f5:5a:29:79:58:7a:
0b:8c:72:b9:cb:23:61:5d:c1:45:c5:38:7f:33:4e:
93:63:75:8a:b0:44:61:8f:59:df:fd:2f:3f:1f:22:
73:66:ba:53:65:53:2a:57:5b:d9:40:34:be:4c:78:
22:4a:bf:94:5d:23:15:65:66:e1:1f:6b:93:12:00:
f0:ac:f5:64:0d:6d:6c:a3:eb:26:83:6d:68:95:e0:
2c:bf:75:62:fa:5f:95:0f:b0:40:68:ce:66:3b:58:
ed:c1:63:e3:d8:35:5c:cc:db:b8:12:e6:62:e4:63:
b6:29:e0:86:75:79:bc:95:27:74:d1:fd:94:b9:7f:
6e:57:b4:e5:39:a2:15:41:94:3f:47:90:43:a5:da:
dd:08:a4:92:c5:bf:ef:34:4e:2e:7e:82:5c:07:0e:
dc:5d:6b:79:10:04:53:cc:b2:8e:bd:65:61:80:49:
ad:c7:dd:5f:5a:9b:74:ae:bc:e0:49:f1:ad:4c:1e:
8f:4e:9d:39:e9:fe:57:4d:39:b7:ba:69:03:e3:7e:
4d:0d:9b:65:c3:55:77:ff:2c:86:27:21:c7:3e:60:
a3:23:a5:e8:7e:0d:29:15:1c:5e:04:91:91:25:03:
f3:97:77:6c:11:24:34:58:c9:ec:b7:ca:ce:74:cd:
a7
This shows the keys indeed match (JSON x,y
, above priv,pub
):
$ grep --max-count=1 '"x"' remote_timings.json
"x": "0x1F8768EB57E1F4F129A6C8CA03C8DB491D8E2B81BD7292640C1CD66D",
$ grep --max-count=1 '"y"' remote_timings.json
"y": "0x9DFABC4700CB11FA5145C1BDB1882DDDA2795BC3430AAFBB83E2D584D10701ABF9AE762DDDF2A575F53E944D3BC6F6CE17C660095B493DCBA0DBEC2991858BC3F56C6A3C01871285AEFC9EBF67811B1DB19D12BD798C54084811136DABB016EF114A27A70A80B3DB72C1CC1EE84A39B700CA97B73A6EE925222E5C57EE62BE23D05E53A39F05D47D7FB5B6CB4B2790147972A54397C66A7DF732B3675890FCC3653457891B4328684324125EF143763CE9BC9C5D7DAED63A3132CADFA40788A2556EA48CDA13C830B72A1C230F32DA9E7FE1F73D2D1C58F51DF27DFB67458DDD84EB83C4B000A6C209B04848F94EA8D7ABE1C6E8BF5CFAE3F2CDC6F1E7F22C90",
This shows the DSA parameters match (JSON p,q,g
, above P,Q,G
):
$ grep --max-count=1 '"p"' remote_timings.json
"p": "0xE54EF432F84AEC283CDD32A805E35AFAA5814798D9A794BA34B0F97B20C5FB52123E82D76E6FF550BE5E9FDF829B4E0C9DA29F3F0AF372C2557C466EFE480088B64E4F9B198C983B714256D2B41C47696EFCF0E626040EE263ED060FFBA8A99473E141E06B5AB4D986CD7B46D339BA1813DAF23A7BDC412183E80D251331905DBD82419BEA6B8ABA8A48B11DD23D5EC41B295E7FB6561BE69165EC8482C2F6A1B0141B0B08D82B2A0617D72A9BC3AAFB2826143F5D0A481A4845C0FDEAEC906CEC93C8AFA3314B3AD8CD20AE8F14582649181F7A99C9DAC3F076B8528DEBB2E2986BA54715C3FFC8E76CD3DBC7FB4C363E15EB45E14A5D01ED3B87F769C13159",
$ grep --max-count=1 '"q"' remote_timings.json
"q": "0xCA6DDFFC7B962E3530274F1FCF572FE94C409753A1FAD089568D2C25",
$ grep --max-count=1 '"g"' remote_timings.json
"g": "0x43260466B380C33F8DF55A2979587A0B8C72B9CB23615DC145C5387F334E9363758AB044618F59DFFD2F3F1F227366BA5365532A575BD94034BE4C78224ABF945D23156566E11F6B931200F0ACF5640D6D6CA3EB26836D6895E02CBF7562FA5F950FB04068CE663B58EDC163E3D8355CCCDBB812E662E463B629E0867579BC952774D1FD94B97F6E57B4E539A21541943F479043A5DADD08A492C5BFEF344E2E7E825C070EDC5D6B79100453CCB28EBD65618049ADC7DD5F5A9B74AEBCE049F1AD4C1E8F4E9D39E9FE574D39B7BA6903E37E4D0D9B65C35577FF2C862721C73E60A323A5E87E0D29151C5E0491912503F397776C11243458C9ECB7CACE74CDA7",
Example: Extract a single entry
Here we use the python script pickone.py
to extract the entry at index 2 (starting from 0).
$ python3 pickone.py remote_timings.json 2 | jq . > 2.json
$ cat 2.json
{
"latency": "399901598",
"y": "0x9DFABC4700CB11FA5145C1BDB1882DDDA2795BC3430AAFBB83E2D584D10701ABF9AE762DDDF2A575F53E944D3BC6F6CE17C660095B493DCBA0DBEC2991858BC3F56C6A3C01871285AEFC9EBF67811B1DB19D12BD798C54084811136DABB016EF114A27A70A80B3DB72C1CC1EE84A39B700CA97B73A6EE925222E5C57EE62BE23D05E53A39F05D47D7FB5B6CB4B2790147972A54397C66A7DF732B3675890FCC3653457891B4328684324125EF143763CE9BC9C5D7DAED63A3132CADFA40788A2556EA48CDA13C830B72A1C230F32DA9E7FE1F73D2D1C58F51DF27DFB67458DDD84EB83C4B000A6C209B04848F94EA8D7ABE1C6E8BF5CFAE3F2CDC6F1E7F22C90",
"g": "0x43260466B380C33F8DF55A2979587A0B8C72B9CB23615DC145C5387F334E9363758AB044618F59DFFD2F3F1F227366BA5365532A575BD94034BE4C78224ABF945D23156566E11F6B931200F0ACF5640D6D6CA3EB26836D6895E02CBF7562FA5F950FB04068CE663B58EDC163E3D8355CCCDBB812E662E463B629E0867579BC952774D1FD94B97F6E57B4E539A21541943F479043A5DADD08A492C5BFEF344E2E7E825C070EDC5D6B79100453CCB28EBD65618049ADC7DD5F5A9B74AEBCE049F1AD4C1E8F4E9D39E9FE574D39B7BA6903E37E4D0D9B65C35577FF2C862721C73E60A323A5E87E0D29151C5E0491912503F397776C11243458C9ECB7CACE74CDA7",
"h": "0xC7DEAC64C95157992CB0D77CF944CB107C756F3E30D1C49C0C48A6EA",
"k": "0x742A7562E2A192996440AE2A4FDF5D37E1A532E1E6A50BCA3964BBDA",
"q": "0xCA6DDFFC7B962E3530274F1FCF572FE94C409753A1FAD089568D2C25",
"p": "0xE54EF432F84AEC283CDD32A805E35AFAA5814798D9A794BA34B0F97B20C5FB52123E82D76E6FF550BE5E9FDF829B4E0C9DA29F3F0AF372C2557C466EFE480088B64E4F9B198C983B714256D2B41C47696EFCF0E626040EE263ED060FFBA8A99473E141E06B5AB4D986CD7B46D339BA1813DAF23A7BDC412183E80D251331905DBD82419BEA6B8ABA8A48B11DD23D5EC41B295E7FB6561BE69165EC8482C2F6A1B0141B0B08D82B2A0617D72A9BC3AAFB2826143F5D0A481A4845C0FDEAEC906CEC93C8AFA3314B3AD8CD20AE8F14582649181F7A99C9DAC3F076B8528DEBB2E2986BA54715C3FFC8E76CD3DBC7FB4C363E15EB45E14A5D01ED3B87F769C13159",
"s": "0x79FD73D901BB077D14334D8CC714804577515A1E0ADC9F995BB7534C",
"r": "0x61F949D772E22EA9EFBB36442BC229767B28BE2A8061FA7339AFDDC8",
"msg": "0x318198301A06092A864886F70D010903310D060B2A864886F70D0109100104301C06092A864886F70D010905310F170D3230303432343131333135375A302B060B2A864886F70D010910020C311C301A30183016041470AD64D33E65A855E6C332AA52736F71D58E7527302F06092A864886F70D0109043122042090C90BFC7A8C459EDB5AF58A8878EE826B6FD02A20E2BAAF2C73984FA380FDD2",
"x": "0x1F8768EB57E1F4F129A6C8CA03C8DB491D8E2B81BD7292640C1CD66D",
"id": "335451053151725",
"k_len": "223"
}
Example: Dump message to binary file
Extract the msg
field from the target JSON and dump it as binary.
$ sed -n 's/^ "msg": "0x\(.*\)",$/\1/p' 2.json | xxd -r -p > 2.msg
$ xxd -g1 2.msg
00000000: 31 81 98 30 1a 06 09 2a 86 48 86 f7 0d 01 09 03 1..0...*.H......
00000010: 31 0d 06 0b 2a 86 48 86 f7 0d 01 09 10 01 04 30 1...*.H........0
00000020: 1c 06 09 2a 86 48 86 f7 0d 01 09 05 31 0f 17 0d ...*.H......1...
00000030: 32 30 30 34 32 34 31 31 33 31 35 37 5a 30 2b 06 200424113157Z0+.
00000040: 0b 2a 86 48 86 f7 0d 01 09 10 02 0c 31 1c 30 1a .*.H........1.0.
00000050: 30 18 30 16 04 14 70 ad 64 d3 3e 65 a8 55 e6 c3 0.0...p.d.>e.U..
00000060: 32 aa 52 73 6f 71 d5 8e 75 27 30 2f 06 09 2a 86 2.Rsoq..u'0/..*.
00000070: 48 86 f7 0d 01 09 04 31 22 04 20 90 c9 0b fc 7a H......1". ....z
00000080: 8c 45 9e db 5a f5 8a 88 78 ee 82 6b 6f d0 2a 20 .E..Z...x..ko.*
00000090: e2 ba af 2c 73 98 4f a3 80 fd d2 ...,s.O....
Note the xxd
output matches the msg
byte string from the target JSON.
Example: Dump hash to binary file
Extract the h
field from the target JSON and dump it as binary.
$ sed -n 's/^ "h": "0x\(.*\)",$/\1/p' 2.json | xxd -r -p > 2.hash
$ xxd -g1 2.hash
00000000: c7 de ac 64 c9 51 57 99 2c b0 d7 7c f9 44 cb 10 ...d.QW.,..|.D..
00000010: 7c 75 6f 3e 30 d1 c4 9c 0c 48 a6 ea |uo>0....H..
Note the xxd
output matches the h
byte string from the target JSON.
Example: Hash is consistent
$ sha256sum 2.msg
c7deac64c95157992cb0d77cf944cb107c756f3e30d1c49c0c48a6ea809e6d58 2.msg
Note the first 28 bytes of sha256sum
output match the h
byte string from the target JSON. (DSA maps to GF(q) with truncation.)
Example: Dump signature to DER
The hex2der.sh
script takes as an argument the target JSON filename, and outputs the DER-encoded DSA signature to stdout by extracting the r
and 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= 60 cons: SEQUENCE
2:d=1 hl=2 l= 28 prim: INTEGER :61F949D772E22EA9EFBB36442BC229767B28BE2A8061FA7339AFDDC8
32:d=1 hl=2 l= 28 prim: INTEGER :79FD73D901BB077D14334D8CC714804577515A1E0ADC9F995BB7534C
Note the asn1parse
output contains a sequence with two integers, matching the r
and s
fields from the target JSON.
Example: Verify the signature (post-hash)
We use pkeyutl
here to verify the raw hash directly.
$ 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=28
28+0 records in
28+0 records out
28 bytes copied, 0.000647097 s, 43.3 kB/s
$ openssl pkeyutl -in bad.hash -inkey public.pem -pubin -verify -sigfile 2.der
Signature Verification Failure
Example: Verify the signature (pre-hash)
We use dgst
here to verify by recomputing the hash.
$ openssl dgst -sha256 -verify public.pem -signature 2.der 2.msg
Verified OK
Example: Message analysis
The msg
JSON field is an RFC 3161 Time Stamp Request. You can examine it:
$ openssl asn1parse -in 2.msg -inform DER
0:d=0 hl=3 l= 152 cons: SET
3:d=1 hl=2 l= 26 cons: SEQUENCE
5:d=2 hl=2 l= 9 prim: OBJECT :contentType
16:d=2 hl=2 l= 13 cons: SET
18:d=3 hl=2 l= 11 prim: OBJECT :id-smime-ct-TSTInfo
31:d=1 hl=2 l= 28 cons: SEQUENCE
33:d=2 hl=2 l= 9 prim: OBJECT :signingTime
44:d=2 hl=2 l= 15 cons: SET
46:d=3 hl=2 l= 13 prim: UTCTIME :200424113157Z
61:d=1 hl=2 l= 43 cons: SEQUENCE
63:d=2 hl=2 l= 11 prim: OBJECT :id-smime-aa-signingCertificate
76:d=2 hl=2 l= 28 cons: SET
78:d=3 hl=2 l= 26 cons: SEQUENCE
80:d=4 hl=2 l= 24 cons: SEQUENCE
82:d=5 hl=2 l= 22 cons: SEQUENCE
84:d=6 hl=2 l= 20 prim: OCTET STRING [HEX DUMP]:70AD64D33E65A855E6C332AA52736F71D58E7527
106:d=1 hl=2 l= 47 cons: SEQUENCE
108:d=2 hl=2 l= 9 prim: OBJECT :messageDigest
119:d=2 hl=2 l= 34 cons: SET
121:d=3 hl=2 l= 32 prim: OCTET STRING [HEX DUMP]:90C90BFC7A8C459EDB5AF58A8878EE826B6FD02A20E2BAAF2C73984FA380FDD2
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.
$ python3 stats.py remote_timings.json
Len Median
205 121.2
206 121.2
207 120.6
208 138.3
209 122.9
210 123.0
211 123.0
212 123.0
213 125.0
214 125.0
215 125.0
216 125.0
217 127.1
218 127.1
219 127.1
220 127.1
221 129.1
222 129.1
223 129.1
224 129.1
You can verify these medians are consistent with Figure 1 in the paper.
The stats.py
script can be easily modified for more advanced analysis.
Credits
Some parts borrowed from this artifact.
Authors
- Sohaib ul Hassan (Tampere University, Tampere, Finland)
- Iaroslav Gridin (Tampere University, Tampere, Finland)
- Ignacio M. Delgado-Lozano (Tampere University, Tampere, Finland)
- Cesar Pereida García (Tampere University, Tampere, Finland)
- Jesús-Javier Chi-Domínguez (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
(57.4 MB)
Name | Size | Download all |
---|---|---|
md5:d8e42219cd9098ac45d609b8b4d1142b
|
1.8 kB | Download |
md5:c3336167c97535efb87739e4e9f1a6df
|
1.4 kB | Download |
md5:9946de83f5ca475e97849aa51282321d
|
1.8 kB | Download |
md5:94d01431962592b511bc106377f4b294
|
879 Bytes | Download |
md5:e0f993ae357af907f71bdff439b8d116
|
15.6 kB | Preview Download |
md5:1c2eb4c8e6ae27d061ea00be6ae677bd
|
57.4 MB | Download |
md5:26e5c8ec8f62ca5d1095544fda78eeb6
|
2.2 kB | Download |