pkg/micro-ecc: support boards without hwrng feature
parent
3dac61aa11
commit
ba7f1af7ab
@ -1 +0,0 @@
|
||||
FEATURES_REQUIRED += periph_hwrng
|
@ -0,0 +1,37 @@
|
||||
# Micro-ECC for RIOT
|
||||
|
||||
This port of Micro-ECC to RIOT is based on the Micro-ECC
|
||||
[upstream](https://github.com/kmackay/micro-ecc) and adds `hwrng_read`
|
||||
(provided by RIOT) as the default RNG function if it is available on the target
|
||||
platform. This port also fixes a minor issue with unused variables in the
|
||||
upstream code.
|
||||
|
||||
# Usage
|
||||
|
||||
## Build
|
||||
|
||||
Add
|
||||
```Makefile
|
||||
USEPKG += micro-ecc
|
||||
```
|
||||
to your Makefile.
|
||||
|
||||
## Choosing the right API
|
||||
|
||||
Before using the Micro-ECC library, you need to check the `Makefile.features`
|
||||
of your target board to see if `periph_hwrng` is provided.
|
||||
|
||||
If it is provided, you may safely use `uECC_make_key` to generate ECDSA key
|
||||
pairs and call `uECC_sign`/`uECC_verify` to sign/verify the ECDSA signatures.
|
||||
|
||||
If not, you cannot use `uECC_make_key` or `uECC_sign` APIs anymore. The ECDSA
|
||||
keys have to be generated on a platform with HWRNG support (e.g., `native`) and
|
||||
transferred to your target device. You need to use `uECC_sign_deterministic` to
|
||||
perform ECDSA deterministic signing (standardized by RFC 6979). You can still
|
||||
use `uECC_verify` to verify the signatures from both signing APIs.
|
||||
|
||||
**WARNING** Calling `uECC_make_key` and `uECC_sign` APIs on platforms without
|
||||
HWRNG support will lead to compile failure.
|
||||
|
||||
Examples of using these uECC APIs can be found in the `test` folder of the
|
||||
Micro-ECC upstream.
|
@ -1,41 +1,145 @@
|
||||
From d2cb5acad29db4c98af1a965a9c0d0ce67729984 Mon Sep 17 00:00:00 2001
|
||||
From: Mathias Tausig <mathias.tausig@fh-campuswien.ac.at>
|
||||
Date: Mon, 7 Mar 2016 17:20:49 +0100
|
||||
From 459241f2801c3b1a0d28c5669527e165ce4b384e Mon Sep 17 00:00:00 2001
|
||||
From: Wentao Shang <wentaoshang@gmail.com>
|
||||
Date: Mon, 12 Dec 2016 16:19:34 -0800
|
||||
Subject: [PATCH 2/3] Include RIOT Hardware RNG interface
|
||||
|
||||
---
|
||||
uECC.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
platform-specific.inc | 4 ++++
|
||||
uECC.c | 22 ++++++++++++++++++++++
|
||||
uECC.h | 8 ++++++++
|
||||
3 files changed, 34 insertions(+)
|
||||
|
||||
diff --git a/platform-specific.inc b/platform-specific.inc
|
||||
index 1bb595a..b13fdbe 100644
|
||||
--- a/platform-specific.inc
|
||||
+++ b/platform-specific.inc
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
+#ifdef FEATURE_PERIPH_HWRNG
|
||||
+
|
||||
#if (defined(_WIN32) || defined(_WIN64))
|
||||
/* Windows */
|
||||
|
||||
@@ -64,4 +66,6 @@ static int default_RNG(uint8_t *dest, unsigned size) {
|
||||
|
||||
#endif /* platform */
|
||||
|
||||
+#endif /* FEATURE_PERIPH_HWRNG */
|
||||
+
|
||||
#endif /* _UECC_PLATFORM_SPECIFIC_H_ */
|
||||
diff --git a/uECC.c b/uECC.c
|
||||
index f65fe37..662d899 100644
|
||||
index daa144a..3691fc4 100644
|
||||
--- a/uECC.c
|
||||
+++ b/uECC.c
|
||||
@@ -2,6 +2,7 @@
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
#include "uECC.h"
|
||||
#include "uECC_vli.h"
|
||||
+#ifdef FEATURE_PERIPH_HWRNG
|
||||
+#include "periph/hwrng.h"
|
||||
+#endif
|
||||
|
||||
#ifndef uECC_RNG_MAX_TRIES
|
||||
#define uECC_RNG_MAX_TRIES 64
|
||||
@@ -170,10 +171,15 @@ static cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left,
|
||||
@@ -181,9 +184,20 @@ static cmpresult_t uECC_vli_cmp_unsafe(const uECC_word_t *left,
|
||||
#include "asm_avr.inc"
|
||||
#endif
|
||||
|
||||
+#ifdef FEATURE_PERIPH_HWRNG
|
||||
+int riot_hwrng(uint8_t *dest, unsigned size) {
|
||||
+ hwrng_read(dest, size);
|
||||
+ return 1;
|
||||
+ hwrng_read(dest, size);
|
||||
+ return 1;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+#ifdef FEATURE_PERIPH_HWRNG
|
||||
#if default_RNG_defined
|
||||
static uECC_RNG_Function g_rng_function = &default_RNG;
|
||||
#else
|
||||
-static uECC_RNG_Function g_rng_function = 0;
|
||||
+static uECC_RNG_Function g_rng_function = &riot_hwrng;
|
||||
+#endif
|
||||
+#else
|
||||
static uECC_RNG_Function g_rng_function = 0;
|
||||
#endif
|
||||
|
||||
void uECC_set_rng(uECC_RNG_Function rng_function) {
|
||||
@@ -1001,6 +1015,8 @@ uECC_VLI_API int uECC_generate_random_int(uECC_word_t *random,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef FEATURE_PERIPH_HWRNG
|
||||
+
|
||||
int uECC_make_key(uint8_t *public_key,
|
||||
uint8_t *private_key,
|
||||
uECC_Curve curve) {
|
||||
@@ -1031,6 +1047,8 @@ int uECC_make_key(uint8_t *public_key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#endif /* FEATURE_PERIPH_HWRNG */
|
||||
+
|
||||
int uECC_shared_secret(const uint8_t *public_key,
|
||||
const uint8_t *private_key,
|
||||
uint8_t *secret,
|
||||
@@ -1303,6 +1321,8 @@ static int uECC_sign_with_k(const uint8_t *private_key,
|
||||
return 1;
|
||||
}
|
||||
|
||||
+#ifdef FEATURE_PERIPH_HWRNG
|
||||
+
|
||||
int uECC_sign(const uint8_t *private_key,
|
||||
const uint8_t *message_hash,
|
||||
unsigned hash_size,
|
||||
@@ -1323,6 +1343,8 @@ int uECC_sign(const uint8_t *private_key,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#endif /* FEATURE_PERIPH_HWRNG */
|
||||
+
|
||||
/* Compute an HMAC using K as a key (as in RFC 6979). Note that K is always
|
||||
the same size as the hash result size. */
|
||||
static void HMAC_init(const uECC_HashContext *hash_context, const uint8_t *K) {
|
||||
diff --git a/uECC.h b/uECC.h
|
||||
index 9911763..6433143 100644
|
||||
--- a/uECC.h
|
||||
+++ b/uECC.h
|
||||
@@ -144,6 +144,8 @@ Returns the size of a public key for the curve in bytes.
|
||||
*/
|
||||
int uECC_curve_public_key_size(uECC_Curve curve);
|
||||
|
||||
+#ifdef FEATURE_PERIPH_HWRNG
|
||||
+
|
||||
/* uECC_make_key() function.
|
||||
Create a public/private key pair.
|
||||
|
||||
@@ -162,6 +164,8 @@ Returns 1 if the key pair was generated successfully, 0 if an error occurred.
|
||||
*/
|
||||
int uECC_make_key(uint8_t *public_key, uint8_t *private_key, uECC_Curve curve);
|
||||
|
||||
+#endif /* FEATURE_PERIPH_HWRNG */
|
||||
+
|
||||
/* uECC_shared_secret() function.
|
||||
Compute a shared secret given your secret key and someone else's public key.
|
||||
Note: It is recommended that you hash the result of uECC_shared_secret() before using it for
|
||||
@@ -235,6 +239,8 @@ Returns 1 if the key was computed successfully, 0 if an error occurred.
|
||||
*/
|
||||
int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve);
|
||||
|
||||
+#ifdef FEATURE_PERIPH_HWRNG
|
||||
+
|
||||
/* uECC_sign() function.
|
||||
Generate an ECDSA signature for a given hash value.
|
||||
|
||||
@@ -258,6 +264,8 @@ int uECC_sign(const uint8_t *private_key,
|
||||
uint8_t *signature,
|
||||
uECC_Curve curve);
|
||||
|
||||
+#endif /* FEATURE_PERIPH_HWRNG */
|
||||
+
|
||||
/* uECC_HashContext structure.
|
||||
This is used to pass in an arbitrary hash function to uECC_sign_deterministic().
|
||||
The structure will be used for multiple hash computations; each time a new hash
|
||||
--
|
||||
2.5.0
|
||||
2.7.4
|
||||
|
||||
|
@ -0,0 +1,53 @@
|
||||
From 17cab9daa22fdff9c3bc884024f330445f558550 Mon Sep 17 00:00:00 2001
|
||||
From: Wentao Shang <wentaoshang@gmail.com>
|
||||
Date: Wed, 1 Jun 2016 15:00:43 -0700
|
||||
Subject: [PATCH 3/3] Silence warning of unused variable
|
||||
|
||||
---
|
||||
asm_avr.inc | 2 +-
|
||||
curve-specific.inc | 2 +-
|
||||
uECC.c | 2 +-
|
||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/asm_avr.inc b/asm_avr.inc
|
||||
index c988040..cd194da 100644
|
||||
--- a/asm_avr.inc
|
||||
+++ b/asm_avr.inc
|
||||
@@ -986,7 +986,7 @@ uECC_VLI_API void uECC_vli_mult(uECC_word_t *result,
|
||||
"st z+, %[r0] \n\t" /* Store last result byte. */
|
||||
"eor r1, r1 \n\t" /* fix r1 to be 0 again */
|
||||
|
||||
- : "+z" (result), "+x" (left), "+y" (right),
|
||||
+ : "+z" (r), "+x" (left), "+y" (right),
|
||||
[r0] "+r" (r0), [r1] "+r" (r1), [r2] "+r" (r2),
|
||||
[zero] "+r" (zero), [num] "+r" (num_words),
|
||||
[k] "=&r" (k), [i] "=&r" (i)
|
||||
diff --git a/curve-specific.inc b/curve-specific.inc
|
||||
index 0453b21..e17e75c 100644
|
||||
--- a/curve-specific.inc
|
||||
+++ b/curve-specific.inc
|
||||
@@ -563,7 +563,7 @@ static void mod_sqrt_secp224r1(uECC_word_t *a, uECC_Curve curve) {
|
||||
}
|
||||
}
|
||||
uECC_vli_modInv(f1, e0, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- 1 / e0 */
|
||||
- uECC_vli_modMult_fast(a, d0, f1, &curve_secp224r1); /* a <-- d0 / e0 */
|
||||
+ uECC_vli_modMult_fast(a, d0, f1, curve); /* a <-- d0 / e0 */
|
||||
}
|
||||
#endif /* uECC_SUPPORT_COMPRESSED_POINT */
|
||||
|
||||
diff --git a/uECC.c b/uECC.c
|
||||
index 3691fc4..2fc6524 100644
|
||||
--- a/uECC.c
|
||||
+++ b/uECC.c
|
||||
@@ -379,7 +379,7 @@ uECC_VLI_API uECC_word_t uECC_vli_sub(uECC_word_t *result,
|
||||
|
||||
#if !asm_mult || (uECC_SQUARE_FUNC && !asm_square) || \
|
||||
(uECC_SUPPORTS_secp256k1 && (uECC_OPTIMIZATION_LEVEL > 0) && \
|
||||
- ((uECC_WORD_SIZE == 1) || (uECC_WORD_SIZE == 8)))
|
||||
+ (uECC_WORD_SIZE == 8))
|
||||
static void muladd(uECC_word_t a,
|
||||
uECC_word_t b,
|
||||
uECC_word_t *r0,
|
||||
--
|
||||
2.7.4
|
||||
|
@ -1,26 +0,0 @@
|
||||
From bea5d775b9a6c0587002fdc70d98f3db6900c8ea Mon Sep 17 00:00:00 2001
|
||||
From: Mathias Tausig <mathias.tausig@fh-campuswien.ac.at>
|
||||
Date: Mon, 7 Mar 2016 16:28:40 +0100
|
||||
Subject: [PATCH 3/3] Use the parameter curve instead of the static reference
|
||||
so curve_secp224r1 (to prevent a compiler warning)
|
||||
|
||||
---
|
||||
curve-specific.inc | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/curve-specific.inc b/curve-specific.inc
|
||||
index 81f725f..137855e 100644
|
||||
--- a/curve-specific.inc
|
||||
+++ b/curve-specific.inc
|
||||
@@ -563,7 +563,7 @@ static void mod_sqrt_secp224r1(uECC_word_t *a, uECC_Curve curve) {
|
||||
}
|
||||
}
|
||||
uECC_vli_modInv(f1, e0, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- 1 / e0 */
|
||||
- uECC_vli_modMult_fast(a, d0, f1, &curve_secp224r1); /* a <-- d0 / e0 */
|
||||
+ uECC_vli_modMult_fast(a, d0, f1, curve); /* a <-- d0 / e0 */
|
||||
}
|
||||
#endif /* uECC_SUPPORT_COMPRESSED_POINT */
|
||||
|
||||
--
|
||||
2.5.0
|
||||
|
@ -0,0 +1,10 @@
|
||||
APPLICATION = pkg_micro-ecc-with-hwrng
|
||||
include ../Makefile.tests_common
|
||||
|
||||
FEATURES_REQUIRED = periph_hwrng
|
||||
|
||||
USEPKG += micro-ecc
|
||||
|
||||
CFLAGS += -DFEATURE_PERIPH_HWRNG
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
@ -0,0 +1,122 @@
|
||||
/*-
|
||||
* Copyright 2014 Kenneth MacKay
|
||||
* Copyright 2014 Frank Holtz
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Check if the micro-ecc builds and working
|
||||
*
|
||||
* @author Frank Holtz <frank-riot2015@holtznet.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "uECC.h"
|
||||
#include "periph/hwrng.h"
|
||||
|
||||
#define TESTROUNDS 16
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("micro-ecc compiled!\n");
|
||||
|
||||
const struct uECC_Curve_t *curve = uECC_secp256r1();
|
||||
int i, errorc = 0;
|
||||
|
||||
int curve_size = uECC_curve_private_key_size(curve);
|
||||
int public_key_size = uECC_curve_public_key_size(curve);
|
||||
|
||||
uint8_t l_secret1[curve_size];
|
||||
uint8_t l_secret2[curve_size];
|
||||
|
||||
/* reserve space for a SHA-256 hash */
|
||||
uint8_t l_hash[32] = { 0 };
|
||||
|
||||
uint8_t l_sig[public_key_size];
|
||||
|
||||
printf("Testing %d random private key pairs and signature using HWRNG\n", TESTROUNDS);
|
||||
|
||||
/* initialize hardware random number generator */
|
||||
hwrng_init();
|
||||
|
||||
uint8_t l_private1[curve_size];
|
||||
uint8_t l_private2[curve_size];
|
||||
|
||||
uint8_t l_public1[public_key_size];
|
||||
uint8_t l_public2[public_key_size];
|
||||
|
||||
for (i = 0; i < TESTROUNDS; ++i) {
|
||||
printf(".");
|
||||
|
||||
if (!uECC_make_key(l_public1, l_private1, curve) || !uECC_make_key(l_public2, l_private2, curve)) {
|
||||
printf("\nRound %d: uECC_make_key() failed", i);
|
||||
errorc++;
|
||||
}
|
||||
else {
|
||||
if (!uECC_shared_secret(l_public2, l_private1, l_secret1, curve)) {
|
||||
printf("\nRound %d: shared_secret() failed (1)", i);
|
||||
errorc++;
|
||||
}
|
||||
else {
|
||||
if (!uECC_shared_secret(l_public1, l_private2, l_secret2, curve)) {
|
||||
printf("\nRound: %d: shared_secret() failed (2)", i);
|
||||
errorc++;
|
||||
}
|
||||
else {
|
||||
if (memcmp(l_secret1, l_secret2, sizeof(l_secret1)) != 0) {
|
||||
printf("\nShared secrets are not identical!\n");
|
||||
errorc++;
|
||||
}
|
||||
|
||||
/* copy some bogus data into the hash */
|
||||
memcpy(l_hash, l_public1, 32);
|
||||
|
||||
if ((uECC_sign(l_private1, l_hash, sizeof(l_hash), l_sig, curve)) != 1) {
|
||||
printf("\nRound %d: uECC_sign() failed", i);
|
||||
errorc++;
|
||||
}
|
||||
else {
|
||||
if ((uECC_verify(l_public1, l_hash, sizeof(l_hash), l_sig, curve)) != 1) {
|
||||
printf("\nRound %d: uECC_verify() failed", i);
|
||||
errorc++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf(" done with %d error(s)\n", errorc);
|
||||
|
||||
if (errorc == 0) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
return 1;
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
APPLICATION = pkg_micro-ecc
|
||||
include ../Makefile.tests_common
|
||||
|
||||
USEMODULE += hashes
|
||||
USEPKG += micro-ecc
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
||||
|
Loading…
Reference in New Issue