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