blob: 55f6cc48929bfaa1858f8669e3d1072096fc9071 [file] [log] [blame]
David Brownb6e0ae62017-11-21 15:13:04 -07001"""
2Tests for ECDSA keys
3"""
4
David Brown79c4fcf2021-01-26 15:04:05 -07005# SPDX-License-Identifier: Apache-2.0
6
David Brownb6e0ae62017-11-21 15:13:04 -07007import io
8import os.path
9import sys
10import tempfile
11import unittest
12
13from cryptography.exceptions import InvalidSignature
14from cryptography.hazmat.primitives.asymmetric import ec
15from cryptography.hazmat.primitives.hashes import SHA256
16
17sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../..')))
18
19from imgtool.keys import load, ECDSA256P1, ECDSAUsageError
20
21class EcKeyGeneration(unittest.TestCase):
22
23 def setUp(self):
24 self.test_dir = tempfile.TemporaryDirectory()
25
26 def tname(self, base):
27 return os.path.join(self.test_dir.name, base)
28
29 def tearDown(self):
30 self.test_dir.cleanup()
31
32 def test_keygen(self):
33 name1 = self.tname("keygen.pem")
34 k = ECDSA256P1.generate()
35 k.export_private(name1, b'secret')
36
37 self.assertIsNone(load(name1))
38
39 k2 = load(name1, b'secret')
40
41 pubname = self.tname('keygen-pub.pem')
42 k2.export_public(pubname)
43 pk2 = load(pubname)
44
45 # We should be able to export the public key from the loaded
46 # public key, but not the private key.
47 pk2.export_public(self.tname('keygen-pub2.pem'))
48 self.assertRaises(ECDSAUsageError,
49 pk2.export_private, self.tname('keygen-priv2.pem'))
50
51 def test_emit(self):
52 """Basic sanity check on the code emitters."""
53 k = ECDSA256P1.generate()
54
David Vinczef763c5f2024-07-30 10:34:34 +020055 pubpem = io.StringIO()
56 k.emit_public_pem(pubpem)
57 self.assertIn("BEGIN PUBLIC KEY", pubpem.getvalue())
58 self.assertIn("END PUBLIC KEY", pubpem.getvalue())
59
David Brownb6e0ae62017-11-21 15:13:04 -070060 ccode = io.StringIO()
Fabio Utzig9560d772020-04-02 13:44:30 -030061 k.emit_c_public(ccode)
David Brownb6e0ae62017-11-21 15:13:04 -070062 self.assertIn("ecdsa_pub_key", ccode.getvalue())
63 self.assertIn("ecdsa_pub_key_len", ccode.getvalue())
64
David Vinczef763c5f2024-07-30 10:34:34 +020065 hashccode = io.StringIO()
66 k.emit_c_public_hash(hashccode)
67 self.assertIn("ecdsa_pub_key_hash", hashccode.getvalue())
68 self.assertIn("ecdsa_pub_key_hash_len", hashccode.getvalue())
69
David Brownb6e0ae62017-11-21 15:13:04 -070070 rustcode = io.StringIO()
Fabio Utzig9560d772020-04-02 13:44:30 -030071 k.emit_rust_public(rustcode)
David Brownb6e0ae62017-11-21 15:13:04 -070072 self.assertIn("ECDSA_PUB_KEY", rustcode.getvalue())
73
David Vinczef763c5f2024-07-30 10:34:34 +020074 # raw data - bytes
75 pubraw = io.BytesIO()
76 k.emit_raw_public(pubraw)
77 self.assertTrue(len(pubraw.getvalue()) > 0)
78
79 hashraw = io.BytesIO()
80 k.emit_raw_public_hash(hashraw)
81 self.assertTrue(len(hashraw.getvalue()) > 0)
82
David Brownb6e0ae62017-11-21 15:13:04 -070083 def test_emit_pub(self):
David Vinczef763c5f2024-07-30 10:34:34 +020084 """Basic sanity check on the code emitters, from public key."""
David Brownb6e0ae62017-11-21 15:13:04 -070085 pubname = self.tname("public.pem")
86 k = ECDSA256P1.generate()
87 k.export_public(pubname)
88
89 k2 = load(pubname)
90
91 ccode = io.StringIO()
Fabio Utzig9560d772020-04-02 13:44:30 -030092 k2.emit_c_public(ccode)
David Brownb6e0ae62017-11-21 15:13:04 -070093 self.assertIn("ecdsa_pub_key", ccode.getvalue())
94 self.assertIn("ecdsa_pub_key_len", ccode.getvalue())
95
96 rustcode = io.StringIO()
Fabio Utzig9560d772020-04-02 13:44:30 -030097 k2.emit_rust_public(rustcode)
David Brownb6e0ae62017-11-21 15:13:04 -070098 self.assertIn("ECDSA_PUB_KEY", rustcode.getvalue())
99
100 def test_sig(self):
101 k = ECDSA256P1.generate()
102 buf = b'This is the message'
David Brown2c9153a2017-11-21 15:18:12 -0700103 sig = k.raw_sign(buf)
David Brownb6e0ae62017-11-21 15:13:04 -0700104
105 # The code doesn't have any verification, so verify this
106 # manually.
107 k.key.public_key().verify(
108 signature=sig,
109 data=buf,
110 signature_algorithm=ec.ECDSA(SHA256()))
111
112 # Modify the message to make sure the signature fails.
113 self.assertRaises(InvalidSignature,
114 k.key.public_key().verify,
115 signature=sig,
116 data=b'This is thE message',
117 signature_algorithm=ec.ECDSA(SHA256()))
118
119if __name__ == '__main__':
120 unittest.main()