Skip to content

Commit 1467254

Browse files
fundakolnvlsianpu
authored andcommitted
scripts: Update west command for uploading keys to KMU
Extended NcsProvision command for another keys slots. Signed-off-by: Lukasz Fundakowski <[email protected]>
1 parent 5716767 commit 1467254

File tree

1 file changed

+89
-54
lines changed

1 file changed

+89
-54
lines changed

scripts/west_commands/ncs-provision.py

Lines changed: 89 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,29 @@
33
#
44
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
55

6-
from pathlib import Path
6+
from __future__ import annotations
7+
78
import re
8-
import sys
99
import subprocess
10+
import sys
11+
from pathlib import Path
12+
1013
from cryptography.hazmat.primitives.serialization import load_pem_private_key
1114
from west.commands import WestCommand
1215

13-
nrf54l15_key_slots = [226, 228, 230]
14-
nrf54l15_key_policies = {"revokable": "REVOKED",
15-
"lock": "LOCKED"}
16+
KEY_SLOTS: dict[str, list[int]] = {
17+
"UROT_PUBKEY": [226, 228, 230],
18+
"BL_PUBKEY": [242, 244, 246],
19+
"APP_PUBKEY": [202, 204, 206],
20+
}
21+
KEY_SLOT_METADATA: str = "0x10ba0030"
22+
KMU_KEY_SLOT_DEST_ADDR: str = "0x20000000"
23+
ALGORITHM: str = "ED25519"
24+
NRF54L15_KEY_POLICIES: dict[str, str] = {"revokable": "REVOKED", "lock": "LOCKED"}
1625

1726

1827
class NcsProvision(WestCommand):
28+
1929
def __init__(self):
2030
super().__init__(
2131
"ncs-provision",
@@ -25,74 +35,99 @@ def __init__(self):
2535

2636
def do_add_parser(self, parser_adder):
2737
parser = parser_adder.add_parser(
28-
self.name, help=self.help, description=self.description
29-
)
38+
self.name, help=self.help, description=self.description)
3039

31-
subparsers = parser.add_subparsers(
32-
dest="command"
33-
)
40+
subparsers = parser.add_subparsers(dest="command")
3441
upload_parser = subparsers.add_parser("upload", help="Send to KMU")
3542
upload_parser.add_argument(
36-
"-k", "--key", type=Path, action='append', dest="keys",
37-
help="Input .pem file with ED25519 private key"
43+
"-k",
44+
"--key",
45+
type=Path,
46+
action="append",
47+
dest="keys",
48+
help="Input .pem file with ED25519 private key",
49+
)
50+
upload_parser.add_argument(
51+
"--keyname",
52+
choices=KEY_SLOTS.keys(),
53+
# default value for backward compatibility
54+
default="UROT_PUBKEY",
55+
help="Key name to upload",
56+
)
57+
upload_parser.add_argument(
58+
"-p",
59+
"--policy",
60+
type=str,
61+
choices=["revokable", "lock", "lock-last"],
62+
default="lock-last",
63+
help="Policy applied to the given set of keys. "
64+
"revokable: keys can be revoked each by one. "
65+
"lock: all keys stay as they are. "
66+
"lock-last: last key is uploaded as locked, "
67+
"others as revokable",
68+
)
69+
upload_parser.add_argument(
70+
"-s", "--soc", type=str, help="SoC",
71+
choices=["nrf54l05", "nrf54l10", "nrf54l15"], required=True
3872
)
39-
upload_parser.add_argument("-p", "--policy", type=str,
40-
choices=["revokable", "lock", "lock-last"], default="lock-last",
41-
help="Policy applied to the given set of keys."
42-
" revokable: keys can be revoked each by one."
43-
" lock: all keys stay as they are."
44-
" lock-last: last key is uploaded as locked,"
45-
" others as revokable")
46-
upload_parser.add_argument("-s", "--soc", type=str, help="SoC",
47-
choices=["nrf54l05", "nrf54l10", "nrf54l15"], required=True)
4873
upload_parser.add_argument("--dev-id", help="Device serial number")
4974

5075
return parser
5176

5277
def do_run(self, args, unknown_args):
5378
if args.command == "upload":
5479
if args.soc in ["nrf54l05", "nrf54l10", "nrf54l15"]:
55-
if len(args.keys) > len(nrf54l15_key_slots):
80+
keyname = args.keyname
81+
if len(args.keys) > len(KEY_SLOTS[keyname]):
5682
sys.exit(
5783
"Error: requested upload of more keys than there are designated slots.")
58-
slot = 0
59-
for keyfile in args.keys:
60-
with open(keyfile, 'rb') as f:
61-
priv_key = load_pem_private_key(f.read(), password=None)
84+
for slot_idx, keyfile in enumerate(args.keys):
85+
with open(keyfile, "rb") as f:
86+
priv_key = load_pem_private_key(
87+
f.read(), password=None)
6288
pub_key = priv_key.public_key()
6389
if args.policy == "lock-last":
64-
if slot == (len(args.keys) - 1):
65-
key_policy = nrf54l15_key_policies["lock"]
90+
if slot_idx == (len(args.keys) - 1):
91+
key_policy = NRF54L15_KEY_POLICIES["lock"]
6692
else:
67-
key_policy = nrf54l15_key_policies["revokable"]
93+
key_policy = NRF54L15_KEY_POLICIES["revokable"]
6894
else:
69-
key_policy = nrf54l15_key_policies[args.policy]
70-
command = [
71-
"nrfprovision",
72-
"provision",
73-
"-r",
74-
key_policy,
75-
"-v",
76-
pub_key.public_bytes_raw().hex(),
77-
"-m",
78-
"0x10ba0030",
79-
"-i",
80-
str(nrf54l15_key_slots[slot]),
81-
"-a",
82-
"ED25519",
83-
"-d",
84-
"0x20000000",
85-
"--verify"
86-
]
87-
if args.dev_id:
88-
command.extend(["--snr", args.dev_id])
95+
key_policy = NRF54L15_KEY_POLICIES[args.policy]
96+
dev_id = args.dev_id
97+
pub_key_hex = pub_key.public_bytes_raw().hex()
98+
slot_id = str(KEY_SLOTS[keyname][slot_idx])
99+
command = self._build_command(
100+
dev_id=dev_id, key_policy=key_policy, pub_key=pub_key_hex, slot_id=slot_id
101+
)
89102
nrfprovision = subprocess.run(
90-
command,
91-
stderr=subprocess.PIPE,
92-
text=True
103+
command, stderr=subprocess.PIPE, text=True
93104
)
94105
stderr = nrfprovision.stderr
95106
print(stderr, file=sys.stderr)
96-
if re.search('fail', stderr) or nrfprovision.returncode:
107+
if re.search("fail", stderr) or nrfprovision.returncode:
97108
sys.exit("Uploading failed!")
98-
slot += 1
109+
110+
@staticmethod
111+
def _build_command(
112+
key_policy: str, pub_key: str, slot_id: str, dev_id: str | None
113+
) -> list[str]:
114+
command = [
115+
"nrfprovision",
116+
"provision",
117+
"--rpolicy",
118+
key_policy,
119+
"--value",
120+
pub_key,
121+
"--metadata",
122+
KEY_SLOT_METADATA,
123+
"--id",
124+
slot_id,
125+
"--algorithm",
126+
ALGORITHM,
127+
"--dest",
128+
KMU_KEY_SLOT_DEST_ADDR,
129+
"--verify",
130+
]
131+
if dev_id:
132+
command.extend(["--snr", dev_id])
133+
return command

0 commit comments

Comments
 (0)