1 | #!/usr/bin/env python |
---|
2 | import sha256, hmac |
---|
3 | import math |
---|
4 | from binascii import a2b_hex, b2a_hex |
---|
5 | |
---|
6 | class HKDF(object): |
---|
7 | def __init__(self, ikm, L, salt=None, info="", digestmod = None): |
---|
8 | self.ikm = ikm |
---|
9 | self.keylen = L |
---|
10 | |
---|
11 | if digestmod is None: |
---|
12 | digestmod = sha256.SHA256 |
---|
13 | |
---|
14 | if callable(digestmod): |
---|
15 | self.digest_cons = digestmod |
---|
16 | else: |
---|
17 | self.digest_cons = lambda d='':digestmod.new(d) |
---|
18 | self.hashlen = len(self.digest_cons().digest()) |
---|
19 | |
---|
20 | if salt is None: |
---|
21 | self.salt = chr(0)*(self.hashlen) |
---|
22 | else: |
---|
23 | self.salt = salt |
---|
24 | |
---|
25 | self.info = info |
---|
26 | |
---|
27 | #extract PRK |
---|
28 | def extract(self): |
---|
29 | h = hmac.new(self.salt, self.ikm, self.digest_cons) |
---|
30 | self.prk = h.digest() |
---|
31 | return self.prk |
---|
32 | |
---|
33 | #expand PRK |
---|
34 | def expand(self): |
---|
35 | N = math.ceil(float(self.keylen)/self.hashlen) |
---|
36 | T = "" |
---|
37 | temp = "" |
---|
38 | i=0x01 |
---|
39 | '''while len(T)<2*self.keylen : |
---|
40 | msg = temp |
---|
41 | msg += self.info |
---|
42 | msg += b2a_hex(chr(i)) |
---|
43 | h = hmac.new(self.prk, a2b_hex(msg), self.digest_cons) |
---|
44 | temp = b2a_hex(h.digest()) |
---|
45 | i += 1 |
---|
46 | T += temp |
---|
47 | ''' |
---|
48 | while len(T)<self.keylen : |
---|
49 | msg = temp |
---|
50 | msg += self.info |
---|
51 | msg += chr(i) |
---|
52 | h = hmac.new(self.prk, msg, self.digest_cons) |
---|
53 | temp = h.digest() |
---|
54 | i += 1 |
---|
55 | T += temp |
---|
56 | |
---|
57 | self.okm = T[0:self.keylen] |
---|
58 | return self.okm |
---|
59 | |
---|
60 | def new(ikm, L, salt=None, info="", digestmod = None): |
---|
61 | return HKDF(ikm, L,salt,info,digestmod) |
---|
62 | |
---|
63 | |
---|