File: generate_pq_hybrid_tls13_handshake_kats.py

package info (click to toggle)
aws-crt-python 0.24.0%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 75,932 kB
  • sloc: ansic: 418,984; python: 23,626; makefile: 6,035; sh: 4,075; ruby: 208; java: 82; perl: 73; cpp: 25; xml: 11
file content (304 lines) | stat: -rwxr-xr-x 16,080 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
import hashlib
import hmac

# The PEM-encoded ECC private keys were used to generate the ECC shared secrets
# are located in in s2n/tests/unit/s2n_tls13_hybrid_shared_secret_test.c with
# names like "CLIENT_{CURVE}_PRIV_KEY" and "SERVER_{CURVE}_PRIV_KEY".

# We aren't really concerned with the actual bytes of the transcript, only the hash.
# The transcript_hash values were calculated as:
# hashlib.sha256(b"client_hello || server_hello").hexdigest()
# hashlib.sha384(b"client_hello || server_hello").hexdigest()
# The string "client_hello || server_hello" is used in s2n/tests/unit/s2n_tls13_hybrid_shared_secret_test.c.

# The PQ shared secrets come from the first test vector in the corresponding NIST KAT.
input_vectors = [
    {
        "group_name": "x25519_sikep434r2",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "35F7F8FF388714DEDC41F139078CEDC9",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "x25519_sikep434r2",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "35F7F8FF388714DEDC41F139078CEDC9",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "secp256r1_sikep434r2",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "35F7F8FF388714DEDC41F139078CEDC9",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "secp256r1_sikep434r2",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "35F7F8FF388714DEDC41F139078CEDC9",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "x25519_bike1l1r2",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "C1C96E2B8B1D23E52F02AD3A766A75ADBEDF7BA1558B94412B4AB534EEDBDE36",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "x25519_bike1l1r2",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "C1C96E2B8B1D23E52F02AD3A766A75ADBEDF7BA1558B94412B4AB534EEDBDE36",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "secp256r1_bike1l1r2",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "C1C96E2B8B1D23E52F02AD3A766A75ADBEDF7BA1558B94412B4AB534EEDBDE36",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "secp256r1_bike1l1r2",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "C1C96E2B8B1D23E52F02AD3A766A75ADBEDF7BA1558B94412B4AB534EEDBDE36",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "x25519_kyber512r2",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "D0FF6083EE6E516C10AECB53DB05426C382A1A75F3E943C9F469A060C634EF4E",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "x25519_kyber512r2",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "D0FF6083EE6E516C10AECB53DB05426C382A1A75F3E943C9F469A060C634EF4E",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "secp256r1_kyber512r2",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "D0FF6083EE6E516C10AECB53DB05426C382A1A75F3E943C9F469A060C634EF4E",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "secp256r1_kyber512r2",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "D0FF6083EE6E516C10AECB53DB05426C382A1A75F3E943C9F469A060C634EF4E",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "x25519_kyber512r3",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "0A6925676F24B22C286F4C81A4224CEC506C9B257D480E02E3B49F44CAA3237F",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "x25519_kyber512r3",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "0A6925676F24B22C286F4C81A4224CEC506C9B257D480E02E3B49F44CAA3237F",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },    {
        "group_name": "secp256r1_kyber512r3",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "0A6925676F24B22C286F4C81A4224CEC506C9B257D480E02E3B49F44CAA3237F",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "secp256r1_kyber512r3",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "0A6925676F24B22C286F4C81A4224CEC506C9B257D480E02E3B49F44CAA3237F",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "x25519_bikel1r3",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "1A88B3A458EE42906A5FD423817E043532579C4F79518A81213DC91D0F2FCEA9",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "x25519_bikel1r3",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "1A88B3A458EE42906A5FD423817E043532579C4F79518A81213DC91D0F2FCEA9",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "secp256r1_bikel1r3",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "1A88B3A458EE42906A5FD423817E043532579C4F79518A81213DC91D0F2FCEA9",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "secp256r1_bikel1r3",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "1A88B3A458EE42906A5FD423817E043532579C4F79518A81213DC91D0F2FCEA9",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "x25519_kyber768r3",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "914CB67FE5C38E73BF74181C0AC50428DEDF7750A98058F7D536708774535B29",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "x25519_kyber768r3",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "914CB67FE5C38E73BF74181C0AC50428DEDF7750A98058F7D536708774535B29",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "secp256r1_kyber768r3",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "914CB67FE5C38E73BF74181C0AC50428DEDF7750A98058F7D536708774535B29",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "secp256r1_kyber768r3",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "914CB67FE5C38E73BF74181C0AC50428DEDF7750A98058F7D536708774535B29",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "secp384r1_kyber768r3",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "b72536062cd8e8eced91046e33413b027cabde0576747aa47863b8dcb914100585c600fafc8ff4927a34abb0aa6b3b68",
        "pq_shared_secret": "914CB67FE5C38E73BF74181C0AC50428DEDF7750A98058F7D536708774535B29",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "secp384r1_kyber768r3",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "b72536062cd8e8eced91046e33413b027cabde0576747aa47863b8dcb914100585c600fafc8ff4927a34abb0aa6b3b68",
        "pq_shared_secret": "914CB67FE5C38E73BF74181C0AC50428DEDF7750A98058F7D536708774535B29",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "secp521r1_kyber1024r3",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "009643bb20199e8f408b7c19bb98d1d19f0cef9104e2ec790c398c6abe7dc5cf47afb96de70aa14c86bc546a12f9ea3abbf2eec399b4d586083114cbc37f53ed2d8b",
        "pq_shared_secret": "B10F7394926AD3B49C5D62D5AEB531D5757538BCC0DA9E550D438F1B61BD7419",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "secp521r1_kyber1024r3",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "009643bb20199e8f408b7c19bb98d1d19f0cef9104e2ec790c398c6abe7dc5cf47afb96de70aa14c86bc546a12f9ea3abbf2eec399b4d586083114cbc37f53ed2d8b",
        "pq_shared_secret": "B10F7394926AD3B49C5D62D5AEB531D5757538BCC0DA9E550D438F1B61BD7419",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "X25519MLKEM768",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "B408D5D115713F0A93047DBBEA832E4340787686D59A9A2D106BD662BA0AA035",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "X25519MLKEM768",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "519be87fa0599077e5673d6f2d910aa150d7fef783c5e1491961fdf63b255910",
        "pq_shared_secret": "B408D5D115713F0A93047DBBEA832E4340787686D59A9A2D106BD662BA0AA035",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
    {
        "group_name": "SecP256r1MLKEM768",
        "cipher_suite": "TLS_AES_128_GCM_SHA256",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "B408D5D115713F0A93047DBBEA832E4340787686D59A9A2D106BD662BA0AA035",
        "transcript_hash": "f5f7f7867668be4b792159d4d194a03ec5cfa238b6409b5ca2ddccfddcc92a2b",
    },
    {
        "group_name": "SecP256r1MLKEM768",
        "cipher_suite": "TLS_AES_256_GCM_SHA384",
        "ec_shared_secret": "9348e27655539e08fffe46b35f863dd634e7437cc6bc11c7d329ef5484ec3b60",
        "pq_shared_secret": "B408D5D115713F0A93047DBBEA832E4340787686D59A9A2D106BD662BA0AA035",
        "transcript_hash": "35412cebcf35cb8a7af8f78278a486fc798f8702eaebd067c97acb27bffe13524d8426a4ed57956b4fd0ffdc4c90be52",
    },
]


def hkdf_extract(key: bytes, info: bytes, hash_alg: str):
    return hmac.new(key, info, hash_alg).digest()


def hkdf_expand_label(key: bytes, label: str, context: bytes, hash_alg: str):
    label_arr = [0, hashlib.new(hash_alg).digest_size, len("tls13 ") + len(label)]
    for c in "tls13 ":
        label_arr.append(ord(c))

    for c in label:
        label_arr.append(ord(c))

    label_arr.append(len(context))

    for c in context:
        label_arr.append(c)

    return hkdf_extract(key, bytearray(label_arr) + bytes([1]), hash_alg)


def compute_secrets(input_vector: dict):
    shared_secret = bytes.fromhex(input_vector["ec_shared_secret"] + input_vector["pq_shared_secret"])
    if (input_vector["group_name"] == "X25519MLKEM768"):
        shared_secret = bytes.fromhex(input_vector["pq_shared_secret"] + input_vector["ec_shared_secret"])

    hash_alg = input_vector["cipher_suite"].split("_")[-1].lower()
    zeros = bytearray([0] * hashlib.new(hash_alg).digest_size)
    transcript_hash = bytes.fromhex(input_vector["transcript_hash"])

    h = hashlib.new(hash_alg)
    h.update(b"")
    empty_hash = h.digest()

    secrets = {"early_secret": hkdf_extract(zeros, zeros, hash_alg)}
    secrets["derived_secret"] = hkdf_expand_label(secrets["early_secret"], "derived", empty_hash, hash_alg)
    secrets["handshake_secret"] = hkdf_extract(secrets["derived_secret"], shared_secret, hash_alg)
    secrets["client_traffic_secret"] = hkdf_expand_label(
        secrets["handshake_secret"], "c hs traffic", transcript_hash, hash_alg)
    secrets["server_traffic_secret"] = hkdf_expand_label(
        secrets["handshake_secret"], "s hs traffic", transcript_hash, hash_alg)

    return secrets


def main():
    output = ""

    for input_vector in input_vectors:
        secrets = compute_secrets(input_vector)

        for input_key, input_value in input_vector.items():
            output += input_key + " = " + input_value + "\n"

        for secret_name, secret_bytes in secrets.items():
            output += secret_name + " = " + secret_bytes.hex() + "\n"

        output += "\n"

    print(output)


if __name__ == '__main__':
    main()