1 #include "internal.h"
2 #include <include/wally_crypto.h>
3 #include "ccan/ccan/build_assert/build_assert.h"
4 #include "ccan/ccan/crypto/ripemd160/ripemd160.h"
5 #include "ccan/ccan/crypto/sha256/sha256.h"
6 #include "ccan/ccan/crypto/sha512/sha512.h"
7 #include "ccan/ccan/endian/endian.h"
8 #include <stdbool.h>
9
10 #undef malloc
11 #undef free
12
13 #if defined(_WIN32)
14 #define WIN32_LEAN_AND_MEAN
15 #include <windows.h>
16 #undef WIN32_LEAN_AND_MEAN
17 #endif
18
19 /* Caller is responsible for thread safety */
20 static secp256k1_context *global_ctx = NULL;
21
privkey_tweak_add(unsigned char * seckey,const unsigned char * tweak)22 int privkey_tweak_add(unsigned char *seckey, const unsigned char *tweak)
23 {
24 return secp256k1_ec_privkey_tweak_add(secp256k1_context_no_precomp, seckey, tweak);
25 }
26
pubkey_combine(secp256k1_pubkey * pubnonce,const secp256k1_pubkey * const * pubnonces,size_t n)27 int pubkey_combine(secp256k1_pubkey *pubnonce, const secp256k1_pubkey *const *pubnonces, size_t n)
28 {
29 return secp256k1_ec_pubkey_combine(secp256k1_context_no_precomp, pubnonce, pubnonces, n);
30 }
31
pubkey_negate(secp256k1_pubkey * pubkey)32 int pubkey_negate(secp256k1_pubkey *pubkey)
33 {
34 return secp256k1_ec_pubkey_negate(secp256k1_context_no_precomp, pubkey);
35 }
36
pubkey_parse(secp256k1_pubkey * pubkey,const unsigned char * input,size_t inputlen)37 int pubkey_parse(secp256k1_pubkey *pubkey, const unsigned char *input, size_t inputlen)
38 {
39 return secp256k1_ec_pubkey_parse(secp256k1_context_no_precomp, pubkey, input, inputlen);
40 }
41
pubkey_serialize(unsigned char * output,size_t * outputlen,const secp256k1_pubkey * pubkey,unsigned int flags)42 int pubkey_serialize(unsigned char *output, size_t *outputlen, const secp256k1_pubkey *pubkey, unsigned int flags)
43 {
44 return secp256k1_ec_pubkey_serialize(secp256k1_context_no_precomp, output, outputlen, pubkey, flags);
45 }
46
seckey_verify(const unsigned char * seckey)47 int seckey_verify(const unsigned char *seckey)
48 {
49 return secp256k1_ec_seckey_verify(secp256k1_context_no_precomp, seckey);
50 }
51
52 #ifndef SWIG
wally_get_secp_context(void)53 struct secp256k1_context_struct *wally_get_secp_context(void)
54 {
55 return (struct secp256k1_context_struct *)secp_ctx();
56 }
57 #endif
58
wally_secp_randomize(const unsigned char * bytes,size_t bytes_len)59 int wally_secp_randomize(const unsigned char *bytes, size_t bytes_len)
60 {
61 secp256k1_context *ctx;
62
63 if (!bytes || bytes_len != WALLY_SECP_RANDOMIZE_LEN)
64 return WALLY_EINVAL;
65
66 if (!(ctx = (secp256k1_context *)secp_ctx()))
67 return WALLY_ENOMEM;
68
69 if (!secp256k1_context_randomize(ctx, bytes))
70 return WALLY_ERROR;
71
72 return WALLY_OK;
73 }
74
wally_free_string(char * str)75 int wally_free_string(char *str)
76 {
77 if (!str)
78 return WALLY_EINVAL;
79 wally_clear(str, strlen(str));
80 wally_free(str);
81 return WALLY_OK;
82 }
83
wally_bzero(void * bytes,size_t len)84 int wally_bzero(void *bytes, size_t len)
85 {
86 if (!bytes)
87 return WALLY_EINVAL;
88 wally_clear(bytes, len);
89 return WALLY_OK;
90 }
91
wally_sha256(const unsigned char * bytes,size_t bytes_len,unsigned char * bytes_out,size_t len)92 int wally_sha256(const unsigned char *bytes, size_t bytes_len,
93 unsigned char *bytes_out, size_t len)
94 {
95 struct sha256 sha;
96 bool aligned = alignment_ok(bytes_out, sizeof(sha.u.u32));
97
98 if ((!bytes && bytes_len != 0) || !bytes_out || len != SHA256_LEN)
99 return WALLY_EINVAL;
100
101 sha256(aligned ? (struct sha256 *)bytes_out : &sha, bytes, bytes_len);
102 if (!aligned) {
103 memcpy(bytes_out, &sha, sizeof(sha));
104 wally_clear(&sha, sizeof(sha));
105 }
106 return WALLY_OK;
107 }
108
sha256_midstate(struct sha256_ctx * ctx,struct sha256 * res)109 static void sha256_midstate(struct sha256_ctx *ctx, struct sha256 *res)
110 {
111 size_t i;
112
113 for (i = 0; i < sizeof(ctx->s) / sizeof(ctx->s[0]); i++)
114 res->u.u32[i] = cpu_to_be32(ctx->s[i]);
115 ctx->bytes = (size_t)-1;
116 }
117
wally_sha256_midstate(const unsigned char * bytes,size_t bytes_len,unsigned char * bytes_out,size_t len)118 int wally_sha256_midstate(const unsigned char *bytes, size_t bytes_len,
119 unsigned char *bytes_out, size_t len)
120 {
121 struct sha256 sha;
122 struct sha256_ctx ctx;
123 bool aligned = alignment_ok(bytes_out, sizeof(sha.u.u32));
124
125 if ((!bytes && bytes_len != 0) || !bytes_out || len != SHA256_LEN)
126 return WALLY_EINVAL;
127
128 sha256_init(&ctx);
129 sha256_update(&ctx, bytes, bytes_len);
130 sha256_midstate(&ctx, aligned ? (struct sha256 *)bytes_out : &sha);
131 wally_clear(&ctx, sizeof(ctx));
132
133 if (!aligned) {
134 memcpy(bytes_out, &sha, sizeof(sha));
135 wally_clear(&sha, sizeof(sha));
136 }
137 return WALLY_OK;
138 }
139
wally_sha256d(const unsigned char * bytes,size_t bytes_len,unsigned char * bytes_out,size_t len)140 int wally_sha256d(const unsigned char *bytes, size_t bytes_len,
141 unsigned char *bytes_out, size_t len)
142 {
143 struct sha256 sha_1, sha_2;
144 bool aligned = alignment_ok(bytes_out, sizeof(sha_1.u.u32));
145
146 if ((!bytes && bytes_len != 0) || !bytes_out || len != SHA256_LEN)
147 return WALLY_EINVAL;
148
149 sha256(&sha_1, bytes, bytes_len);
150 sha256(aligned ? (struct sha256 *)bytes_out : &sha_2, &sha_1, sizeof(sha_1));
151 if (!aligned) {
152 memcpy(bytes_out, &sha_2, sizeof(sha_2));
153 wally_clear(&sha_2, sizeof(sha_2));
154 }
155 wally_clear(&sha_1, sizeof(sha_1));
156 return WALLY_OK;
157 }
158
wally_sha512(const unsigned char * bytes,size_t bytes_len,unsigned char * bytes_out,size_t len)159 int wally_sha512(const unsigned char *bytes, size_t bytes_len,
160 unsigned char *bytes_out, size_t len)
161 {
162 struct sha512 sha;
163 bool aligned = alignment_ok(bytes_out, sizeof(sha.u.u64));
164
165 if ((!bytes && bytes_len != 0) || !bytes_out || len != SHA512_LEN)
166 return WALLY_EINVAL;
167
168 sha512(aligned ? (struct sha512 *)bytes_out : &sha, bytes, bytes_len);
169 if (!aligned) {
170 memcpy(bytes_out, &sha, sizeof(sha));
171 wally_clear(&sha, sizeof(sha));
172 }
173 return WALLY_OK;
174 }
175
wally_hash160(const unsigned char * bytes,size_t bytes_len,unsigned char * bytes_out,size_t len)176 int wally_hash160(const unsigned char *bytes, size_t bytes_len,
177 unsigned char *bytes_out, size_t len)
178 {
179 unsigned char buff[SHA256_LEN];
180 struct ripemd160 ripemd;
181 const bool aligned = alignment_ok(bytes_out, sizeof(ripemd.u.u32));
182
183 if (!bytes_out || len != HASH160_LEN)
184 return WALLY_EINVAL;
185
186 BUILD_ASSERT(sizeof(ripemd) == HASH160_LEN);
187
188 if (wally_sha256(bytes, bytes_len, buff, sizeof(buff)) != WALLY_OK)
189 return WALLY_EINVAL;
190
191 ripemd160(aligned ? (struct ripemd160 *)bytes_out : &ripemd, &buff, sizeof(buff));
192 if (!aligned) {
193 memcpy(bytes_out, &ripemd, sizeof(ripemd));
194 wally_clear(&ripemd, sizeof(ripemd));
195 }
196 wally_clear(&buff, sizeof(buff));
197 return WALLY_OK;
198 }
199
200 /*
201 * For clang 7.0.1 and up it may be useful to disable the memset builtin for this code to not be elided when on -O3.
202 * The following program can be used to check what your compiler is doing.
203 * printf "#include <string.h> \n int main() { unsigned char s[10]; memset(s, 0, sizeof(s)); }" | clang -O3 -fno-builtin-memset -o memset.ll -S -emit-llvm -x c -
204 */
wally_internal_bzero(void * dest,size_t len)205 static void wally_internal_bzero(void *dest, size_t len)
206 {
207 #ifdef _WIN32
208 SecureZeroMemory(dest, len);
209 #elif defined(HAVE_MEMSET_S)
210 memset_s(dest, len, 0, len);
211 #elif defined(HAVE_EXPLICIT_BZERO)
212 explicit_bzero(dest, len);
213 #elif defined(HAVE_EXPLICIT_MEMSET)
214 explicit_memset(dest, 0, len);
215 #else
216 memset(dest, 0, len);
217 #if defined(HAVE_INLINE_ASM)
218 /* This is used by boringssl to prevent memset from being elided. It
219 * works by forcing a memory barrier and so can be slow.
220 */
221 __asm__ __volatile__ ("" : : "r" (dest) : "memory");
222 #endif
223 #endif
224 }
225
wally_internal_malloc(size_t size)226 static void *wally_internal_malloc(size_t size)
227 {
228 return malloc(size);
229 }
230
wally_internal_free(void * ptr)231 static void wally_internal_free(void *ptr)
232 {
233 if (ptr)
234 free(ptr);
235 }
236
wally_internal_ec_nonce_fn(unsigned char * nonce32,const unsigned char * msg32,const unsigned char * key32,const unsigned char * algo16,void * data,unsigned int attempt)237 static int wally_internal_ec_nonce_fn(unsigned char *nonce32,
238 const unsigned char *msg32, const unsigned char *key32,
239 const unsigned char *algo16, void *data, unsigned int attempt)
240 {
241 return secp256k1_nonce_function_default(nonce32, msg32, key32, algo16, data, attempt);
242 }
243
wally_get_new_secp_context(void)244 struct secp256k1_context_struct *wally_get_new_secp_context(void)
245 {
246 return secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN);
247 }
248
wally_internal_secp_context(void)249 struct secp256k1_context_struct *wally_internal_secp_context(void)
250 {
251 /* Default implementation uses a lazy-initialized global context,
252 * this should be fetched or set by the caller before any threads
253 * are created in order to be thread-safe. */
254 if (!global_ctx)
255 global_ctx = wally_get_new_secp_context();
256
257 return global_ctx;
258 }
259
260 static struct wally_operations _ops = {
261 sizeof(struct wally_operations),
262 wally_internal_malloc,
263 wally_internal_free,
264 wally_internal_bzero,
265 wally_internal_ec_nonce_fn,
266 wally_internal_secp_context,
267 NULL,
268 NULL,
269 NULL,
270 NULL
271 };
272
secp_ctx(void)273 const secp256k1_context *secp_ctx(void)
274 {
275 return (const secp256k1_context *)_ops.secp_context_fn();
276 }
277
wally_malloc(size_t size)278 void *wally_malloc(size_t size)
279 {
280 return _ops.malloc_fn(size);
281 }
282
wally_calloc(size_t size)283 void *wally_calloc(size_t size)
284 {
285 void *p = _ops.malloc_fn(size);
286 (void) wally_bzero(p, size);
287 return p;
288 }
289
wally_free(void * ptr)290 void wally_free(void *ptr)
291 {
292 _ops.free_fn(ptr);
293 }
294
wally_strdup(const char * str)295 char *wally_strdup(const char *str)
296 {
297 size_t len = strlen(str) + 1;
298 char *new_str = (char *)wally_malloc(len);
299 if (new_str)
300 memcpy(new_str, str, len); /* Copies terminating nul */
301 return new_str;
302 }
303
wally_ops(void)304 const struct wally_operations *wally_ops(void)
305 {
306 return &_ops;
307 }
308
wally_get_operations(struct wally_operations * output)309 int wally_get_operations(struct wally_operations *output)
310 {
311 if (!output || output->struct_size != sizeof(struct wally_operations))
312 return WALLY_EINVAL;
313 memcpy(output, &_ops, sizeof(_ops));
314 return WALLY_OK;
315 }
316
wally_set_operations(const struct wally_operations * ops)317 int wally_set_operations(const struct wally_operations *ops)
318 {
319 if (!ops || ops->struct_size != sizeof(struct wally_operations))
320 return WALLY_EINVAL; /* Null or invalid version of ops */
321 /* Reserved pointers must be null so they can be enabled in the
322 * future without breaking back compatibility */
323 if (ops->reserved_1 || ops->reserved_2 || ops->reserved_3 || ops->reserved_4)
324 return WALLY_EINVAL;
325
326 #define COPY_FN_PTR(name) if (ops->name) _ops.name = ops->name
327 COPY_FN_PTR(malloc_fn);
328 COPY_FN_PTR(free_fn);
329 COPY_FN_PTR (bzero_fn);
330 COPY_FN_PTR (ec_nonce_fn);
331 COPY_FN_PTR (secp_context_fn);
332 #undef COPY_FN_PTR
333 return WALLY_OK;
334 }
335
wally_is_elements_build(size_t * written)336 int wally_is_elements_build(size_t *written)
337 {
338 if (!written)
339 return WALLY_EINVAL;
340 #ifdef BUILD_ELEMENTS
341 *written = 1;
342 #else
343 *written = 0;
344 #endif
345 return WALLY_OK;
346 }
347
wally_clear(void * p,size_t len)348 void wally_clear(void *p, size_t len){
349 _ops.bzero_fn(p, len);
350 }
351
wally_clear_2(void * p,size_t len,void * p2,size_t len2)352 void wally_clear_2(void *p, size_t len, void *p2, size_t len2){
353 _ops.bzero_fn(p, len);
354 _ops.bzero_fn(p2, len2);
355 }
356
wally_clear_3(void * p,size_t len,void * p2,size_t len2,void * p3,size_t len3)357 void wally_clear_3(void *p, size_t len, void *p2, size_t len2,
358 void *p3, size_t len3){
359 _ops.bzero_fn(p, len);
360 _ops.bzero_fn(p2, len2);
361 _ops.bzero_fn(p3, len3);
362 }
363
wally_clear_4(void * p,size_t len,void * p2,size_t len2,void * p3,size_t len3,void * p4,size_t len4)364 void wally_clear_4(void *p, size_t len, void *p2, size_t len2,
365 void *p3, size_t len3, void *p4, size_t len4){
366 _ops.bzero_fn(p, len);
367 _ops.bzero_fn(p2, len2);
368 _ops.bzero_fn(p3, len3);
369 _ops.bzero_fn(p4, len4);
370 }
371
clear_and_free(void * p,size_t len)372 void clear_and_free(void *p, size_t len)
373 {
374 if (p) {
375 wally_clear(p, len);
376 wally_free(p);
377 }
378 }
379
380 static bool wally_init_done = false;
381
wally_init(uint32_t flags)382 int wally_init(uint32_t flags)
383 {
384 if (flags)
385 return WALLY_EINVAL;
386
387 if (!wally_init_done) {
388 sha256_optimize();
389 wally_init_done = true;
390 }
391
392 return WALLY_OK;
393 }
394
wally_cleanup(uint32_t flags)395 int wally_cleanup(uint32_t flags)
396 {
397 if (flags)
398 return WALLY_EINVAL;
399 if (global_ctx) {
400 wally_secp_context_free(global_ctx);
401 global_ctx = NULL;
402 }
403 return WALLY_OK;
404 }
405
wally_secp_context_free(struct secp256k1_context_struct * ctx)406 void wally_secp_context_free(struct secp256k1_context_struct *ctx)
407 {
408 #undef secp256k1_context_destroy
409 if (ctx)
410 secp256k1_context_destroy(ctx);
411 }
412
413 #ifdef __ANDROID__
414 #define malloc(size) wally_malloc(size)
415 #define free(ptr) wally_free(ptr)
416 #include "cpufeatures/cpu-features.c"
417 #endif
418