Пример #1
0
def new_random_key(maker, kek, purpose, user, klen=32):
    from cryptoe.KeyMgmt import newkey_rnd
    from cryptoe.KeyWrap import KWP

    session = maker()
    no_salt = session.query(Salt).filter_by(salt='').first()
    if len(no_salt.salt) != 0:
        raise SaltLengthError('Salt length for new_random_key should be 0')
    k = Key()
    k.bits = klen * 8
    k.purpose = purpose
    k.user = user
    k.salt_id = no_salt.id
    k_actual = newkey_rnd(klen)
    if len(k_actual) != klen:
        raise KeyLengthError(
            'Key returned by newkey_rnd does not match requested length (%d != %d)'
            % (len(k_actual), klen))
    k.key = KWP.wrap(kek, k_actual)
    k_hash = SHAd256.new(k_actual).hexdigest()
    k.key_hash = k_hash
    k.related_hash = SHAd256.new(kek).hexdigest()
    session.add(k)
    session.commit()
    session.close()
    return k_actual
Пример #2
0
def new_derived_key(maker, kek, kdk, purpose, user, klen=32):
    from cryptoe.KeyWrap import KWP
    from cryptoe.KeyMgmt import newkey_hkdf

    session = maker()
    k = Key()
    k.bits = klen * 8
    k.purpose = purpose
    k_salt = new_salt(maker, klen)
    if len(k_salt.salt) != klen:
        raise SaltLengthError(
            'HKDF salt must be the same length as the derivation key')
    k.salt_id = k_salt.id
    k.user = user
    k_actual = newkey_hkdf(klen, kdk, k_salt.salt,
                           pack_hkdf_info(k.purpose, k.user))
    if len(k_actual) != klen:
        raise KeyLengthError(
            'HKDF returned a key with an incorrect length (%d != %d)' %
            (len(k_actual), klen))
    if kek == '':
        k.key = ''
    else:
        k.key = KWP.wrap(kek, k_actual)
    k.related_hash = SHAd256.new(kdk).hexdigest()
    k_hash = SHAd256.new(k_actual).hexdigest()
    k.key_hash = k_hash
    session.add(k)
    session.commit()
    session.close()
    return k_actual
Пример #3
0
    def test_python_vs_c_RND(self):
        from Crypto import Random
        from cryptoe.Hash import SHAd256 as ct_SHAd256

        rnd_buf_lens = sorted(
            list(set([random.randint(0, 4096) for _ in xrange(0, 64)])))
        for r in xrange(0, len(rnd_buf_lens)):
            data = Random.new().read(rnd_buf_lens[r])
            ct_hash = ct_SHAd256.new(data).digest()
            py_hash = py_SHAd256(data)
            self.assertEqual(ct_hash, py_hash)
Пример #4
0
    def test_python_vs_c_NIST(self):
        from cryptoe.Hash import SHAd256 as ct_SHAd256

        for v in NIST_FIPS_VECTORS:
            data = v[1]
            if isinstance(data, int):
                data = long2ba(data)
            if isinstance(data, long):
                data = long2ba(data)
            data = bytes(data)
            ct_hash = ct_SHAd256.new(data).digest()
            py_hash = py_SHAd256(data)
            self.assertEqual(ct_hash, py_hash)
Пример #5
0
def unlock_db(maker):
    from getpass import getpass
    from cryptoe.KeyMgmt import newkey_pbkdf
    from utils import yubikey_passphrase_cr

    session = maker()
    mk = session.query(MasterKey).order_by(MasterKey.created.desc()).one()
    if not mk:
        print('[UNLOCK] no master key found. cannot proceed.')
        sys.exit(0)

    pw = getpass('passphrase: ').rstrip()
    pw = yubikey_passphrase_cr(pw)
    mk_key = newkey_pbkdf(32, pw, mk.salt.salt, mk.rounds)
    mk_key_hash = SHAd256.new(mk_key).hexdigest()
    if mk_key_hash != mk.key_hash:
        return None
    else:
        return mk_key
Пример #6
0
def yubikey_passphrase_cr(passphrase):
    """
    This function:
     Takes an input passphrase
     generates the SHAd256 hash of it
     sends that hash to a Yubikey configured for HMAC-SHA1 on slot 2
     computes the whirlpool hash of the HMAC-SHA1 response received from the Yubikey
     returns the whirlpool hash
    :param passphrase: passphrase (plaintext)
    :type passphrase: str
    :return: whirlpool digest (hex)
    :rtype: str
    """
    try:
        import yubico
    except ImportError:
        yubico = None
    if not yubico:
        del yubico
        return passphrase
    try:
        yubikey = yubico.find_yubikey()
    except yubico.yubikey.YubiKeyError:
        return passphrase
    if yubikey:
        challenge = SHAd256.new(passphrase).hexdigest()
        print('[YubiKey] Sending challenge')
        try:
            response = yubikey.challenge_response(challenge,
                                                  slot=YUBIKEY_HMAC_CR_SLOT)
            print('[YubiKey] Got response')
        except yubico.yubikey.YubiKeyTimeout:
            print('[YubiKey] Timeout. Not using Yubikey.')
            return passphrase
        passphrase = whirlpool.new(response).hexdigest()
    return passphrase
Пример #7
0
def init_keys(maker, use_yubikey=False):
    from getpass import getpass
    from cryptoe.exceptions import KeyLengthError
    from cryptoe.KeyMgmt import newkey_pbkdf

    password_transforms = {}
    if use_yubikey is True:
        from cryptoe.utils import yubikey_passphrase_cr

        password_transforms['YK-HMAC-SHA1'] = yubikey_passphrase_cr

    passphrase_ready = 0
    session = maker()
    passphrase = ''
    while not passphrase_ready:
        passphrase = getpass('passphrase: ').rstrip()
        if len(passphrase) < KEYDB_PASSPHRASE_LENGTH:
            print('passphrase is too short.')
            continue
        else:
            confirm = getpass('passphrase (confirm): ').rstrip()
            if confirm == passphrase:
                passphrase_ready = 1
    del passphrase_ready
    roundcount = KEYDB_PBKDF2_ITERATIONS
    print('[INIT->PASSPHRASE] applying passphrase transformations')
    for tr in password_transforms:
        trnam = tr.upper()
        tr_func = password_transforms[tr]
        print('[INIT->%s] running' % trnam)
        opp = passphrase
        passphrase = tr_func(passphrase)
        if opp == passphrase:
            print('[INIT->%s] no change' % trnam)
        else:
            print('[INIT->%s] old length: %d bytes, new length: %d bytes' %
                  (trnam, len(opp), len(passphrase)))
    klen_bits = 256
    klen = klen_bits / 8
    slen = klen / 2
    print('[INIT->SALT] creating new salt for PBKDF (salt len = %d)' % slen)
    mk_salt = new_salt(maker, klen)
    print('[INIT->SALT] salt created (id=%d)' % mk_salt.id)
    mk = MasterKey()
    mk.bits = klen_bits
    mk.prf_hash = DEFAULT_PRF_HASH.__name__.split('.')[-1]
    mk.rounds = roundcount
    mk.salt_id = mk_salt.id

    print('[INIT->PBKDF] newkey_pbkdf(%d,<passphrase>,<salt>,%d)' %
          (klen, roundcount))
    mk_key = newkey_pbkdf(klen, passphrase, mk_salt.salt, roundcount)
    print('[INIT->PBKDF] %d-bit master key derived' % (len(mk_key) * 8))
    if len(mk_key) != klen:
        raise KeyLengthError(
            'PBKDF key is not of requested length (%d != %d)' %
            (len(mk_key), klen))
    mk_hash = SHAd256.new(mk_key).hexdigest()
    mk.key_hash = mk_hash
    session.add(mk)
    session.commit()
    session.close()
    mk = None
    mk_salt = '\x00' * klen
    del mk
    del mk_salt

    kp = KEYDB_PURPOSE_WRAPPING
    wk = new_derived_key(maker, '', mk_key, kp, KEYDB_USER, klen)
    print('[INIT->KDF] %d-bit key (purpose: %s) derived' % (len(wk) * 8, kp))

    if len(wk) != klen:
        raise KeyLengthError('[INIT->KDF] %d != %d' % (len(wk), klen))
    mk_key = '\x00' * klen
    del mk_key

    dbk_list = [
        [
            'encryption',
            32,
            KEYDB_PURPOSE_ENCRYPTION,
        ],
        [
            'authentication',
            32,
            KEYDB_PURPOSE_HMAC,
        ],
        [
            'authentication',
            48,
            KEYDB_PURPOSE_HMAC,
        ],
        [
            'authentication',
            64,
            KEYDB_PURPOSE_HMAC,
        ],
    ]

    for k in dbk_list:
        rk = new_random_key(maker, wk, k[2], KEYDB_USER, k[1])
        if len(rk) != k[1]:
            raise KeyLengthError('[INIT->RND] %d != %d' % (len(rk), k[1]))
        else:
            print('[INIT->RND] %d-bit key "%s" created and wrapped' %
                  (len(rk) * 8, k[2]))

        rk = '\x00' * klen
        del rk
    wk = '\x00' * 32
    del wk
Пример #8
0
def _shad256_new(*args):
    _new_funcs['SHAd256'] = _new_funcs['shad256'] = SHAd256.new
    return SHAd256.new(*args)