laforge has submitted this change. (
https://gerrit.osmocom.org/c/pysim/+/38959?usp=email
)
Change subject: contrib/suci-keytool.py: Convenience tool for SUCI key generation
......................................................................
contrib/suci-keytool.py: Convenience tool for SUCI key generation
This adds a small utility program that can be used for generating
keys used for SUCI in 5G SA networks, as well as for dumping them
in a format that's compatible with what is needed on the USIM.
Change-Id: I9e92bbba7f700e160ea9c58da5f23fa4c31d40c6
---
A contrib/suci-keytool.py
M docs/index.rst
A docs/suci-keytool.rst
3 files changed, 111 insertions(+), 0 deletions(-)
Approvals:
laforge: Looks good to me, approved
Jenkins Builder: Verified
diff --git a/contrib/suci-keytool.py b/contrib/suci-keytool.py
new file mode 100755
index 0000000..6abd489
--- /dev/null
+++ b/contrib/suci-keytool.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+
+# small utility program to deal with 5G SUCI key material, at least for the ECIES
Protection Scheme
+# Profile A (curve25519) and B (secp256r1)
+
+# (C) 2024 by Harald Welte <laforge(a)osmocom.org>
+# SPDX-License-Identifier: GPL-2.0+
+
+import argparse
+
+from osmocom.utils import b2h
+from Cryptodome.PublicKey import ECC
+# if used with pycryptodome < v3.21.0 you will get the following error when using
curve25519:
+# "Cryptodome.PublicKey.ECC.UnsupportedEccFeature: Unsupported ECC purpose (OID:
1.3.101.110)"
+
+def gen_key(opts):
+ # FIXME: avoid overwriting key files
+ mykey = ECC.generate(curve=opts.curve)
+ data = mykey.export_key(format='PEM')
+ with open(opts.key_file, "wt") as f:
+ f.write(data)
+
+def dump_pkey(opts):
+
+ #with open("curve25519-1.key", "r") as f:
+
+ with open(opts.key_file, "r") as f:
+ data = f.read()
+ mykey = ECC.import_key(data)
+
+ der = mykey.public_key().export_key(format='raw',
compress=opts.compressed)
+ print(b2h(der))
+
+arg_parser = argparse.ArgumentParser(description="""Generate or export
SUCI keys for 5G SA networks""")
+arg_parser.add_argument('--key-file', help='The key file to use',
required=True)
+
+subparsers = arg_parser.add_subparsers(dest='command', help="The command to
perform", required=True)
+
+parser_genkey = subparsers.add_parser('generate-key', help='Generate a new
key pair')
+parser_genkey.add_argument('--curve', help='The ECC curve to use',
choices=['secp256r1','curve25519'], required=True)
+
+parser_dump_pkey = subparsers.add_parser('dump-pub-key', help='Dump the
public key')
+parser_dump_pkey.add_argument('--compressed', help='Use point
compression', action='store_true')
+
+if __name__ == '__main__':
+
+ opts = arg_parser.parse_args()
+
+ if opts.command == 'generate-key':
+ gen_key(opts)
+ elif opts.command == 'dump-pub-key':
+ dump_pkey(opts)
diff --git a/docs/index.rst b/docs/index.rst
index 228fb79..1dfa624 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -44,6 +44,7 @@
library
osmo-smdpp
sim-rest
+ suci-keytool
Indices and tables
diff --git a/docs/suci-keytool.rst b/docs/suci-keytool.rst
new file mode 100644
index 0000000..88e3a24
--- /dev/null
+++ b/docs/suci-keytool.rst
@@ -0,0 +1,58 @@
+suci-keytool
+============
+
+Subscriber concealment is an important feature of the 5G SA architecture: It avoids the
many privacy
+issues associated with having a permanent identifier (SUPI, traditionally the IMSI)
transmitted in plain text
+over the air interface. Using SUCI solves this issue not just for the air interface; it
even ensures the SUPI/IMSI
+is not known to the visited network (VPLMN) at all.
+
+In principle, the SUCI mechanism works by encrypting the SUPI by asymmetric (public key)
cryptography:
+Only the HPLMN is in possession of the private key and hence can decrypt the SUCI to the
SUPI, while
+each subscriber has the public key in order to encrypt their SUPI into the SUCI. In
reality, the
+details are more complex, as there are ephemeral keys and cryptographic MAC involved.
+
+In any case, in order to operate a SUCI-enabled 5G SA network, you will have to
+
+#. generate a ECC key pair of public + private key
+#. deploy the public key on your USIMs
+#. deploy the private key on your 5GC, specifically the UDM function
+
+pysim contains (int its `contrib` directory) a small utility program that can make it
easy to generate
+such keys: `suci-keytool.py`
+
+Generating keys
+~~~~~~~~~~~~~~~
+
+Example: Generating a *secp256r1* ECC public key pair and storing it to `/tmp/suci.key`:
+::
+
+ $ ./contrib/suci-keytool.py --key-file /tmp/suci.key generate-key --curve
secp256r1
+
+Dumping public keys
+~~~~~~~~~~~~~~~~~~~
+
+In order to store the key to SIM cards as part of `ADF.USIM/DF.5GS/EF.SUCI_Calc_Info`,
you will need
+a hexadecimal representation of the public key. You can achieve that using the
`dump-pub-key` operation
+of suci-keytool:
+
+Example: Dumping the public key part from a previously generated key file:
+::
+
+ $ ./contrib/suci-keytool.py --key-file /tmp/suci.key dump-pub-key
+
0473152f32523725f5175d255da2bd909de97b1d06449a9277bc629fe42112f8643e6b69aa6dce6c86714ccbe6f2e0f4f4898d102e2b3f0c18ce26626f052539bb
+
+If you want the point-compressed representation, you can use the `--compressed` option:
+::
+
+ $ ./contrib/suci-keytool.py --key-file /tmp/suci.key dump-pub-key --compressed
+ 0373152f32523725f5175d255da2bd909de97b1d06449a9277bc629fe42112f864
+
+
+
+suci-keytool syntax
+~~~~~~~~~~~~~~~~~~~
+
+.. argparse::
+ :module: contrib.suci-keytool
+ :func: arg_parser
+ :prog: contrib/suci-keytool.py
--
To view, visit
https://gerrit.osmocom.org/c/pysim/+/38959?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I9e92bbba7f700e160ea9c58da5f23fa4c31d40c6
Gerrit-Change-Number: 38959
Gerrit-PatchSet: 1
Gerrit-Owner: laforge <laforge(a)osmocom.org>
Gerrit-Reviewer: Jenkins Builder
Gerrit-Reviewer: laforge <laforge(a)osmocom.org>