aboutsummaryrefslogtreecommitdiff
path: root/circuitpython/lib/nrfutil/nordicsemi/dfu/signing.py
diff options
context:
space:
mode:
authorRaghuram Subramani <raghus2247@gmail.com>2022-06-19 19:47:51 +0530
committerRaghuram Subramani <raghus2247@gmail.com>2022-06-19 19:47:51 +0530
commit4fd287655a72b9aea14cdac715ad5b90ed082ed2 (patch)
tree65d393bc0e699dd12d05b29ba568e04cea666207 /circuitpython/lib/nrfutil/nordicsemi/dfu/signing.py
parent0150f70ce9c39e9e6dd878766c0620c85e47bed0 (diff)
add circuitpython code
Diffstat (limited to 'circuitpython/lib/nrfutil/nordicsemi/dfu/signing.py')
-rw-r--r--circuitpython/lib/nrfutil/nordicsemi/dfu/signing.py149
1 files changed, 149 insertions, 0 deletions
diff --git a/circuitpython/lib/nrfutil/nordicsemi/dfu/signing.py b/circuitpython/lib/nrfutil/nordicsemi/dfu/signing.py
new file mode 100644
index 0000000..ca98eb1
--- /dev/null
+++ b/circuitpython/lib/nrfutil/nordicsemi/dfu/signing.py
@@ -0,0 +1,149 @@
+# Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
+#
+# The information contained herein is property of Nordic Semiconductor ASA.
+# Terms and conditions of usage are described in detail in NORDIC
+# SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+#
+# Licensees are granted free, non-transferable use of the information. NO
+# WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+# the file.
+
+import hashlib
+import binascii
+
+try:
+ from ecdsa import SigningKey
+ from ecdsa.curves import NIST256p
+ from ecdsa.keys import sigencode_string
+except Exception:
+ print "Failed to import ecdsa, cannot do signing"
+
+from nordicsemi.exceptions import InvalidArgumentException, IllegalStateException
+
+
+class Signing(object):
+ """
+ Class for singing of hex-files
+ """
+ def gen_key(self, filename):
+ """
+ Generate a new Signing key using NIST P-256 curve
+ """
+ self.sk = SigningKey.generate(curve=NIST256p)
+
+ with open(filename, "w") as sk_file:
+ sk_file.write(self.sk.to_pem())
+
+ def load_key(self, filename):
+ """
+ Load signing key (from pem file)
+ """
+ with open(filename, "r") as sk_file:
+ sk_pem = sk_file.read()
+
+ self.sk = SigningKey.from_pem(sk_pem)
+
+ sk_hex = "".join(c.encode('hex') for c in self.sk.to_string())
+
+ def sign(self, init_packet_data):
+ """
+ Create signature for init package using P-256 curve and SHA-256 as hashing algorithm
+ Returns R and S keys combined in a 64 byte array
+ """
+ # Add assertion of init_packet
+ if self.sk is None:
+ raise IllegalStateException("Can't save key. No key created/loaded")
+
+ # Sign the init-packet
+ signature = self.sk.sign(init_packet_data, hashfunc=hashlib.sha256, sigencode=sigencode_string)
+ return signature
+
+ def verify(self, init_packet, signature):
+ """
+ Verify init packet
+ """
+ # Add assertion of init_packet
+ if self.sk is None:
+ raise IllegalStateException("Can't save key. No key created/loaded")
+
+ vk = self.sk.get_verifying_key()
+
+ # Verify init packet
+ try:
+ vk.verify(signature, init_packet, hashfunc=hashlib.sha256)
+ except:
+ return False
+
+ return True
+
+ def get_vk(self, output_type):
+ """
+ Get verification key (as hex, code or pem)
+ """
+ if self.sk is None:
+ raise IllegalStateException("Can't get key. No key created/loaded")
+
+ if output_type is None:
+ raise InvalidArgumentException("Invalid output type for signature.")
+ elif output_type == 'hex':
+ return self.get_vk_hex()
+ elif output_type == 'code':
+ return self.get_vk_code()
+ elif output_type == 'pem':
+ return self.get_vk_pem()
+ else:
+ raise InvalidArgumentException("Invalid argument. Can't get key")
+
+ def get_vk_hex(self):
+ """
+ Get the verification key as hex
+ """
+ if self.sk is None:
+ raise IllegalStateException("Can't get key. No key created/loaded")
+
+ vk = self.sk.get_verifying_key()
+ vk_hexlify = binascii.hexlify(vk.to_string())
+
+ vk_hex = "Verification key Qx: {0}\n".format(vk_hexlify[0:64])
+ vk_hex += "Verification key Qy: {0}".format(vk_hexlify[64:128])
+
+ return vk_hex
+
+ def get_vk_code(self):
+ """
+ Get the verification key as code
+ """
+ if self.sk is None:
+ raise IllegalStateException("Can't get key. No key created/loaded")
+
+ vk = self.sk.get_verifying_key()
+ vk_hex = binascii.hexlify(vk.to_string())
+
+ vk_x_separated = ""
+ vk_x_str = vk_hex[0:64]
+ for i in xrange(0, len(vk_x_str), 2):
+ vk_x_separated += "0x" + vk_x_str[i:i+2] + ", "
+ vk_x_separated = vk_x_separated[:-2]
+
+ vk_y_separated = ""
+ vk_y_str = vk_hex[64:128]
+ for i in xrange(0, len(vk_y_str), 2):
+ vk_y_separated += "0x" + vk_y_str[i:i+2] + ", "
+ vk_y_separated = vk_y_separated[:-2]
+
+ vk_code = "static uint8_t Qx[] = {{ {0} }};\n".format(vk_x_separated)
+ vk_code += "static uint8_t Qy[] = {{ {0} }};".format(vk_y_separated)
+
+ return vk_code
+
+ def get_vk_pem(self):
+ """
+ Get the verification key as PEM
+ """
+ if self.sk is None:
+ raise IllegalStateException("Can't get key. No key created/loaded")
+
+ vk = self.sk.get_verifying_key()
+ vk_pem = vk.to_pem()
+
+ return vk_pem