Actions
  • shareshare
  • link
  • cite
  • add
add
Research data . Dataset . 2020

CVE-2020-12399: research data and tooling

ul Hassan, Sohaib; Gridin, Iaroslav; Delgado-Lozano, Ignacio M.; Pereida García, Cesar; Chi-Domínguez, Jesús-Javier; Aldaya, Alejandro Cabrera; Brumley, Billy Bob;
Open Access   English  
Published: 13 Aug 2020
Publisher: Zenodo
Abstract
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.
Subjects

side-channel analysis, applied cryptography, Digital Signature Algorithm (DSA), Network Security Services (NSS), timing attacks, Mozilla, Firefox, CVE-2020-12399

Funded by
EC| SCARE
Project
SCARE
Side-Channel Aware Engineering
  • Funder: European Commission (EC)
  • Project Code: 804476
  • Funding stream: H2020 | ERC | ERC-STG
Download from
lock_open