1313// limitations under the License.
1414
1515#include < cstring>
16+ #include < new>
1617#include " bls.hpp"
1718
1819namespace bls {
20+ namespace {
21+
22+ class SecureBytes {
23+ public:
24+ explicit SecureBytes (size_t size) : m_size(size), m_data(Util::SecAlloc<uint8_t >(size)) {
25+ if (m_data == nullptr ) {
26+ throw std::bad_alloc ();
27+ }
28+ }
29+
30+ ~SecureBytes () {
31+ Util::SecureWipe (m_data, m_size);
32+ Util::SecFree (m_data);
33+ }
34+
35+ SecureBytes (const SecureBytes&) = delete ;
36+ SecureBytes& operator =(const SecureBytes&) = delete ;
37+
38+ uint8_t * data () { return m_data; }
39+
40+ private:
41+ const size_t m_size;
42+ uint8_t * const m_data;
43+ };
44+
45+ class SecureRelicBn {
46+ public:
47+ SecureRelicBn () {
48+ bn_null (m_value);
49+ bn_new (m_value);
50+ }
51+
52+ ~SecureRelicBn () {
53+ #if ALLOC == DYNAMIC
54+ if (m_value != nullptr && m_value->dp != nullptr && m_value->alloc > 0 ) {
55+ Util::SecureWipe (m_value->dp , m_value->alloc * sizeof (dig_t ));
56+ }
57+ bn_free (m_value);
58+ #elif ALLOC == AUTO
59+ Util::SecureWipe (m_value, sizeof (m_value));
60+ #endif
61+ }
62+
63+ SecureRelicBn (const SecureRelicBn&) = delete ;
64+ SecureRelicBn& operator =(const SecureRelicBn&) = delete ;
65+
66+ bn_st* get () { return m_value; }
67+
68+ private:
69+ bn_t m_value;
70+ };
71+
72+ } // namespace
1973
2074ExtendedPrivateKey ExtendedPrivateKey::FromSeed (const Bytes& bytes) {
2175 // "BLS HD seed" in ascii
2276 const uint8_t prefix[] = {66 , 76 , 83 , 32 , 72 , 68 , 32 , 115 , 101 , 101 , 100 };
2377
24- uint8_t * hashInput = Util::SecAlloc< uint8_t > (bytes.size () + 1 );
25- std::memcpy (hashInput, bytes.begin (), bytes.size ());
78+ SecureBytes hashInput (bytes.size () + 1 );
79+ std::memcpy (hashInput. data () , bytes.begin (), bytes.size ());
2680
2781 // 32 bytes for secret key, and 32 bytes for chaincode
28- uint8_t * ILeft = Util::SecAlloc<uint8_t >(
29- PrivateKey::PRIVATE_KEY_SIZE );
30- uint8_t IRight[ChainCode::SIZE ];
82+ SecureBytes ILeft (PrivateKey::PRIVATE_KEY_SIZE );
83+ SecureBytes IRight (ChainCode::SIZE );
3184
3285 // Hash the seed into 64 bytes, half will be sk, half will be cc
33- hashInput[bytes.size ()] = 0 ;
34- md_hmac (ILeft, hashInput, bytes.size () + 1 , prefix, sizeof (prefix));
86+ hashInput. data () [bytes.size ()] = 0 ;
87+ md_hmac (ILeft. data () , hashInput. data () , bytes.size () + 1 , prefix, sizeof (prefix));
3588
36- hashInput[bytes.size ()] = 1 ;
37- md_hmac (IRight, hashInput, bytes.size () + 1 , prefix, sizeof (prefix));
89+ hashInput. data () [bytes.size ()] = 1 ;
90+ md_hmac (IRight. data () , hashInput. data () , bytes.size () + 1 , prefix, sizeof (prefix));
3891
3992 // Make sure private key is less than the curve order
40- bn_t * skBn = Util::SecAlloc<bn_t >(1 );
41- bn_t order;
42- bn_new (order);
43- g1_get_ord (order);
93+ SecureRelicBn skBn;
94+ SecureRelicBn order;
95+ g1_get_ord (order.get ());
4496
45- bn_new (*skBn);
46- bn_read_bin (*skBn, ILeft, PrivateKey::PRIVATE_KEY_SIZE );
47- bn_mod_basic (*skBn, *skBn, order);
48- bn_write_bin (ILeft, PrivateKey::PRIVATE_KEY_SIZE , *skBn);
97+ bn_read_bin (skBn.get (), ILeft.data (), PrivateKey::PRIVATE_KEY_SIZE );
98+ bn_mod_basic (skBn.get (), skBn.get (), order.get ());
99+ bn_write_bin (ILeft.data (), PrivateKey::PRIVATE_KEY_SIZE , skBn.get ());
49100
50101 ExtendedPrivateKey esk (ExtendedPublicKey::REVISION , 0 , 0 , 0 ,
51- ChainCode::FromBytes (Bytes (IRight, ChainCode::SIZE )),
52- PrivateKey::FromBytes (Bytes (ILeft, PrivateKey::PRIVATE_KEY_SIZE )));
102+ ChainCode::FromBytes (Bytes (IRight. data () , ChainCode::SIZE )),
103+ PrivateKey::FromBytes (Bytes (ILeft. data () , PrivateKey::PRIVATE_KEY_SIZE )));
53104
54- Util::SecFree (skBn);
55- Util::SecFree (ILeft);
56- Util::SecFree (hashInput);
57105 return esk;
58106}
59107
@@ -79,48 +127,45 @@ ExtendedPrivateKey ExtendedPrivateKey::PrivateChild(uint32_t i, const bool fLega
79127 uint32_t cmp = (1 << 31 );
80128 bool hardened = i >= cmp;
81129
82- uint8_t * ILeft = Util::SecAlloc< uint8_t > (PrivateKey::PRIVATE_KEY_SIZE );
83- uint8_t IRight[ ChainCode::SIZE ] ;
130+ SecureBytes ILeft (PrivateKey::PRIVATE_KEY_SIZE );
131+ SecureBytes IRight ( ChainCode::SIZE ) ;
84132
85133 // Chain code is used as hmac key
86- uint8_t hmacKey[ ChainCode::SIZE ] ;
87- chainCode.Serialize (hmacKey);
134+ SecureBytes hmacKey ( ChainCode::SIZE ) ;
135+ chainCode.Serialize (hmacKey. data () );
88136
89137 size_t inputLen = hardened ? PrivateKey::PRIVATE_KEY_SIZE + 4 + 1
90138 : G1Element::SIZE + 4 + 1 ;
91139 // Hmac input includes sk or pk, int i, and byte with 0 or 1
92- uint8_t * hmacInput = Util::SecAlloc< uint8_t > (inputLen);
140+ SecureBytes hmacInput (inputLen);
93141
94142 // Fill the input with the required data
95143 if (hardened) {
96- sk.Serialize (hmacInput);
97- Util::IntToFourBytes (hmacInput + PrivateKey::PRIVATE_KEY_SIZE , i);
144+ sk.Serialize (hmacInput. data () );
145+ Util::IntToFourBytes (hmacInput. data () + PrivateKey::PRIVATE_KEY_SIZE , i);
98146 } else {
99- memcpy (hmacInput, sk.GetG1Element ().Serialize (fLegacy ).data (), G1Element::SIZE );
100- Util::IntToFourBytes (hmacInput + G1Element::SIZE , i);
147+ memcpy (hmacInput. data () , sk.GetG1Element ().Serialize (fLegacy ).data (), G1Element::SIZE );
148+ Util::IntToFourBytes (hmacInput. data () + G1Element::SIZE , i);
101149 }
102- hmacInput[inputLen - 1 ] = 0 ;
150+ hmacInput. data () [inputLen - 1 ] = 0 ;
103151
104- md_hmac (ILeft, hmacInput, inputLen,
105- hmacKey, ChainCode::SIZE );
152+ md_hmac (ILeft. data () , hmacInput. data () , inputLen,
153+ hmacKey. data () , ChainCode::SIZE );
106154
107155 // Change 1 byte to generate a different sequence for chaincode
108- hmacInput[inputLen - 1 ] = 1 ;
156+ hmacInput. data () [inputLen - 1 ] = 1 ;
109157
110- md_hmac (IRight, hmacInput, inputLen,
111- hmacKey, ChainCode::SIZE );
158+ md_hmac (IRight. data () , hmacInput. data () , inputLen,
159+ hmacKey. data () , ChainCode::SIZE );
112160
113- PrivateKey newSk = PrivateKey::FromBytes (Bytes (ILeft, PrivateKey::PRIVATE_KEY_SIZE ), true );
161+ PrivateKey newSk = PrivateKey::FromBytes (Bytes (ILeft. data () , PrivateKey::PRIVATE_KEY_SIZE ), true );
114162 newSk = PrivateKey::Aggregate ({sk, newSk});
115163
116164 ExtendedPrivateKey esk (version, depth + 1 ,
117165 sk.GetG1Element ().GetFingerprint (), i,
118- ChainCode::FromBytes (Bytes (IRight, ChainCode::SIZE )),
166+ ChainCode::FromBytes (Bytes (IRight. data () , ChainCode::SIZE )),
119167 newSk);
120168
121- Util::SecFree (ILeft);
122- Util::SecFree (hmacInput);
123-
124169 return esk;
125170}
126171
0 commit comments