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()