diff --git a/Makefile b/Makefile index 2202e10c3c22..07ab6aecf4f7 100644 --- a/Makefile +++ b/Makefile @@ -177,7 +177,7 @@ CWARNFLAGS := -Werror -Wall -Wundef -Wmissing-prototypes -Wmissing-declarations CDEBUGFLAGS := -g -fstack-protector CFLAGS := $(CWARNFLAGS) $(CDEBUGFLAGS) -I $(CCANDIR) -I secp256k1/include/ -I . $(FEATURES) -LDLIBS := -lcrypto -lprotobuf-c -lgmp -lsodium +LDLIBS := -lprotobuf-c -lgmp -lsodium -lbase58 $(PROGRAMS): CFLAGS+=-I. default: $(PROGRAMS) daemon-all diff --git a/bitcoin/base58.c b/bitcoin/base58.c index ab570a4bce17..d745c8f24003 100644 --- a/bitcoin/base58.c +++ b/bitcoin/base58.c @@ -11,149 +11,28 @@ #include #include #include -#include #include #include +#include -static const char enc_16[] = "0123456789abcdef"; -static const char enc_58[] = - "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; - -static char encode_char(unsigned long val, const char *enc) -{ - assert(val < strlen(enc)); - return enc[val]; -} - -static int decode_char(char c, const char *enc) -{ - const char *pos = strchr(enc, c); - if (!pos) - return -1; - return pos - enc; -} - -/* - * Encode a byte sequence as a base58-encoded string. This is a bit - * weird: returns pointer into buf (or NULL if wouldn't fit). - */ -static char *encode_base58(char *buf, size_t buflen, - const u8 *data, size_t data_len) -{ - char *p; - BIGNUM bn; - - /* Convert to a bignum. */ - BN_init(&bn); - BN_bin2bn(data, data_len, &bn); - - /* Add NUL terminator */ - if (!buflen) { - p = NULL; - goto out; - } - p = buf + buflen; - *(--p) = '\0'; - - /* Fill from the back, using a series of divides. */ - while (!BN_is_zero(&bn)) { - int rem = BN_div_word(&bn, 58); - if (--p < buf) { - p = NULL; - goto out; - } - *p = encode_char(rem, enc_58); - } - - /* Now, this is really weird. We pad with zeroes, but not at - * base 58, but in terms of zero bytes. This means that some - * encodings are shorter than others! */ - while (data_len && *data == '\0') { - if (--p < buf) { - p = NULL; - goto out; - } - *p = encode_char(0, enc_58); - data_len--; - data++; - } - -out: - BN_free(&bn); - return p; -} - -/* - * Decode a base_n-encoded string into a byte sequence. - */ -bool raw_decode_base_n(BIGNUM *bn, const char *src, size_t len, int base) +static bool my_sha256(void *digest, const void *data, size_t datasz) { - const char *enc; - - BN_zero(bn); - - assert(base == 16 || base == 58); - switch (base) { - case 16: - enc = enc_16; - break; - case 58: - enc = enc_58; - break; - } - - while (len) { - char current = *src; - - if (base == 16) - current = tolower(current); /* TODO: Not in ccan. */ - int val = decode_char(current, enc); - if (val < 0) { - BN_free(bn); - return false; - } - BN_mul_word(bn, base); - BN_add_word(bn, val); - src++; - len--; - } - + sha256(digest, data, datasz); return true; } -/* - * Decode a base58-encoded string into a byte sequence. - */ -bool raw_decode_base58(BIGNUM *bn, const char *src, size_t len) -{ - return raw_decode_base_n(bn, src, len, 58); -} - -void base58_get_checksum(u8 csum[4], const u8 buf[], size_t buflen) -{ - struct sha256_double sha_result; - - /* Form checksum, using double SHA2 (as per bitcoin standard) */ - sha256_double(&sha_result, buf, buflen); - - /* Use first four bytes of that as the checksum. */ - memcpy(csum, sha_result.sha.u.u8, 4); -} - static char *to_base58(const tal_t *ctx, u8 version, const struct ripemd160 *rmd) { - u8 buf[1 + sizeof(*rmd) + 4]; - char out[BASE58_ADDR_MAX_LEN + 2], *p; - - buf[0] = version; - memcpy(buf+1, rmd, sizeof(*rmd)); - - /* Append checksum */ - base58_get_checksum(buf + 1 + sizeof(*rmd), buf, 1 + sizeof(*rmd)); + char out[BASE58_ADDR_MAX_LEN + 1]; + size_t outlen = sizeof(out); - p = encode_base58(out, BASE58_ADDR_MAX_LEN, buf, sizeof(buf)); - return tal_strdup(ctx, p); + b58_sha256_impl = my_sha256; + if (!b58check_enc(out, &outlen, version, rmd, sizeof(*rmd))) { + return NULL; + }else{ + return tal_strdup(ctx, out); + } } char *bitcoin_to_base58(const tal_t *ctx, bool test_net, @@ -173,30 +52,15 @@ static bool from_base58(u8 *version, const char *base58, size_t base58_len) { u8 buf[1 + sizeof(*rmd) + 4]; - BIGNUM bn; - size_t len; - u8 csum[4]; - - BN_init(&bn); - if (!raw_decode_base58(&bn, base58, base58_len)) - return false; - - len = BN_num_bytes(&bn); - if (len > sizeof(buf)) - return false; - memset(buf, 0, sizeof(buf)); - BN_bn2bin(&bn, buf + sizeof(buf) - len); - BN_free(&bn); + b58_sha256_impl = my_sha256; + size_t buflen = sizeof(buf); + b58tobin(buf, &buflen, base58, base58_len); + int r = b58check(buf, sizeof(buf), base58, base58_len); *version = buf[0]; - - base58_get_checksum(csum, buf, 1 + sizeof(*rmd)); - if (memcmp(csum, buf + 1 + sizeof(*rmd), sizeof(csum)) != 0) - return false; - - memcpy(rmd, buf+1, sizeof(*rmd)); - return true; + memcpy(rmd, buf + 1, sizeof(*rmd)); + return r > 0; } bool bitcoin_from_base58(bool *test_net, @@ -235,124 +99,60 @@ bool p2sh_from_base58(bool *test_net, return true; } -/* buf already contains version and ripemd160. Append checksum and encode */ -char *base58_with_check(char dest[BASE58_ADDR_MAX_LEN], - u8 buf[1 + sizeof(struct ripemd160) + 4]) -{ - /* Append checksum */ - base58_get_checksum(buf + 1 + sizeof(struct ripemd160), - buf, 1 + sizeof(struct ripemd160)); - - /* Now encode. */ - return encode_base58(dest, BASE58_ADDR_MAX_LEN, buf, - 1 + sizeof(struct ripemd160) + 4); -} - bool ripemd_from_base58(u8 *version, struct ripemd160 *ripemd160, const char *base58) { - u8 buf[1 + sizeof(*ripemd160) + 4]; - u8 csum[4]; - BIGNUM bn; - size_t len; - - /* Too long? Check here before doing arithmetic. */ - if (strlen(base58) > BASE58_ADDR_MAX_LEN - 1) - return false; - - BN_init(&bn); - /* Fails if it contains invalid characters. */ - if (!raw_decode_base58(&bn, base58, strlen(base58))) - return false; - - /* Too big? */ - len = BN_num_bytes(&bn); - if (len > sizeof(buf)) { - BN_free(&bn); - return false; - } - - /* Fill start with zeroes. */ - memset(buf, 0, sizeof(buf) - len); - BN_bn2bin(&bn, buf + sizeof(buf) - len); - BN_free(&bn); - - /* Check checksum is correct. */ - base58_get_checksum(csum, buf, sizeof(buf)); - if (memcmp(csum, buf + 1 + sizeof(*ripemd160), 4) != 0) - return false; - - *version = buf[0]; - memcpy(ripemd160, buf + 1, sizeof(*ripemd160)); - return true; + return from_base58(version, ripemd160, base58, strlen(base58)); } char *key_to_base58(const tal_t *ctx, bool test_net, const struct privkey *key) { - u8 buf[1 + 32 + 1 + 4]; - char out[BASE58_KEY_MAX_LEN + 2], *p; - - buf[0] = test_net ? 239 : 128; - memcpy(buf + 1, key->secret, sizeof(key->secret)); + u8 buf[32 + 1]; + char out[BASE58_KEY_MAX_LEN + 2]; + u8 version = test_net ? 239 : 128; + size_t outlen = sizeof(out); + memcpy(buf, key->secret, sizeof(key->secret)); /* Mark this as a compressed key. */ - buf[1 + 32] = 1; + buf[32] = 1; - /* Append checksum */ - base58_get_checksum(buf + 1 + 32 + 1, buf, 1 + 32 + 1); - - p = encode_base58(out, BASE58_KEY_MAX_LEN, buf, sizeof(buf)); - return tal_strdup(ctx, p); + b58check_enc(out, &outlen, version, buf, sizeof(buf)); + return tal_strdup(ctx, out); } bool key_from_base58(secp256k1_context *secpctx, const char *base58, size_t base58_len, bool *test_net, struct privkey *priv, struct pubkey *key) { + // 1 byte version, 32 byte private key, 1 byte compressed, 4 byte checksum u8 keybuf[1 + 32 + 1 + 4]; - u8 csum[4]; - BIGNUM bn; - size_t keylen; - - BN_init(&bn); - if (!raw_decode_base58(&bn, base58, base58_len)) - return false; - - keylen = BN_num_bytes(&bn); - if (keylen != 1 + 32 + 1 + 4) - goto fail_free_bn; - BN_bn2bin(&bn, keybuf); + size_t keybuflen = sizeof(keybuf); - base58_get_checksum(csum, keybuf, keylen - sizeof(csum)); - if (memcmp(csum, keybuf + keylen - sizeof(csum), sizeof(csum)) != 0) - goto fail_free_bn; + b58tobin(keybuf, &keybuflen, base58, base58_len); + if (b58check(keybuf, sizeof(keybuf), base58, base58_len) < 0) + return false; /* Byte after key should be 1 to represent a compressed key. */ if (keybuf[1 + 32] != 1) - goto fail_free_bn; + return false; if (keybuf[0] == 128) *test_net = false; else if (keybuf[0] == 239) *test_net = true; else - goto fail_free_bn; + return false; /* Copy out secret. */ memcpy(priv->secret, keybuf + 1, sizeof(priv->secret)); if (!secp256k1_ec_seckey_verify(secpctx, priv->secret)) - goto fail_free_bn; + return false; /* Get public key, too. */ if (!pubkey_from_privkey(secpctx, priv, key)) - goto fail_free_bn; + return false; - BN_free(&bn); return true; - -fail_free_bn: - BN_free(&bn); - return false; } diff --git a/test/test_onion.c b/test/test_onion.c index 78f13a1a1312..33c4a41627d8 100644 --- a/test/test_onion.c +++ b/test/test_onion.c @@ -1,12 +1,10 @@ #define _GNU_SOURCE 1 #include "onion_key.h" #include "version.h" -#include -#include -#include #include #include #include +#include #include #include #include @@ -20,6 +18,9 @@ #include #include #include +#include +#include +#include /* * The client knows the server's public key S (which has corresponding @@ -43,7 +44,7 @@ struct hmackey { }; struct iv { - unsigned char iv[AES_BLOCK_SIZE]; + unsigned char iv[crypto_stream_aes128ctr_NONCEBYTES]; }; static void sha_with_seed(const unsigned char secret[32], @@ -234,51 +235,13 @@ static struct hop *myhop(const struct onion *onion) static bool aes_encrypt(void *dst, const void *src, size_t len, const struct enckey *enckey, const struct iv *iv) { - EVP_CIPHER_CTX evpctx; - int outlen; - - /* Counter mode allows parallelism in future. */ - if (EVP_EncryptInit(&evpctx, EVP_aes_128_ctr(), - memcheck(enckey->k.u.u8, sizeof(enckey->k)), - memcheck(iv->iv, sizeof(iv->iv))) != 1) - return false; - - /* No padding, we're a multiple of 128 bits. */ - if (EVP_CIPHER_CTX_set_padding(&evpctx, 0) != 1) - return false; - - EVP_EncryptUpdate(&evpctx, dst, &outlen, memcheck(src, len), len); - assert(outlen == len); - /* Shouldn't happen (no padding) */ - if (EVP_EncryptFinal(&evpctx, dst, &outlen) != 1) - return false; - assert(outlen == 0); - return true; + return crypto_stream_aes128ctr_xor(dst, src, len, iv->iv, enckey->k.u.u8) == 0; } static bool aes_decrypt(void *dst, const void *src, size_t len, const struct enckey *enckey, const struct iv *iv) { - EVP_CIPHER_CTX evpctx; - int outlen; - - /* Counter mode allows parallelism in future. */ - if (EVP_DecryptInit(&evpctx, EVP_aes_128_ctr(), - memcheck(enckey->k.u.u8, sizeof(enckey->k)), - memcheck(iv->iv, sizeof(iv->iv))) != 1) - return false; - - /* No padding, we're a multiple of 128 bits. */ - if (EVP_CIPHER_CTX_set_padding(&evpctx, 0) != 1) - return false; - - EVP_DecryptUpdate(&evpctx, dst, &outlen, memcheck(src, len), len); - assert(outlen == len); - /* Shouldn't happen (no padding) */ - if (EVP_DecryptFinal(&evpctx, dst, &outlen) != 1) - return false; - assert(outlen == 0); - return true; + return crypto_stream_aes128ctr_xor(dst, src, len, iv->iv, enckey->k.u.u8) == 0; } #if 0 @@ -333,18 +296,14 @@ static void make_hmac(const struct hop *hops, size_t num_hops, const struct hmackey *hmackey, struct sha256 *hmac) { - HMAC_CTX ctx; - size_t len, padlen; - - /* Calculate HMAC of padding then onion up to and including pubkey. */ - HMAC_CTX_init(&ctx); - HMAC_Init_ex(&ctx, memcheck(hmackey->k.u.u8, sizeof(hmackey->k)), - sizeof(hmackey->k), EVP_sha256(), NULL); - padlen = (MAX_HOPS - num_hops) * sizeof(struct hop); - HMAC_Update(&ctx, memcheck((unsigned char *)padding, padlen), padlen); + crypto_auth_hmacsha256_state state; + size_t len, padlen = (MAX_HOPS - num_hops) * sizeof(struct hop); len = num_hops*sizeof(struct hop) - sizeof(hops->hmac); - HMAC_Update(&ctx, memcheck((unsigned char *)hops, len), len); - HMAC_Final(&ctx, hmac->u.u8, NULL); + crypto_auth_hmacsha256_init(&state, hmackey->k.u.u8, sizeof(hmackey->k)); + crypto_auth_hmacsha256_update(&state, memcheck((unsigned char *)padding, padlen), padlen); + crypto_auth_hmacsha256_update(&state, memcheck((unsigned char *)hops, len), len); + crypto_auth_hmacsha256_update(&state, memcheck((unsigned char *)padding, padlen), padlen); + crypto_auth_hmacsha256_final(&state, hmac->u.u8); } #if 0 @@ -370,7 +329,7 @@ static bool check_hmac(struct onion *onion, const struct hmackey *hmackey) struct sha256 hmac; make_hmac(onion->hop, MAX_HOPS, NULL, hmackey, &hmac); - return CRYPTO_memcmp(&hmac, &myhop(onion)->hmac, sizeof(hmac)) == 0; + return sodium_memcmp(&hmac, &myhop(onion)->hmac, sizeof(hmac)) == 0; } static bool create_onion(const secp256k1_pubkey pubkey[], @@ -385,7 +344,7 @@ static bool create_onion(const secp256k1_pubkey pubkey[], struct hmackey hmackeys[MAX_HOPS]; struct iv ivs[MAX_HOPS]; struct iv pad_ivs[MAX_HOPS]; - HMAC_CTX padding_hmac[MAX_HOPS]; + crypto_auth_hmacsha256_state padding_hmac[MAX_HOPS]; struct hop padding[MAX_HOPS]; size_t junk_hops; secp256k1_context *ctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); @@ -429,14 +388,13 @@ static bool create_onion(const secp256k1_pubkey pubkey[], } /* And generates more padding for next node. */ add_padding(&padding[0], &enckeys[i-1], &pad_ivs[i-1]); - HMAC_CTX_init(&padding_hmac[i]); - HMAC_Init_ex(&padding_hmac[i], - hmackeys[i].k.u.u8, sizeof(hmackeys[i].k), - EVP_sha256(), NULL); - HMAC_Update(&padding_hmac[i], - memcheck((unsigned char *)padding, - i * sizeof(struct hop)), - i * sizeof(struct hop)); + crypto_auth_hmacsha256_init(&padding_hmac[i], + hmackeys[i].k.u.u8, + sizeof(hmackeys[i].k)); + crypto_auth_hmacsha256_update(&padding_hmac[i], + memcheck((unsigned char *)padding, + i * sizeof(struct hop)), + i * sizeof(struct hop)); } /* @@ -475,9 +433,9 @@ static bool create_onion(const secp256k1_pubkey pubkey[], /* HMAC covers entire thing except hmac itself. */ len = (other_hops + 1)*sizeof(struct hop) - sizeof(myhop->hmac); - HMAC_Update(&padding_hmac[i], + crypto_auth_hmacsha256_update(&padding_hmac[i], memcheck((unsigned char *)onion, len), len); - HMAC_Final(&padding_hmac[i], myhop->hmac.u.u8, NULL); + crypto_auth_hmacsha256_final(&padding_hmac[i], myhop->hmac.u.u8); } ok = true; @@ -612,8 +570,6 @@ int main(int argc, char *argv[]) struct onion onion; bool generate = false, decode = false; - assert(EVP_CIPHER_iv_length(EVP_aes_128_ctr()) == sizeof(struct iv)); - opt_register_noarg("--help|-h", opt_usage_and_exit, "--generate ... OR\n" "--decode \n"