| 1015 | del packet[:slen] |
| 1016 | |
| 1017 | def derive_key(self, passphrase): |
| 1018 | ##TODO: raise an exception if self.usage is not 254 or 255 |
| 1019 | keylen = self.encalg.key_size |
| 1020 | hashlen = self.halg.digest_size * 8 |
| 1021 | |
| 1022 | ctx = int(math.ceil((keylen / hashlen))) |
| 1023 | |
| 1024 | # Simple S2K - always done |
| 1025 | hsalt = b'' |
| 1026 | if isinstance(passphrase, bytes): |
| 1027 | hpass = passphrase |
| 1028 | else: |
| 1029 | hpass = passphrase.encode('utf-8') |
| 1030 | |
| 1031 | # salted, iterated S2K |
| 1032 | if self.specifier >= String2KeyType.Salted: |
| 1033 | hsalt = bytes(self.salt) |
| 1034 | |
| 1035 | count = len(hsalt + hpass) |
| 1036 | if self.specifier == String2KeyType.Iterated and self.count > len(hsalt + hpass): |
| 1037 | count = self.count |
| 1038 | |
| 1039 | hcount = (count // len(hsalt + hpass)) |
| 1040 | hleft = count - (hcount * len(hsalt + hpass)) |
| 1041 | |
| 1042 | hashdata = ((hsalt + hpass) * hcount) + (hsalt + hpass)[:hleft] |
| 1043 | |
| 1044 | h = [] |
| 1045 | for i in range(0, ctx): |
| 1046 | _h = self.halg.hasher |
| 1047 | _h.update(b'\x00' * i) |
| 1048 | _h.update(hashdata) |
| 1049 | h.append(_h) |
| 1050 | |
| 1051 | # GC some stuff |
| 1052 | del hsalt |
| 1053 | del hpass |
| 1054 | del hashdata |
| 1055 | |
| 1056 | # and return the key! |
| 1057 | return b''.join(hc.digest() for hc in h)[:(keylen // 8)] |
| 1058 | |
| 1059 | |
| 1060 | class ECKDF(Field): |