1 /*
2  * This module provides a thin abstraction over some of the crypto
3  * primitives to make it easier to swap out the used crypto library.
4  *
5  * At this point, there are two choices: MCUBOOT_USE_MBED_TLS, or
6  * MCUBOOT_USE_TINYCRYPT.  It is a compile error there is not exactly
7  * one of these defined.
8  */
9 
10 #ifndef __BOOTUTIL_CRYPTO_ECDH_P256_H_
11 #define __BOOTUTIL_CRYPTO_ECDH_P256_H_
12 
13 #include "mcuboot_config/mcuboot_config.h"
14 
15 #if (defined(MCUBOOT_USE_MBED_TLS) + \
16      defined(MCUBOOT_USE_TINYCRYPT)) != 1
17     #error "One crypto backend must be defined: either MBED_TLS or TINYCRYPT"
18 #endif
19 
20 #if defined(MCUBOOT_USE_MBED_TLS)
21     #include <mbedtls/ecp.h>
22     #include <mbedtls/ecdh.h>
23     #define EC256_PUBK_LEN (65)
24 #endif /* MCUBOOT_USE_MBED_TLS */
25 
26 #if defined(MCUBOOT_USE_TINYCRYPT)
27     #include <tinycrypt/ecc_dh.h>
28     #include <tinycrypt/constants.h>
29     #define BOOTUTIL_CRYPTO_ECDH_P256_HASH_SIZE (4 * 8)
30 #endif /* MCUBOOT_USE_TINYCRYPT */
31 
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35 
36 #if defined(MCUBOOT_USE_TINYCRYPT)
37 typedef uintptr_t bootutil_ecdh_p256_context;
bootutil_ecdh_p256_init(bootutil_ecdh_p256_context * ctx)38 static inline void bootutil_ecdh_p256_init(bootutil_ecdh_p256_context *ctx)
39 {
40     (void)ctx;
41 }
42 
bootutil_ecdh_p256_drop(bootutil_ecdh_p256_context * ctx)43 static inline void bootutil_ecdh_p256_drop(bootutil_ecdh_p256_context *ctx)
44 {
45     (void)ctx;
46 }
47 
bootutil_ecdh_p256_shared_secret(bootutil_ecdh_p256_context * ctx,const uint8_t * pk,const uint8_t * sk,uint8_t * z)48 static inline int bootutil_ecdh_p256_shared_secret(bootutil_ecdh_p256_context *ctx, const uint8_t *pk, const uint8_t *sk, uint8_t *z)
49 {
50     int rc;
51     (void)ctx;
52 
53     if (pk[0] != 0x04) {
54         return -1;
55     }
56 
57     rc = uECC_valid_public_key(&pk[1], uECC_secp256r1());
58     if (rc != 0) {
59         return -1;
60     }
61 
62     rc = uECC_shared_secret(&pk[1], sk, z, uECC_secp256r1());
63     if (rc != TC_CRYPTO_SUCCESS) {
64         return -1;
65     }
66     return 0;
67 }
68 #endif /* MCUBOOT_USE_TINYCRYPT */
69 
70 #if defined(MCUBOOT_USE_MBED_TLS)
71 #define NUM_ECC_BYTES 32
72 
73 #if MBEDTLS_VERSION_NUMBER >= 0x03000000
74 static int fake_rng(void *p_rng, unsigned char *output, size_t len);
75 #endif
76 
77 typedef struct bootutil_ecdh_p256_context {
78     mbedtls_ecp_group grp;
79     mbedtls_ecp_point P;
80     mbedtls_mpi z;
81     mbedtls_mpi d;
82 } bootutil_ecdh_p256_context;
83 
bootutil_ecdh_p256_init(bootutil_ecdh_p256_context * ctx)84 static inline void bootutil_ecdh_p256_init(bootutil_ecdh_p256_context *ctx)
85 {
86     mbedtls_mpi_init(&ctx->z);
87     mbedtls_mpi_init(&ctx->d);
88 
89     mbedtls_ecp_group_init(&ctx->grp);
90     mbedtls_ecp_point_init(&ctx->P);
91 
92     if (mbedtls_ecp_group_load(&ctx->grp, MBEDTLS_ECP_DP_SECP256R1) != 0) {
93         mbedtls_ecp_group_free(&ctx->grp);
94         mbedtls_ecp_point_free(&ctx->P);
95     }
96 }
97 
bootutil_ecdh_p256_drop(bootutil_ecdh_p256_context * ctx)98 static inline void bootutil_ecdh_p256_drop(bootutil_ecdh_p256_context *ctx)
99 {
100     mbedtls_mpi_free(&ctx->d);
101     mbedtls_mpi_free(&ctx->z);
102     mbedtls_ecp_group_free(&ctx->grp);
103     mbedtls_ecp_point_free(&ctx->P);
104 }
105 
bootutil_ecdh_p256_shared_secret(bootutil_ecdh_p256_context * ctx,const uint8_t * pk,const uint8_t * sk,uint8_t * z)106 static inline int bootutil_ecdh_p256_shared_secret(bootutil_ecdh_p256_context *ctx, const uint8_t *pk, const uint8_t *sk, uint8_t *z)
107 {
108     int rc;
109 
110     rc = mbedtls_ecp_point_read_binary(&ctx->grp,
111                                        &ctx->P,
112                                        pk,
113                                        EC256_PUBK_LEN);
114     if (rc != 0) {
115         mbedtls_ecp_group_free(&ctx->grp);
116         mbedtls_ecp_point_free(&ctx->P);
117         return -1;
118     }
119 
120     rc = mbedtls_ecp_check_pubkey(&ctx->grp, &ctx->P);
121     if (rc != 0) {
122         mbedtls_ecp_group_free(&ctx->grp);
123         mbedtls_ecp_point_free(&ctx->P);
124         return -1;
125     }
126 
127     mbedtls_mpi_read_binary(&ctx->d, sk, NUM_ECC_BYTES);
128 
129 #if MBEDTLS_VERSION_NUMBER >= 0x03000000
130     rc = mbedtls_ecdh_compute_shared(&ctx->grp,
131                                      &ctx->z,
132                                      &ctx->P,
133                                      &ctx->d,
134                                      fake_rng,
135                                      NULL);
136 #else
137     rc = mbedtls_ecdh_compute_shared(&ctx->grp,
138                                      &ctx->z,
139                                      &ctx->P,
140                                      &ctx->d,
141                                      NULL,
142                                      NULL);
143 #endif
144     mbedtls_mpi_write_binary(&ctx->z, z, NUM_ECC_BYTES);
145 
146     return rc;
147 }
148 #endif /* MCUBOOT_USE_MBED_TLS */
149 
150 #ifdef __cplusplus
151 }
152 #endif
153 
154 #endif /* __BOOTUTIL_CRYPTO_ECDH_P256_H_ */
155