File: test_rsa.py

package info (click to toggle)
python-yubihsm 3.1.1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 452 kB
  • sloc: python: 4,882; makefile: 4
file content (389 lines) | stat: -rw-r--r-- 20,911 bytes parent folder | download | duplicates (3)
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
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
# Copyright 2016-2018 Yubico AB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from yubihsm.defs import ALGORITHM, CAPABILITY, ERROR
from yubihsm.objects import AsymmetricKey
from yubihsm.exceptions import YubiHsmDeviceError

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from binascii import a2b_hex
import os
import pytest


RSA_SIZES = [
    2048,
    3072,
    4096,
]


@pytest.mark.parametrize(
    "hashtype",
    [
        hashes.SHA256,
        hashes.SHA384,
        hashes.SHA512,
    ],
)
@pytest.mark.parametrize("keysize", RSA_SIZES)
def test_rsa_pkcs1v1_5_sign(session, keysize, hashtype):
    key = rsa.generate_private_key(
        public_exponent=0x10001, key_size=keysize, backend=default_backend()
    )

    asymkey = AsymmetricKey.put(
        session, 0, "RSA PKCS#1v1.5 Sign", 0xFFFF, CAPABILITY.SIGN_PKCS, key
    )

    data = os.urandom(64)
    resp = asymkey.sign_pkcs1v1_5(data, hash=hashtype())

    key.public_key().verify(resp, data, padding.PKCS1v15(), hashtype())

    asymkey.delete()


@pytest.mark.parametrize("keysize", RSA_SIZES)
def test_rsa_pkcs1v1_5_decrypt(session, keysize):
    key = rsa.generate_private_key(
        public_exponent=0x10001, key_size=keysize, backend=default_backend()
    )

    asymkey = AsymmetricKey.put(
        session,
        0,
        "RSA PKCS#1v1.5 Decrypt",
        0xFFFF,
        CAPABILITY.DECRYPT_PKCS,
        key,
    )

    message = os.urandom(64)
    data = key.public_key().encrypt(message, padding.PKCS1v15())

    resp = asymkey.decrypt_pkcs1v1_5(data)
    assert message == resp

    asymkey.delete()


def test_rsa_pkcs1_decrypt_errors(session):
    rawmessages = [
        # no actual padding bytes:
        b"\x00\x02\x00" + b"\xc3" * 236 + b"\x00",
        # first byte != 0x00:
        b"\x01\x02" + b"\xc3" * 237 + b"\x00",
        # second byte != 0x02:
        b"\x00\x01" + b"\xc3" * 237 + b"\x00",
        # only 7 bytes of padding:
        b"\x00\x02" + b"\xc3" * 7 + b"\x00" + b"\x3c" * 246,
    ]

    rsakey = rsa.generate_private_key(
        public_exponent=0x10001, key_size=2048, backend=default_backend()
    )

    key = AsymmetricKey.put(
        session, 0, "pkcs1 test", 0xFFFF, CAPABILITY.DECRYPT_PKCS, rsakey
    )

    numbers = key.get_public_key().public_numbers()

    for m in rawmessages:
        error = ERROR.OK
        m = m.ljust(256, b"\xc3")
        m_int = int.from_bytes(m, "big")
        enc = pow(m_int, numbers.e, numbers.n)
        try:
            key.decrypt_pkcs1v1_5(int.to_bytes(enc, 256, "big"))
        except YubiHsmDeviceError as e:
            error = e.code
        assert error == ERROR.INVALID_DATA

    key.delete()


@pytest.mark.parametrize(
    "hashtype, mgf1hash",
    [
        (hashes.SHA256, hashes.SHA256),
        (hashes.SHA384, hashes.SHA384),
        (hashes.SHA512, hashes.SHA512),
        (hashes.SHA256, hashes.SHA1),
    ],
)
@pytest.mark.parametrize("keysize", RSA_SIZES)
def test_rsa_pss_sign(session, keysize, hashtype, mgf1hash):
    key = rsa.generate_private_key(
        public_exponent=0x10001, key_size=keysize, backend=default_backend()
    )

    asymkey = AsymmetricKey.put(
        session, 0, "RSA PSS Sign", 0xFFFF, CAPABILITY.SIGN_PSS, key
    )

    # No salt
    data = os.urandom(64)
    resp = asymkey.sign_pss(data, 0, hash=hashtype(), mgf_hash=mgf1hash())

    key.public_key().verify(
        resp, data, padding.PSS(padding.MGF1(mgf1hash()), 0), hashtype()
    )

    # Max - len salt
    saltlen = keysize // 8 - hashtype.digest_size - 2
    data = os.urandom(64)
    resp = asymkey.sign_pss(data, saltlen, hash=hashtype(), mgf_hash=mgf1hash())

    key.public_key().verify(
        resp,
        data,
        padding.PSS(padding.MGF1(mgf1hash()), padding.PSS.MAX_LENGTH),
        hashtype(),
    )

    asymkey.delete()


@pytest.mark.parametrize(
    "algorithm",
    [
        ALGORITHM.RSA_2048,
        ALGORITHM.RSA_3072,
        ALGORITHM.RSA_4096,
    ],
)
def test_generate_rsa_sign(session, algorithm):
    asymkey = AsymmetricKey.generate(
        session, 0, "Generate RSA Sign", 0xFFFF, CAPABILITY.SIGN_PKCS, algorithm
    )

    pub = asymkey.get_public_key()

    data = os.urandom(64)
    resp = asymkey.sign_pkcs1v1_5(data)

    pub.verify(resp, data, padding.PKCS1v15(), hashes.SHA256())

    asymkey.delete()


@pytest.mark.parametrize("keysize", RSA_SIZES)
def test_rsa_get_public_key(session, keysize):
    key = rsa.generate_private_key(
        public_exponent=0x10001, key_size=keysize, backend=default_backend()
    )

    asymkey = AsymmetricKey.put(
        session, 0, "Pubkey RSA", 0xFFFF, CAPABILITY.SIGN_PKCS, key
    )

    pub = asymkey.get_public_key()
    assert pub.public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo,
    ) == key.public_key().public_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PublicFormat.SubjectPublicKeyInfo,
    )

    data = os.urandom(64)
    resp = asymkey.sign_pkcs1v1_5(data)

    pub.verify(resp, data, padding.PKCS1v15(), hashes.SHA256())

    asymkey.delete()


def test_oaep_double0(session):
    data = a2b_hex(
        "77294f3a4f5cfc921d9255a6895f8d2397e7d312e1b10b41c88b025748f0b6d4c41c4bdc6309388648a3b7a07112a11f831d9d6e1af1408fae875be2868bc4d0"  # noqa: E501
    )
    # this ciphertext is special as it decrypts to a valid plaintext
    # starting with 0000
    ciphertext = a2b_hex(
        "add1fd0bc2e9439a76c53fa4655e4bef77394dee407903604d665ba0e506334ddffc689e3bec658fc15c80c70ffddb8a8ce578d441926106316067a8c5e8b5f2655d035eff1525cf697720baf510af722d14539ccaf605785a9f4cfd284e4b496c54684a0c72fae522be186aedcedf47da63408065345180e30d7cb003cd64b5ce508ea029999ad695f1f2464fb659db5c2779631f1c27d650bc8b7ae23048b8dc1d51ad9623a4af0f7363f74eed0e16d947322d1a3a76ef8dbdf9c0258f393c0f2d7ebaccfcc116f759f0e9077387de74b1cb82851e1ded0128e48bbde389bd407cf8339752b9c070bf22ad64eaa12ee996f474a6412f7642aa0fa66873b5d2"  # noqa: E501
    )

    h = hashes.SHA1()
    rsapem = b"""
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA7mKlVPrZdxLkYrfGESb3KI4UbWKaKOfX49LqZ2pUypF13VRi
yqfpBbjAJztEy8BvOgbIEJgDtRVyUHCO+pfs6uVakYEcbLZzP92iZaFTwa9//B+P
Hq+vtNejdO5Zsqd1s11bCPy6vpPXeMPbbT5s9gR7ENGdNwUkusVRtQweJAd5icVU
edewI/4npIZG7To0iKUS4OvuqKWi/ms9fpi5l5BeJkok+5P7nQlmE5H5P+MuHUaC
KHPdzbfaqIYof11XhsUYzgvEZnhz/YPwDiMiLXpZD0kT7azZWjz38rmWCz0tdh7a
Cs/Lu1n17KrtT62kXYeO1Ni5Osy43xEHcqp5WQIDAQABAoIBAHrv+J+4tknIPmwC
pmzWEYSisTowLZyG5Dmj3irzFUNafNRl3oTwzyWaP857rGD/ntzn/mlAXDkZFFkT
k0j87Lu/CFQdp5ERDqKTJFsRNeafIXvesqp6pDy5MJzvBucxoWuc64PZAl2iVO78
4r6WAQ9nBCiKUW+8gVKozBh4ZVriWRYhe1JD06OVrOxws2Aql8/3BooO14f0DeSe
6tgn49d3c6/lrFe/vB+46kDg4FNxeTozGgIcI6siVAFEaJkBU629SEGLJW1O1Zcx
tL41xK27S/BW47sSE91D7TT/0DYH7c1KNNx4IRx8B+AHo/lkyCawVUVmeYPrjC90
oGe27gECgYEA/Pkk9p0+t9ir6gUibkh1XoAVzryPnMCeCXenpTvFKjfOXdr5Sy2w
ZSYGJXcUm82G0XRB+WWyTtFvPUYCt7gJ3ncqrVSAa2LhgWowk0CpyOtm6isrRWrh
3wXj4mRzZuIe0XNnS/4gb/1+8I826r4CwOWrxUASP8bYTLB9nkglK/kCgYEA8TzR
np/2lyJVbuqAMOymel0ZUEh+yWEOif5nQGely6QVmUmAuCH+pP8pmCCreAuu/mQ9
U1obXMmr5D0rH7jA4z8DAeGXSvPVN7MJlpS1HoPGzDnKuuDad8/rJUXyKOACYXw5
xeXtQnf+5AHC0G8IFmru1G4C6UsyRkG/gpVPUGECgYEA7OxeXQZKTh8Ea2mhpI4C
Np5ZTkU1b4bKvG0vOsZu0ypvAWHrJyjEUwc4rHAJgh4MTTDH9U70n3Lw7v8Z3nzj
6VHMS4efunNiZjVRByiBm2Y0/c2uehYvMxQuKMMRfeL7IAkoTnjUYm6VK7HFqjaJ
F6ZCqLtoHAkcXT7Sd6J0BekCgYEAy1Lshprils2MXljtxM6hHj87p6wCmK7iNzKi
SelSF0psHe+Sux+D5gNeRmc6vopyat2HxqoKp/EenNdlcm4gvSgN29cM0lKjYjfX
nAAoi9ibhOQs18fOuu8WjSrgCM2NlCbE9uRtTfmfbwOA9HawxVxJgehbMdB8RjUC
OgioeeECgYBpGDz7CkblZQl8YXcOqFh9Y40ePG467gIaEesbiOIUVsN/J9Vkdy/U
qMS+DogAW9kGj5MA/L1EQxpsZDRZSH15AM1FXeX5cjItOWkg5LzfTwqA29xaIC97
4ddiJOH50Tqy7YRs40IxF+995AgMq4PvP1K+SlV4hQ6W17JsT2UsBg==
-----END RSA PRIVATE KEY-----
"""
    key = serialization.load_pem_private_key(
        rsapem, password=None, backend=default_backend()
    )
    asymkey = AsymmetricKey.put(
        session, 0, "OAEP RSA Decrypt", 0xFFFF, CAPABILITY.ALL, key
    )

    plain = key.decrypt(
        ciphertext,
        padding.OAEP(mgf=padding.MGF1(algorithm=h), algorithm=h, label=None),
    )

    assert plain == data
    dec = asymkey.decrypt_oaep(ciphertext, hash=h, mgf_hash=h)
    assert dec == data
    asymkey.delete()


@pytest.mark.parametrize(
    "hashtype, mgf1hash",
    [
        (hashes.SHA1, hashes.SHA1),
        (hashes.SHA256, hashes.SHA256),
        (hashes.SHA384, hashes.SHA384),
        (hashes.SHA512, hashes.SHA512),
        (hashes.SHA256, hashes.SHA1),
    ],
)
@pytest.mark.parametrize("keysize", RSA_SIZES)
def test_rsa_oaep_decrypt(session, keysize, hashtype, mgf1hash):
    key = rsa.generate_private_key(
        public_exponent=0x10001, key_size=keysize, backend=default_backend()
    )

    asymkey = AsymmetricKey.put(
        session, 0, "OAEP RSA Decrypt", 0xFFFF, CAPABILITY.DECRYPT_OAEP, key
    )

    data = os.urandom(64)
    ciphertext = key.public_key().encrypt(
        data,
        padding.OAEP(
            mgf=padding.MGF1(algorithm=mgf1hash()), algorithm=hashtype(), label=None
        ),
    )

    dec = asymkey.decrypt_oaep(ciphertext, hash=hashtype(), mgf_hash=mgf1hash())
    assert data == dec

    asymkey.delete()


OAEP_VECTOR_KEY = rsa.RSAPrivateNumbers(
    p=0xECF5AECD1E5515FFFACBD75A2816C6EBF49018CDFB4638E185D66A7396B6F8090F8018C7FD95CC34B857DC17F0CC6516BB1346AB4D582CADAD7B4103352387B70338D084047C9D9539B6496204B3DD6EA442499207BEC01F964287FF6336C3984658336846F56E46861881C10233D2176BF15A5E96DDC780BC868AA77D3CE769,  # noqa: E501
    q=0xBC46C464FC6AC4CA783B0EB08A3C841B772F7E9B2F28BABD588AE885E1A0C61E4858A0FB25AC299990F35BE85164C259BA1175CDD7192707135184992B6C29B746DD0D2CABE142835F7D148CC161524B4A09946D48B828473F1CE76B6CB6886C345C03E05F41D51B5C3A90A3F24073C7D74A4FE25D9CF21C75960F3FC3863183,  # noqa: E501
    d=0x056B04216FE5F354AC77250A4B6B0C8525A85C59B0BD80C56450A22D5F438E596A333AA875E291DD43F48CB88B9D5FC0D499F9FCD1C397F9AFC070CD9E398C8D19E61DB7C7410A6B2675DFBF5D345B804D201ADD502D5CE2DFCB091CE9997BBEBE57306F383E4D588103F036F7E85D1934D152A323E4A8DB451D6F4A5B1B0F102CC150E02FEEE2B88DEA4AD4C1BACCB24D84072D14E1D24A6771F7408EE30564FB86D4393A34BCF0B788501D193303F13A2284B001F0F649EAF79328D4AC5C430AB4414920A9460ED1B7BC40EC653E876D09ABC509AE45B525190116A0C26101848298509C1C3BF3A483E7274054E15E97075036E989F60932807B5257751E79,  # noqa: E501
    dmp1=0xC73564571D00FB15D08A3DE9957A50915D7126E9442DACF42BC82E862E5673FF6A008ED4D2E374617DF89F17A160B43B7FDA9CB6B6B74218609815F7D45CA263C159AA32D272D127FAF4BC8CA2D77378E8AEB19B0AD7DA3CB3DE0AE7314980F62B6D4B0A875D1DF03C1BAE39CCD833EF6CD7E2D9528BF084D1F969E794E9F6C1,  # noqa: E501
    dmq1=0x2658B37F6DF9C1030BE1DB68117FA9D87E39EA2B693B7E6D3A2F70947413EEC6142E18FB8DFCB6AC545D7C86A0AD48F8457170F0EFB26BC48126C53EFD1D16920198DC2A1107DC282DB6A80CD3062360BA3FA13F70E4312FF1A6CD6B8FC4CD9C5C3DB17C6D6A57212F73AE29F619327BAD59B153858585BA4E28B60A62A45E49,  # noqa: E501
    iqmp=0x6F38526B3925085534EF3E415A836EDE8B86158A2C7CBFECCB0BD834304FEC683BA8D4F479C433D43416E63269623CEA100776D85AFF401D3FFF610EE65411CE3B1363D63A9709EEDE42647CEA561493D54570A879C18682CD97710B96205EC31117D73B5F36223FADD6E8BA90DD7C0EE61D44E163251E20C7F66EB305117CB8,  # noqa: E501
    public_numbers=rsa.RSAPublicNumbers(
        n=0xAE45ED5601CEC6B8CC05F803935C674DDBE0D75C4C09FD7951FC6B0CAEC313A8DF39970C518BFFBA5ED68F3F0D7F22A4029D413F1AE07E4EBE9E4177CE23E7F5404B569E4EE1BDCF3C1FB03EF113802D4F855EB9B5134B5A7C8085ADCAE6FA2FA1417EC3763BE171B0C62B760EDE23C12AD92B980884C641F5A8FAC26BDAD4A03381A22FE1B754885094C82506D4019A535A286AFEB271BB9BA592DE18DCF600C2AEEAE56E02F7CF79FC14CF3BDC7CD84FEBBBF950CA90304B2219A7AA063AEFA2C3C1980E560CD64AFE779585B6107657B957857EFDE6010988AB7DE417FC88D8F384C4E6E72C3F943E0C31C0C4A5CC36F879D8A3AC9D7D59860EAADA6B83BB,  # noqa: E501
        e=0x10001,
    ),
).private_key(default_backend())


OAEP_VECTORS = [
    {
        "msg": b"\x8b\xba\x6b\xf8\x2a\x6c\x0f\x86\xd5\xf1\x75\x6e\x97\x95\x68\x70\xb0\x89\x53\xb0\x6b\x4e\xb2\x05\xbc\x16\x94\xee",  # noqa: E501
        "enc": b"\x53\xea\x5d\xc0\x8c\xd2\x60\xfb\x3b\x85\x85\x67\x28\x7f\xa9\x15\x52\xc3\x0b\x2f\xeb\xfb\xa2\x13\xf0\xae\x87\x70\x2d\x06\x8d\x19\xba\xb0\x7f\xe5\x74\x52\x3d\xfb\x42\x13\x9d\x68\xc3\xc5\xaf\xee\xe0\xbf\xe4\xcb\x79\x69\xcb\xf3\x82\xb8\x04\xd6\xe6\x13\x96\x14\x4e\x2d\x0e\x60\x74\x1f\x89\x93\xc3\x01\x4b\x58\xb9\xb1\x95\x7a\x8b\xab\xcd\x23\xaf\x85\x4f\x4c\x35\x6f\xb1\x66\x2a\xa7\x2b\xfc\xc7\xe5\x86\x55\x9d\xc4\x28\x0d\x16\x0c\x12\x67\x85\xa7\x23\xeb\xee\xbe\xff\x71\xf1\x15\x94\x44\x0a\xae\xf8\x7d\x10\x79\x3a\x87\x74\xa2\x39\xd4\xa0\x4c\x87\xfe\x14\x67\xb9\xda\xf8\x52\x08\xec\x6c\x72\x55\x79\x4a\x96\xcc\x29\x14\x2f\x9a\x8b\xd4\x18\xe3\xc1\xfd\x67\x34\x4b\x0c\xd0\x82\x9d\xf3\xb2\xbe\xc6\x02\x53\x19\x62\x93\xc6\xb3\x4d\x3f\x75\xd3\x2f\x21\x3d\xd4\x5c\x62\x73\xd5\x05\xad\xf4\xcc\xed\x10\x57\xcb\x75\x8f\xc2\x6a\xee\xfa\x44\x12\x55\xed\x4e\x64\xc1\x99\xee\x07\x5e\x7f\x16\x64\x61\x82\xfd\xb4\x64\x73\x9b\x68\xab\x5d\xaf\xf0\xe6\x3e\x95\x52\x01\x68\x24\xf0\x54\xbf\x4d\x3c\x8c\x90\xa9\x7b\xb6\xb6\x55\x32\x84\xeb\x42\x9f\xcc",  # noqa: E501
    },
    {
        "msg": b"\xe6\xad\x18\x1f\x05\x3b\x58\xa9\x04\xf2\x45\x75\x10\x37\x3e\x57",  # noqa: E501
        "enc": b"\xa2\xb1\xa4\x30\xa9\xd6\x57\xe2\xfa\x1c\x2b\xb5\xed\x43\xff\xb2\x5c\x05\xa3\x08\xfe\x90\x93\xc0\x10\x31\x79\x5f\x58\x74\x40\x01\x10\x82\x8a\xe5\x8f\xb9\xb5\x81\xce\x9d\xdd\xd3\xe5\x49\xae\x04\xa0\x98\x54\x59\xbd\xe6\xc6\x26\x59\x4e\x7b\x05\xdc\x42\x78\xb2\xa1\x46\x5c\x13\x68\x40\x88\x23\xc8\x5e\x96\xdc\x66\xc3\xa3\x09\x83\xc6\x39\x66\x4f\xc4\x56\x9a\x37\xfe\x21\xe5\xa1\x95\xb5\x77\x6e\xed\x2d\xf8\xd8\xd3\x61\xaf\x68\x6e\x75\x02\x29\xbb\xd6\x63\xf1\x61\x86\x8a\x50\x61\x5e\x0c\x33\x7b\xec\x0c\xa3\x5f\xec\x0b\xb1\x9c\x36\xeb\x2e\x0b\xbc\xc0\x58\x2f\xa1\xd9\x3a\xac\xdb\x06\x10\x63\xf5\x9f\x2c\xe1\xee\x43\x60\x5e\x5d\x89\xec\xa1\x83\xd2\xac\xdf\xe9\xf8\x10\x11\x02\x2a\xd3\xb4\x3a\x3d\xd4\x17\xda\xc9\x4b\x4e\x11\xea\x81\xb1\x92\x96\x6e\x96\x6b\x18\x20\x82\xe7\x19\x64\x60\x7b\x4f\x80\x02\xf3\x62\x99\x84\x4a\x11\xf2\xae\x0f\xae\xac\x2e\xae\x70\xf8\xf4\xf9\x80\x88\xac\xdc\xd0\xac\x55\x6e\x9f\xcc\xc5\x11\x52\x19\x08\xfa\xd2\x6f\x04\xc6\x42\x01\x45\x03\x05\x77\x87\x58\xb0\x53\x8b\xf8\xb5\xbb\x14\x4a\x82\x8e\x62\x97\x95",  # noqa: E501
    },
    {
        "msg": b"\x51\x0a\x2c\xf6\x0e\x86\x6f\xa2\x34\x05\x53\xc9\x4e\xa3\x9f\xbc\x25\x63\x11\xe8\x3e\x94\x45\x4b\x41\x24",  # noqa: E501
        "enc": b"\x98\x86\xc3\xe6\x76\x4a\x8b\x9a\x84\xe8\x41\x48\xeb\xd8\xc3\xb1\xaa\x80\x50\x38\x1a\x78\xf6\x68\x71\x4c\x16\xd9\xcf\xd2\xa6\xed\xc5\x69\x79\xc5\x35\xd9\xde\xe3\xb4\x4b\x85\xc1\x8b\xe8\x92\x89\x92\x37\x17\x11\x47\x22\x16\xd9\x5d\xda\x98\xd2\xee\x83\x47\xc9\xb1\x4d\xff\xdf\xf8\x4a\xa4\x8d\x25\xac\x06\xf7\xd7\xe6\x53\x98\xac\x96\x7b\x1c\xe9\x09\x25\xf6\x7d\xce\x04\x9b\x7f\x81\x2d\xb0\x74\x29\x97\xa7\x4d\x44\xfe\x81\xdb\xe0\xe7\xa3\xfe\xaf\x2e\x5c\x40\xaf\x88\x8d\x55\x0d\xdb\xbe\x3b\xc2\x06\x57\xa2\x95\x43\xf8\xfc\x29\x13\xb9\xbd\x1a\x61\xb2\xab\x22\x56\xec\x40\x9b\xbd\x7d\xc0\xd1\x77\x17\xea\x25\xc4\x3f\x42\xed\x27\xdf\x87\x38\xbf\x4a\xfc\x67\x66\xff\x7a\xff\x08\x59\x55\x5e\xe2\x83\x92\x0f\x4c\x8a\x63\xc4\xa7\x34\x0c\xba\xfd\xdc\x33\x9e\xcd\xb4\xb0\x51\x50\x02\xf9\x6c\x93\x2b\x5b\x79\x16\x7a\xf6\x99\xc0\xad\x3f\xcc\xfd\xf0\xf4\x4e\x85\xa7\x02\x62\xbf\x2e\x18\xfe\x34\xb8\x50\x58\x99\x75\xe8\x67\xff\x96\x9d\x48\xea\xbf\x21\x22\x71\x54\x6c\xdc\x05\xa6\x9e\xcb\x52\x6e\x52\x87\x0c\x83\x6f\x30\x7b\xd7\x98\x78\x0e\xde",  # noqa: E501
    },
    {
        "msg": b"\xbc\xdd\x19\x0d\xa3\xb7\xd3\x00\xdf\x9a\x06\xe2\x2c\xaa\xe2\xa7\x5f\x10\xc9\x1f\xf6\x67\xb7\xc1\x6b\xde\x8b\x53\x06\x4a\x26\x49\xa9\x40\x45\xc9",  # noqa: E501
        "enc": b"\x63\x18\xe9\xfb\x5c\x0d\x05\xe5\x30\x7e\x16\x83\x43\x6e\x90\x32\x93\xac\x46\x42\x35\x8a\xaa\x22\x3d\x71\x63\x01\x3a\xba\x87\xe2\xdf\xda\x8e\x60\xc6\x86\x0e\x29\xa1\xe9\x26\x86\x16\x3e\xa0\xb9\x17\x5f\x32\x9c\xa3\xb1\x31\xa1\xed\xd3\xa7\x77\x59\xa8\xb9\x7b\xad\x6a\x4f\x8f\x43\x96\xf2\x8c\xf6\xf3\x9c\xa5\x81\x12\xe4\x81\x60\xd6\xe2\x03\xda\xa5\x85\x6f\x3a\xca\x5f\xfe\xd5\x77\xaf\x49\x94\x08\xe3\xdf\xd2\x33\xe3\xe6\x04\xdb\xe3\x4a\x9c\x4c\x90\x82\xde\x65\x52\x7c\xac\x63\x31\xd2\x9d\xc8\x0e\x05\x08\xa0\xfa\x71\x22\xe7\xf3\x29\xf6\xcc\xa5\xcf\xa3\x4d\x4d\x1d\xa4\x17\x80\x54\x57\xe0\x08\xbe\xc5\x49\xe4\x78\xff\x9e\x12\xa7\x63\xc4\x77\xd1\x5b\xbb\x78\xf5\xb6\x9b\xd5\x78\x30\xfc\x2c\x4e\xd6\x86\xd7\x9b\xc7\x2a\x95\xd8\x5f\x88\x13\x4c\x6b\x0a\xfe\x56\xa8\xcc\xfb\xc8\x55\x82\x8b\xb3\x39\xbd\x17\x90\x9c\xf1\xd7\x0d\xe3\x33\x5a\xe0\x70\x39\x09\x3e\x60\x6d\x65\x53\x65\xde\x65\x50\xb8\x72\xcd\x6d\xe1\xd4\x40\xee\x03\x1b\x61\x94\x5f\x62\x9a\xd8\xa3\x53\xb0\xd4\x09\x39\xe9\x6a\x3c\x45\x0d\x2a\x8d\x5e\xee\x9f\x67\x80\x93\xc8",  # noqa: E501
    },
    {
        "msg": b"\xa7\xdd\x6c\x7d\xc2\x4b\x46\xf9\xdd\x5f\x1e\x91\xad\xa4\xc3\xb3\xdf\x94\x7e\x87\x72\x32\xa9",  # noqa: E501
        "enc": b"\x75\x29\x08\x72\xcc\xfd\x4a\x45\x05\x66\x0d\x65\x1f\x56\xda\x6d\xaa\x09\xca\x13\x01\xd8\x90\x63\x2f\x6a\x99\x2f\x3d\x56\x5c\xee\x46\x4a\xfd\xed\x40\xed\x3b\x5b\xe9\x35\x67\x14\xea\x5a\xa7\x65\x5f\x4a\x13\x66\xc2\xf1\x7c\x72\x8f\x6f\x2c\x5a\x5d\x1f\x8e\x28\x42\x9b\xc4\xe6\xf8\xf2\xcf\xf8\xda\x8d\xc0\xe0\xa9\x80\x8e\x45\xfd\x09\xea\x2f\xa4\x0c\xb2\xb6\xce\x6f\xff\xf5\xc0\xe1\x59\xd1\x1b\x68\xd9\x0a\x85\xf7\xb8\x4e\x10\x3b\x09\xe6\x82\x66\x64\x80\xc6\x57\x50\x5c\x09\x29\x25\x94\x68\xa3\x14\x78\x6d\x74\xea\xb1\x31\x57\x3c\xf2\x34\xbf\x57\xdb\x7d\x9e\x66\xcc\x67\x48\x19\x2e\x00\x2d\xc0\xde\xea\x93\x05\x85\xf0\x83\x1f\xdc\xd9\xbc\x33\xd5\x1f\x79\xed\x2f\xfc\x16\xbc\xf4\xd5\x98\x12\xfc\xeb\xca\xa3\xf9\x06\x9b\x0e\x44\x56\x86\xd6\x44\xc2\x5c\xcf\x63\xb4\x56\xee\x5f\xa6\xff\xe9\x6f\x19\xcd\xf7\x51\xfe\xd9\xea\xf3\x59\x57\x75\x4d\xbf\x4b\xfe\xa5\x21\x6a\xa1\x84\x4d\xc5\x07\xcb\x2d\x08\x0e\x72\x2e\xba\x15\x03\x08\xc2\xb5\xff\x11\x93\x62\x0f\x17\x66\xec\xf4\x48\x1b\xaf\xb9\x43\xbd\x29\x28\x77\xf2\x13\x6c\xa4\x94\xab\xa0",  # noqa: E501
    },
    {
        "msg": b"\xea\xf1\xa7\x3a\x1b\x0c\x46\x09\x53\x7d\xe6\x9c\xd9\x22\x8b\xbc\xfb\x9a\x8c\xa8\xc6\xc3\xef\xaf\x05\x6f\xe4\xa7\xf4\x63\x4e\xd0\x0b\x7c\x39\xec\x69\x22\xd7\xb8\xea\x2c\x04\xeb\xac",  # noqa: E501
        "enc": b"\x2d\x20\x7a\x73\x43\x2a\x8f\xb4\xc0\x30\x51\xb3\xf7\x3b\x28\xa6\x17\x64\x09\x8d\xfa\x34\xc4\x7a\x20\x99\x5f\x81\x15\xaa\x68\x16\x67\x9b\x55\x7e\x82\xdb\xee\x58\x49\x08\xc6\xe6\x97\x82\xd7\xde\xb3\x4d\xbd\x65\xaf\x06\x3d\x57\xfc\xa7\x6a\x5f\xd0\x69\x49\x2f\xd6\x06\x8d\x99\x84\xd2\x09\x35\x05\x65\xa6\x2e\x5c\x77\xf2\x30\x38\xc1\x2c\xb1\x0c\x66\x34\x70\x9b\x54\x7c\x46\xf6\xb4\xa7\x09\xbd\x85\xca\x12\x2d\x74\x46\x5e\xf9\x77\x62\xc2\x97\x63\xe0\x6d\xbc\x7a\x9e\x73\x8c\x78\xbf\xca\x01\x02\xdc\x5e\x79\xd6\x5b\x97\x3f\x28\x24\x0c\xaa\xb2\xe1\x61\xa7\x8b\x57\xd2\x62\x45\x7e\xd8\x19\x5d\x53\xe3\xc7\xae\x9d\xa0\x21\x88\x3c\x6d\xb7\xc2\x4a\xfd\xd2\x32\x2e\xac\x97\x2a\xd3\xc3\x54\xc5\xfc\xef\x1e\x14\x6c\x3a\x02\x90\xfb\x67\xad\xf0\x07\x06\x6e\x00\x42\x8d\x2c\xec\x18\xce\x58\xf9\x32\x86\x98\xde\xfe\xf4\xb2\xeb\x5e\xc7\x69\x18\xfd\xe1\xc1\x98\xcb\xb3\x8b\x7a\xfc\x67\x62\x6a\x9a\xef\xec\x43\x22\xbf\xd9\x0d\x25\x63\x48\x1c\x9a\x22\x1f\x78\xc8\x27\x2c\x82\xd1\xb6\x2a\xb9\x14\xe1\xc6\x9f\x6a\xf6\xef\x30\xca\x52\x60\xdb\x4a\x46",  # noqa: E501
    },
]


@pytest.mark.parametrize("vector", OAEP_VECTORS)
def test_rsa_oaep_vectors(session, vector):
    asymkey = AsymmetricKey.put(
        session, 0, "OAEP Vectors", 0xFFFF, CAPABILITY.DECRYPT_OAEP, OAEP_VECTOR_KEY
    )

    dec = asymkey.decrypt_oaep(
        vector["enc"], hash=hashes.SHA1(), mgf_hash=hashes.SHA1()
    )
    assert vector["msg"] == dec

    asymkey.delete()


def test_import_invalid_public_exponent(session):
    key = rsa.generate_private_key(
        public_exponent=3, key_size=2048, backend=default_backend()
    )

    with pytest.raises(ValueError):
        AsymmetricKey.put(
            session,
            0,
            "Test PUT invalid exponent",
            0xFFFF,
            CAPABILITY.SIGN_PKCS,
            key,
        )


def test_import_invalid_key_size(session):
    key = rsa.generate_private_key(
        public_exponent=0x10001, key_size=1024, backend=default_backend()
    )

    with pytest.raises(ValueError):
        AsymmetricKey.put(
            session,
            0,
            "Test PUT invalid key size",
            0xFFFF,
            CAPABILITY.SIGN_PKCS,
            key,
        )