Skip to content

Commit b89ef13

Browse files
committed
Merge #7689: Replace OpenSSL AES with ctaes-based version
723779c build: Enumerate ctaes rather than globbing (Cory Fields) 34ed64a crypter: add tests for crypter (Cory Fields) 0a36b9a crypter: shuffle Makefile so that crypto can be used by the wallet (Cory Fields) 976f9ec crypter: add a BytesToKey clone to replace the use of openssl (Cory Fields) 9049cde crypter: hook up the new aes cbc classes (Cory Fields) fb96831 crypter: constify encrypt/decrypt (Cory Fields) 1c391a5 crypter: fix the stored initialization vector size (Cory Fields) daa3841 crypto: add aes cbc tests (Cory Fields) 27a212d crypto: add AES 128/256 CBC classes (Cory Fields) 6bec172 Add ctaes-based constant time AES implementation (Pieter Wuille) a545127 Squashed 'src/crypto/ctaes/' content from commit cd3c3ac (Pieter Wuille)
2 parents 01d8359 + 723779c commit b89ef13

File tree

14 files changed

+1790
-78
lines changed

14 files changed

+1790
-78
lines changed

src/Makefile.am

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,12 @@ LIBUNIVALUE = $(UNIVALUE_LIBS)
1515
endif
1616

1717
BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config
18-
BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
18+
BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BDB_CPPFLAGS) $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS)
1919

2020
BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include
2121
BITCOIN_INCLUDES += $(UNIVALUE_CFLAGS)
2222

2323
LIBBITCOIN_SERVER=libbitcoin_server.a
24-
LIBBITCOIN_WALLET=libbitcoin_wallet.a
2524
LIBBITCOIN_COMMON=libbitcoin_common.a
2625
LIBBITCOIN_CONSENSUS=libbitcoin_consensus.a
2726
LIBBITCOIN_CLI=libbitcoin_cli.a
@@ -30,32 +29,32 @@ LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
3029
LIBBITCOINQT=qt/libbitcoinqt.a
3130
LIBSECP256K1=secp256k1/libsecp256k1.la
3231

32+
if ENABLE_ZMQ
33+
LIBBITCOIN_ZMQ=libbitcoin_zmq.a
34+
endif
35+
if BUILD_BITCOIN_LIBS
36+
LIBBITCOINCONSENSUS=libbitcoinconsensus.la
37+
endif
38+
if ENABLE_WALLET
39+
LIBBITCOIN_WALLET=libbitcoin_wallet.a
40+
endif
41+
3342
$(LIBSECP256K1): $(wildcard secp256k1/src/*) $(wildcard secp256k1/include/*)
3443
$(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C $(@D) $(@F)
3544

3645
# Make is not made aware of per-object dependencies to avoid limiting building parallelization
3746
# But to build the less dependent modules first, we manually select their order here:
3847
EXTRA_LIBRARIES += \
39-
crypto/libbitcoin_crypto.a \
40-
libbitcoin_util.a \
41-
libbitcoin_common.a \
42-
libbitcoin_consensus.a \
43-
libbitcoin_server.a \
44-
libbitcoin_cli.a
45-
if ENABLE_WALLET
46-
BITCOIN_INCLUDES += $(BDB_CPPFLAGS)
47-
EXTRA_LIBRARIES += libbitcoin_wallet.a
48-
endif
49-
if ENABLE_ZMQ
50-
EXTRA_LIBRARIES += libbitcoin_zmq.a
51-
endif
48+
$(LIBBITCOIN_CRYPTO) \
49+
$(LIBBITCOIN_UTIL) \
50+
$(LIBBITCOIN_COMMON) \
51+
$(LIBBITCOIN_CONSENSUS) \
52+
$(LIBBITCOIN_SERVER) \
53+
$(LIBBITCOIN_CLI) \
54+
$(LIBBITCOIN_WALLET) \
55+
$(LIBBITCOIN_ZMQ)
5256

53-
if BUILD_BITCOIN_LIBS
54-
lib_LTLIBRARIES = libbitcoinconsensus.la
55-
LIBBITCOINCONSENSUS=libbitcoinconsensus.la
56-
else
57-
LIBBITCOINCONSENSUS=
58-
endif
57+
lib_LTLIBRARIES = $(LIBBITCOINCONSENSUS)
5958

6059
bin_PROGRAMS =
6160
TESTS =
@@ -196,8 +195,6 @@ libbitcoin_server_a_SOURCES = \
196195
$(BITCOIN_CORE_H)
197196

198197
if ENABLE_ZMQ
199-
LIBBITCOIN_ZMQ=libbitcoin_zmq.a
200-
201198
libbitcoin_zmq_a_CPPFLAGS = $(BITCOIN_INCLUDES) $(ZMQ_CFLAGS)
202199
libbitcoin_zmq_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
203200
libbitcoin_zmq_a_SOURCES = \
@@ -225,6 +222,8 @@ libbitcoin_wallet_a_SOURCES = \
225222
crypto_libbitcoin_crypto_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_CONFIG_INCLUDES)
226223
crypto_libbitcoin_crypto_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
227224
crypto_libbitcoin_crypto_a_SOURCES = \
225+
crypto/aes.cpp \
226+
crypto/aes.h \
228227
crypto/common.h \
229228
crypto/hmac_sha256.cpp \
230229
crypto/hmac_sha256.h \
@@ -345,21 +344,15 @@ bitcoind_LDADD = \
345344
$(LIBBITCOIN_COMMON) \
346345
$(LIBUNIVALUE) \
347346
$(LIBBITCOIN_UTIL) \
347+
$(LIBBITCOIN_WALLET) \
348+
$(LIBBITCOIN_ZMQ) \
348349
$(LIBBITCOIN_CONSENSUS) \
349350
$(LIBBITCOIN_CRYPTO) \
350351
$(LIBLEVELDB) \
351352
$(LIBMEMENV) \
352353
$(LIBSECP256K1)
353354

354-
if ENABLE_ZMQ
355-
bitcoind_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
356-
endif
357-
358-
if ENABLE_WALLET
359-
bitcoind_LDADD += libbitcoin_wallet.a
360-
endif
361-
362-
bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
355+
bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS)
363356

364357
# bitcoin-cli binary #
365358
bitcoin_cli_SOURCES = bitcoin-cli.cpp
@@ -418,6 +411,12 @@ libbitcoinconsensus_la_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
418411
endif
419412
#
420413

414+
CTAES_DIST = crypto/ctaes/bench.c
415+
CTAES_DIST += crypto/ctaes/ctaes.c
416+
CTAES_DIST += crypto/ctaes/ctaes.h
417+
CTAES_DIST += crypto/ctaes/README.md
418+
CTAES_DIST += crypto/ctaes/test.c
419+
421420
CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a
422421
CLEANFILES += $(EXTRA_LIBRARIES)
423422
CLEANFILES += *.gcda *.gcno
@@ -435,7 +434,7 @@ CLEANFILES += zmq/*.gcda zmq/*.gcno
435434

436435
DISTCLEANFILES = obj/build.h
437436

438-
EXTRA_DIST = leveldb
437+
EXTRA_DIST = leveldb $(CTAES_DIST)
439438

440439
clean-local:
441440
-$(MAKE) -C leveldb clean

src/Makefile.test.include

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ BITCOIN_TESTS += \
9595
wallet/test/wallet_test_fixture.h \
9696
wallet/test/accounting_tests.cpp \
9797
wallet/test/wallet_tests.cpp \
98+
wallet/test/crypto_tests.cpp \
9899
wallet/test/rpc_wallet_tests.cpp
99100
endif
100101

src/crypto/aes.cpp

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
// Copyright (c) 2016 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include "aes.h"
6+
#include "crypto/common.h"
7+
8+
#include <assert.h>
9+
#include <string.h>
10+
11+
extern "C" {
12+
#include "crypto/ctaes/ctaes.c"
13+
}
14+
15+
AES128Encrypt::AES128Encrypt(const unsigned char key[16])
16+
{
17+
AES128_init(&ctx, key);
18+
}
19+
20+
AES128Encrypt::~AES128Encrypt()
21+
{
22+
memset(&ctx, 0, sizeof(ctx));
23+
}
24+
25+
void AES128Encrypt::Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const
26+
{
27+
AES128_encrypt(&ctx, 1, ciphertext, plaintext);
28+
}
29+
30+
AES128Decrypt::AES128Decrypt(const unsigned char key[16])
31+
{
32+
AES128_init(&ctx, key);
33+
}
34+
35+
AES128Decrypt::~AES128Decrypt()
36+
{
37+
memset(&ctx, 0, sizeof(ctx));
38+
}
39+
40+
void AES128Decrypt::Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const
41+
{
42+
AES128_decrypt(&ctx, 1, plaintext, ciphertext);
43+
}
44+
45+
AES256Encrypt::AES256Encrypt(const unsigned char key[32])
46+
{
47+
AES256_init(&ctx, key);
48+
}
49+
50+
AES256Encrypt::~AES256Encrypt()
51+
{
52+
memset(&ctx, 0, sizeof(ctx));
53+
}
54+
55+
void AES256Encrypt::Encrypt(unsigned char ciphertext[16], const unsigned char plaintext[16]) const
56+
{
57+
AES256_encrypt(&ctx, 1, ciphertext, plaintext);
58+
}
59+
60+
AES256Decrypt::AES256Decrypt(const unsigned char key[32])
61+
{
62+
AES256_init(&ctx, key);
63+
}
64+
65+
AES256Decrypt::~AES256Decrypt()
66+
{
67+
memset(&ctx, 0, sizeof(ctx));
68+
}
69+
70+
void AES256Decrypt::Decrypt(unsigned char plaintext[16], const unsigned char ciphertext[16]) const
71+
{
72+
AES256_decrypt(&ctx, 1, plaintext, ciphertext);
73+
}
74+
75+
76+
template <typename T>
77+
static int CBCEncrypt(const T& enc, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)
78+
{
79+
int written = 0;
80+
int padsize = size % AES_BLOCKSIZE;
81+
unsigned char mixed[AES_BLOCKSIZE];
82+
83+
if (!data || !size || !out)
84+
return 0;
85+
86+
if (!pad && padsize != 0)
87+
return 0;
88+
89+
memcpy(mixed, iv, AES_BLOCKSIZE);
90+
91+
// Write all but the last block
92+
while (written + AES_BLOCKSIZE <= size) {
93+
for (int i = 0; i != AES_BLOCKSIZE; i++)
94+
mixed[i] ^= *data++;
95+
enc.Encrypt(out + written, mixed);
96+
memcpy(mixed, out + written, AES_BLOCKSIZE);
97+
written += AES_BLOCKSIZE;
98+
}
99+
if (pad) {
100+
// For all that remains, pad each byte with the value of the remaining
101+
// space. If there is none, pad by a full block.
102+
for (int i = 0; i != padsize; i++)
103+
mixed[i] ^= *data++;
104+
for (int i = padsize; i != AES_BLOCKSIZE; i++)
105+
mixed[i] ^= AES_BLOCKSIZE - padsize;
106+
enc.Encrypt(out + written, mixed);
107+
written += AES_BLOCKSIZE;
108+
}
109+
return written;
110+
}
111+
112+
template <typename T>
113+
static int CBCDecrypt(const T& dec, const unsigned char iv[AES_BLOCKSIZE], const unsigned char* data, int size, bool pad, unsigned char* out)
114+
{
115+
unsigned char padsize = 0;
116+
int written = 0;
117+
bool fail = false;
118+
const unsigned char* prev = iv;
119+
120+
if (!data || !size || !out)
121+
return 0;
122+
123+
if (size % AES_BLOCKSIZE != 0)
124+
return 0;
125+
126+
// Decrypt all data. Padding will be checked in the output.
127+
while (written != size) {
128+
dec.Decrypt(out, data + written);
129+
for (int i = 0; i != AES_BLOCKSIZE; i++)
130+
*out++ ^= prev[i];
131+
prev = data + written;
132+
written += AES_BLOCKSIZE;
133+
}
134+
135+
// When decrypting padding, attempt to run in constant-time
136+
if (pad) {
137+
// If used, padding size is the value of the last decrypted byte. For
138+
// it to be valid, It must be between 1 and AES_BLOCKSIZE.
139+
padsize = *--out;
140+
fail = !padsize | (padsize > AES_BLOCKSIZE);
141+
142+
// If not well-formed, treat it as though there's no padding.
143+
padsize *= !fail;
144+
145+
// All padding must equal the last byte otherwise it's not well-formed
146+
for (int i = AES_BLOCKSIZE; i != 0; i--)
147+
fail |= ((i > AES_BLOCKSIZE - padsize) & (*out-- != padsize));
148+
149+
written -= padsize;
150+
}
151+
return written * !fail;
152+
}
153+
154+
AES256CBCEncrypt::AES256CBCEncrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
155+
: enc(key), pad(padIn)
156+
{
157+
memcpy(iv, ivIn, AES_BLOCKSIZE);
158+
}
159+
160+
int AES256CBCEncrypt::Encrypt(const unsigned char* data, int size, unsigned char* out) const
161+
{
162+
return CBCEncrypt(enc, iv, data, size, pad, out);
163+
}
164+
165+
AES256CBCEncrypt::~AES256CBCEncrypt()
166+
{
167+
memset(iv, 0, sizeof(iv));
168+
}
169+
170+
AES256CBCDecrypt::AES256CBCDecrypt(const unsigned char key[AES256_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
171+
: dec(key), pad(padIn)
172+
{
173+
memcpy(iv, ivIn, AES_BLOCKSIZE);
174+
}
175+
176+
177+
int AES256CBCDecrypt::Decrypt(const unsigned char* data, int size, unsigned char* out) const
178+
{
179+
return CBCDecrypt(dec, iv, data, size, pad, out);
180+
}
181+
182+
AES256CBCDecrypt::~AES256CBCDecrypt()
183+
{
184+
memset(iv, 0, sizeof(iv));
185+
}
186+
187+
AES128CBCEncrypt::AES128CBCEncrypt(const unsigned char key[AES128_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
188+
: enc(key), pad(padIn)
189+
{
190+
memcpy(iv, ivIn, AES_BLOCKSIZE);
191+
}
192+
193+
AES128CBCEncrypt::~AES128CBCEncrypt()
194+
{
195+
memset(iv, 0, AES_BLOCKSIZE);
196+
}
197+
198+
int AES128CBCEncrypt::Encrypt(const unsigned char* data, int size, unsigned char* out) const
199+
{
200+
return CBCEncrypt(enc, iv, data, size, pad, out);
201+
}
202+
203+
AES128CBCDecrypt::AES128CBCDecrypt(const unsigned char key[AES128_KEYSIZE], const unsigned char ivIn[AES_BLOCKSIZE], bool padIn)
204+
: dec(key), pad(padIn)
205+
{
206+
memcpy(iv, ivIn, AES_BLOCKSIZE);
207+
}
208+
209+
AES128CBCDecrypt::~AES128CBCDecrypt()
210+
{
211+
memset(iv, 0, AES_BLOCKSIZE);
212+
}
213+
214+
int AES128CBCDecrypt::Decrypt(const unsigned char* data, int size, unsigned char* out) const
215+
{
216+
return CBCDecrypt(dec, iv, data, size, pad, out);
217+
}

0 commit comments

Comments
 (0)