crypto.py: improve get_random() implementation
This commit is contained in:
parent
24cdd98037
commit
589c37806b
4 changed files with 39 additions and 19 deletions
|
|
@ -112,10 +112,11 @@ def decrypt_seed(enc_seed,key,seed_id,key_id):
|
|||
dmsg(f'Decrypted seed: {dec_seed.hex()}')
|
||||
return dec_seed
|
||||
|
||||
def encrypt_data(data,key,iv=aesctr_dfl_iv,desc='data',verify=True):
|
||||
def encrypt_data(data,key,iv=aesctr_dfl_iv,desc='data',verify=True,silent=False):
|
||||
from cryptography.hazmat.primitives.ciphers import Cipher,algorithms,modes
|
||||
from cryptography.hazmat.backends import default_backend
|
||||
vmsg(f'Encrypting {desc}')
|
||||
if not silent:
|
||||
vmsg(f'Encrypting {desc}')
|
||||
c = Cipher(algorithms.AES(key),modes.CTR(iv),backend=default_backend())
|
||||
encryptor = c.encryptor()
|
||||
enc_data = encryptor.update(data) + encryptor.finalize()
|
||||
|
|
@ -127,7 +128,8 @@ def encrypt_data(data,key,iv=aesctr_dfl_iv,desc='data',verify=True):
|
|||
dec_data = encryptor.update(enc_data) + encryptor.finalize()
|
||||
if dec_data != data:
|
||||
die(2,f'ERROR.\nDecrypted {desc} doesn’t match original {desc}')
|
||||
vmsg('done')
|
||||
if not silent:
|
||||
vmsg('done')
|
||||
|
||||
return enc_data
|
||||
|
||||
|
|
@ -243,22 +245,42 @@ def _get_random_data_from_user(uchars,desc):
|
|||
return ret.encode()
|
||||
|
||||
def get_random(length):
|
||||
return add_user_random(
|
||||
rand_bytes = os.urandom(length),
|
||||
desc = 'generated by your operating system' )
|
||||
|
||||
def add_user_random(rand_bytes,desc):
|
||||
os_rand = os.urandom(length)
|
||||
assert len(os_rand) == length, f'OS random number generator returned {len(os_rand)} (!= {length}) bytes!'
|
||||
|
||||
return add_user_random(
|
||||
rand_bytes = os_rand,
|
||||
desc = 'from your operating system' )
|
||||
|
||||
def add_user_random(
|
||||
rand_bytes,
|
||||
desc,
|
||||
urand = {'data':b'', 'counter':0} ):
|
||||
|
||||
assert type(rand_bytes) == bytes, 'add_user_random_chk1'
|
||||
|
||||
if opt.usr_randchars:
|
||||
if not g.user_entropy:
|
||||
|
||||
if not urand['data']:
|
||||
from hashlib import sha256
|
||||
g.user_entropy = sha256(_get_random_data_from_user(opt.usr_randchars,desc)).digest()
|
||||
urand_desc = 'user-supplied entropy'
|
||||
else:
|
||||
urand_desc = 'saved user-supplied entropy'
|
||||
key = make_key(g.user_entropy,b'','2',from_what=urand_desc,verbose=True)
|
||||
msg(f'Encrypting random data {desc} with key')
|
||||
return encrypt_data(rand_bytes,key,desc=desc,verify=False)
|
||||
urand['data'] = sha256(_get_random_data_from_user(opt.usr_randchars,desc)).digest()
|
||||
|
||||
# counter protects against very evil rng that might repeatedly output the same data
|
||||
urand['counter'] += 1
|
||||
|
||||
os_rand = os.urandom(8)
|
||||
assert len(os_rand) == 8, f'OS random number generator returned {len(os_rand)} (!= 8) bytes!'
|
||||
|
||||
import hmac
|
||||
key = hmac.digest(
|
||||
urand['data'],
|
||||
os_rand + int.to_bytes(urand['counter'],8,'big'),
|
||||
'sha256' )
|
||||
|
||||
msg('Encrypting random data {} with ephemeral key #{}'.format( desc, urand['counter'] ))
|
||||
|
||||
return encrypt_data( data=rand_bytes, key=key, desc=desc, verify=False, silent=True )
|
||||
else:
|
||||
return rand_bytes
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ class GlobalContext(Lockable):
|
|||
3 - command line
|
||||
"""
|
||||
_autolock = False
|
||||
_set_ok = ('user_entropy','session')
|
||||
_set_ok = ('session',)
|
||||
_reset_ok = ('stdout','stderr','accept_defaults')
|
||||
_use_class_attr = True
|
||||
|
||||
|
|
@ -66,7 +66,6 @@ class GlobalContext(Lockable):
|
|||
|
||||
# Variables - these might be altered at runtime:
|
||||
|
||||
user_entropy = b''
|
||||
dfl_hash_preset = '3'
|
||||
usr_randchars = 30
|
||||
|
||||
|
|
|
|||
|
|
@ -253,7 +253,6 @@ class TestSuiteMain(TestSuiteBase,TestSuiteShared):
|
|||
t = self.spawn('mmgen-walletgen', args + [self.usr_rand_arg])
|
||||
t.license()
|
||||
t.usr_rand(self.usr_rand_chars)
|
||||
t.expect('Generating')
|
||||
wcls = MMGenWallet
|
||||
t.passphrase_new('new '+wcls.desc,self.wpasswd)
|
||||
t.label()
|
||||
|
|
@ -591,7 +590,7 @@ class TestSuiteMain(TestSuiteBase,TestSuiteShared):
|
|||
t.usr_rand(self.usr_rand_chars)
|
||||
|
||||
if ocls.type.startswith('incog'):
|
||||
m = 'Encrypting random data generated by your operating system with key'
|
||||
m = 'Encrypting random data from your operating system with ephemeral key'
|
||||
t.expect(m)
|
||||
t.expect(m)
|
||||
incog_id = t.expect_getend('New Incog Wallet ID: ')
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ class TestSuiteWalletConv(TestSuiteBase,TestSuiteShared):
|
|||
t.usr_rand(self.usr_rand_chars)
|
||||
if wcls.type.startswith('incog'):
|
||||
for i in (1,2,3):
|
||||
t.expect('Encrypting random data generated by your operating system with key')
|
||||
t.expect('Encrypting random data from your operating system with ephemeral key')
|
||||
if wcls.type == 'incog_hidden':
|
||||
t.hincog_create(hincog_bytes)
|
||||
if out_fmt == 'w':
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue