|
@@ -25,27 +25,6 @@ from cryptography.hazmat.backends import default_backend
|
|
|
from hashlib import sha256
|
|
|
from .common import *
|
|
|
|
|
|
-crmsg = {
|
|
|
- 'usr_rand_notice': """
|
|
|
-Now we're going to gather some additional input from the keyboard to
|
|
|
-further randomize the {d} we've already gathered.
|
|
|
-
|
|
|
-An encryption key will be created from this input, and the {d}
|
|
|
-will be encrypted using the key. The resulting data is guaranteed to be at
|
|
|
-least as random as the original {d}, so even if you type very
|
|
|
-predictably no harm will be done.
|
|
|
-
|
|
|
-However, to gain the maximum benefit, try making your input as random as
|
|
|
-possible. Type slowly and choose your symbols carefully. Try to use both
|
|
|
-upper and lowercase as well as punctuation and numerals. The timings between
|
|
|
-your keystrokes will also be used as a source of entropy, so be as
|
|
|
-unpredictable as possible in your timing as well.
|
|
|
-
|
|
|
-Please type {r} symbols on your keyboard. What you type will not be displayed
|
|
|
-on the screen.
|
|
|
-"""
|
|
|
-}
|
|
|
-
|
|
|
def sha256_rounds(s,n):
|
|
|
for i in range(n):
|
|
|
s = sha256(s).digest()
|
|
@@ -152,53 +131,74 @@ def make_key(passwd,salt,hash_preset,desc='encryption key',from_what='passphrase
|
|
|
dmsg('Key: {}'.format(key.hex()))
|
|
|
return key
|
|
|
|
|
|
-def _get_random_data_from_user(uchars,desc,test_suite=False):
|
|
|
- m = 'Enter {r} random symbols' if opt.quiet or test_suite else crmsg['usr_rand_notice']
|
|
|
- msg(m.format(r=uchars,d=desc))
|
|
|
+def _get_random_data_from_user(uchars,desc):
|
|
|
+ info1 = f"""
|
|
|
+ Now we're going to gather some additional input from the keyboard to further
|
|
|
+ randomize the random data {desc}.
|
|
|
+
|
|
|
+ An encryption key will be created from this input, and the random data will
|
|
|
+ be encrypted using the key. The resulting data is guaranteed to be at least
|
|
|
+ as random as the original random data, so even if you type very predictably
|
|
|
+ no harm will be done.
|
|
|
+
|
|
|
+ However, to gain the maximum benefit, try making your input as random as
|
|
|
+ possible. Type slowly and choose your symbols carefully. Try to use both
|
|
|
+ upper and lowercase letters as well as punctuation and numerals. The timings
|
|
|
+ between your keystrokes will also be used as a source of entropy, so be as
|
|
|
+ random as possible in your timing as well.
|
|
|
+ """
|
|
|
+ info2 = f"""
|
|
|
+ Please type {uchars} symbols on your keyboard. What you type will not be displayed
|
|
|
+ on the screen.
|
|
|
+ """
|
|
|
+
|
|
|
+ msg(f'Enter {uchars} random symbols' if opt.quiet else
|
|
|
+ '\n{}\n{}'.format( fmt(info1,indent=' '), fmt(info2) ))
|
|
|
+
|
|
|
prompt = 'You may begin typing. {} symbols left: '
|
|
|
|
|
|
import time
|
|
|
from .term import get_char_raw
|
|
|
- key_data,time_data = '',[]
|
|
|
+ key_data = ''
|
|
|
+ time_data = []
|
|
|
|
|
|
for i in range(uchars):
|
|
|
key_data += get_char_raw('\r'+prompt.format(uchars-i))
|
|
|
time_data.append(time.time())
|
|
|
|
|
|
- msg_r('\r' if opt.quiet else "\rThank you. That's enough.{}\n\n".format(' '*18))
|
|
|
+ msg_r( '\r' if opt.quiet else f"\rThank you. That's enough.{' '*18}\n\n" )
|
|
|
|
|
|
time_data = ['{:.22f}'.format(t).rstrip('0') for t in time_data]
|
|
|
|
|
|
avg_prec = sum(len(t.split('.')[1]) for t in time_data) // len(time_data)
|
|
|
+
|
|
|
if avg_prec < g.min_time_precision:
|
|
|
- m = 'WARNING: Avg. time precision of only {} decimal points. User entropy quality is degraded!'
|
|
|
- ymsg(m.format(avg_prec))
|
|
|
+ ymsg(f'WARNING: Avg. time precision of only {avg_prec} decimal points. User entropy quality is degraded!')
|
|
|
|
|
|
ret = key_data + '\n' + '\n'.join(time_data)
|
|
|
|
|
|
if g.debug:
|
|
|
- msg('USER ENTROPY (user input + keystroke timings):\n{}'.format(ret))
|
|
|
+ msg(f'USER ENTROPY (user input + keystroke timings):\n{ret}')
|
|
|
|
|
|
- if not test_suite:
|
|
|
- my_raw_input('User random data successfully acquired. Press ENTER to continue: ')
|
|
|
+ my_raw_input('User random data successfully acquired. Press ENTER to continue: ')
|
|
|
|
|
|
return ret.encode()
|
|
|
|
|
|
def get_random(length):
|
|
|
- return add_user_random(os.urandom(length),'OS random data')
|
|
|
+ return add_user_random(
|
|
|
+ rand_bytes = os.urandom(length),
|
|
|
+ desc = 'generated by your operating system' )
|
|
|
|
|
|
def add_user_random(rand_bytes,desc):
|
|
|
- assert type(rand_bytes) == bytes, (
|
|
|
- "{!r}: invalid type for 'rand_bytes'".format(type(rand_bytes).__name__) )
|
|
|
+ assert type(rand_bytes) == bytes, 'add_user_random_chk1'
|
|
|
if opt.usr_randchars:
|
|
|
if not g.user_entropy:
|
|
|
- g.user_entropy = \
|
|
|
- sha256(_get_random_data_from_user(opt.usr_randchars,desc)).digest()
|
|
|
+ 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('Encrypting {} with key'.format(desc))
|
|
|
+ msg(f'Encrypting random data {desc} with key')
|
|
|
return encrypt_data(rand_bytes,key,desc=desc,verify=False)
|
|
|
else:
|
|
|
return rand_bytes
|