1 2# Upstream Author: Zooko O'Whielacronx <zooko@zooko.com> 3# 4# Copyright: 5# 6# You may use this package under the GNU General Public License, version 7# 2 or, at your option, any later version. You may use this package 8# under the Transitive Grace Period Public Licence, version 1.0 or, at 9# your option, any later version. (You may choose to use this package 10# under the terms of either licence, at your option.) See the file 11# COPYING.GPL for the terms of the GNU General Public License, version 2. 12# See the file COPYING.TGPPL.html for the terms of the Transitive Grace 13# Period Public Licence, version 1.0. 14# 15# The following licensing text applies to a subset of the Crypto++ source code 16# which is included in the pycryptopp source tree under the "embeddedcryptopp" 17# subdirectory. That embedded subset of the Crypto++ source code is not used 18# when pycryptopp is built for Debian -- instead the --disable-embedded-cryptopp 19# option to "setup.py build" is used to for pycryptopp to build against the 20# system libcryptopp. 21 22import hashlib, hmac 23import math 24from binascii import a2b_hex, b2a_hex 25 26class HKDF(object): 27 def __init__(self, ikm, L, salt=None, info="", digestmod = None): 28 self.ikm = ikm 29 self.keylen = L 30 31 if digestmod is None: 32 digestmod = hashlib.sha256 33 34 if callable(digestmod): 35 self.digest_cons = digestmod 36 else: 37 self.digest_cons = lambda d='':digestmod.new(d) 38 self.hashlen = len(self.digest_cons().digest()) 39 40 if salt is None: 41 self.salt = chr(0)*(self.hashlen) 42 else: 43 self.salt = salt 44 45 self.info = info 46 47 #extract PRK 48 def extract(self): 49 h = hmac.new(self.salt, self.ikm, self.digest_cons) 50 self.prk = h.digest() 51 return self.prk 52 53 #expand PRK 54 def expand(self): 55 N = math.ceil(float(self.keylen)/self.hashlen) 56 T = "" 57 temp = "" 58 i=0x01 59 '''while len(T)<2*self.keylen : 60 msg = temp 61 msg += self.info 62 msg += b2a_hex(chr(i)) 63 h = hmac.new(self.prk, a2b_hex(msg), self.digest_cons) 64 temp = b2a_hex(h.digest()) 65 i += 1 66 T += temp 67 ''' 68 while len(T)<self.keylen : 69 msg = temp 70 msg += self.info 71 msg += chr(i) 72 h = hmac.new(self.prk, msg, self.digest_cons) 73 temp = h.digest() 74 i += 1 75 T += temp 76 77 self.okm = T[0:self.keylen] 78 return self.okm 79 80def new(ikm, L, salt=None, info="", digestmod = None): 81 return HKDF(ikm, L,salt,info,digestmod) 82 83def hkdf(ikm, length, salt=None, info=""): 84 hk = HKDF(ikm, length ,salt,info) 85 computedprk = hk.extract() 86 return hk.expand()