def gotSecret(self, secret, question=None, appdata=None): ourFP = self.crypto.ctx.user.getPrivkey().fingerprint() if self.state == 1: # first secret -> SMP1TLV combSecret = SHA256(b'\1' + ourFP + self.crypto.theirPubkey.fingerprint() + self.crypto.sessionId + secret) self.secret = bytes_to_long(combSecret) self.x2 = bytes_to_long(RNG.read(192)) self.x3 = bytes_to_long(RNG.read(192)) msg = [pow(self.g1, self.x2, DH1536_MODULUS)] msg += proof_known_log(self.g1, self.x2, 1) msg.append(pow(self.g1, self.x3, DH1536_MODULUS)) msg += proof_known_log(self.g1, self.x3, 2) self.prog = SMPPROG_OK self.state = 2 if question is None: self.sendTLV(proto.SMP1TLV(msg), appdata=appdata) else: self.sendTLV(proto.SMP1QTLV(question, msg), appdata=appdata) if self.state == 0: # response secret -> SMP2TLV combSecret = SHA256(b'\1' + self.crypto.theirPubkey.fingerprint() + ourFP + self.crypto.sessionId + secret) self.secret = bytes_to_long(combSecret) msg = [pow(self.g1, self.x2, DH1536_MODULUS)] msg += proof_known_log(self.g1, self.x2, 3) msg.append(pow(self.g1, self.x3, DH1536_MODULUS)) msg += proof_known_log(self.g1, self.x3, 4) r = bytes_to_long(RNG.read(192)) self.p = pow(self.g3, r, DH1536_MODULUS) msg.append(self.p) qb1 = pow(self.g1, r, DH1536_MODULUS) qb2 = pow(self.g2, self.secret, DH1536_MODULUS) self.q = qb1 * qb2 % DH1536_MODULUS msg.append(self.q) msg += self.proof_equal_coords(r, 5) self.state = 3 self.sendTLV(proto.SMP2TLV(msg), appdata=appdata)
def proof_equal_coords(self, r, v): r1 = bytes_to_long(RNG.read(192)) r2 = bytes_to_long(RNG.read(192)) temp2 = pow(self.g1, r1, DH1536_MODULUS) \ * pow(self.g2, r2, DH1536_MODULUS) % DH1536_MODULUS temp1 = pow(self.g3, r1, DH1536_MODULUS) cb = SHA256(struct.pack(b'B', v) + pack_mpi(temp1) + pack_mpi(temp2)) c = bytes_to_long(cb) temp1 = r * c % SM_ORDER d1 = (r1-temp1) % SM_ORDER temp1 = self.secret * c % SM_ORDER d2 = (r2 - temp1) % SM_ORDER return c, d1, d2
def proof_equal_logs(self, v): r = bytes_to_long(RNG.read(192)) temp1 = pow(self.g1, r, DH1536_MODULUS) temp2 = pow(self.qab, r, DH1536_MODULUS) cb = SHA256(struct.pack(b'B', v) + pack_mpi(temp1) + pack_mpi(temp2)) c = bytes_to_long(cb) temp1 = self.x3 * c % SM_ORDER d = (r - temp1) % SM_ORDER return c, d
def startAKE(self): self.r = RNG.read(16) gxmpi = pack_mpi(self.dh.pub) self.hashgx = SHA256(gxmpi) self.encgx = AESCTR(self.r).encrypt(gxmpi) self.state = STATE_AWAITING_DHKEY return proto.DHCommit(self.encgx, self.hashgx)
def proof_known_log(g, x, v): r = bytes_to_long(RNG.read(192)) c = bytes_to_long(SHA256(struct.pack(b'B', v) + pack_mpi(pow(g, r, DH1536_MODULUS)))) temp = x * c % SM_ORDER return c, (r-temp) % SM_ORDER
def __init__(self): self.priv = bytes_to_long(RNG.read(40)) self.pub = pow(self.gen, self.priv, self.prime)
def handle(self, tlv, appdata=None): logger.debug('handling TLV {0.__class__.__name__}'.format(tlv)) self.prog = SMPPROG_CHEATED if isinstance(tlv, proto.SMPABORTTLV): self.state = 1 return is1qTlv = isinstance(tlv, proto.SMP1QTLV) if isinstance(tlv, proto.SMP1TLV) or is1qTlv: if self.state != 1: self.abort(appdata=appdata) return msg = tlv.mpis if not check_group(msg[0]) or not check_group(msg[3]) \ or not check_exp(msg[2]) or not check_exp(msg[5]) \ or not check_known_log(msg[1], msg[2], self.g1, msg[0], 1) \ or not check_known_log(msg[4], msg[5], self.g1, msg[3], 2): logger.error('invalid SMP1TLV received') self.abort(appdata=appdata) return self.questionReceived = is1qTlv self.g3o = msg[3] self.x2 = bytes_to_long(RNG.read(192)) self.x3 = bytes_to_long(RNG.read(192)) self.g2 = pow(msg[0], self.x2, DH1536_MODULUS) self.g3 = pow(msg[3], self.x3, DH1536_MODULUS) self.prog = SMPPROG_OK self.state = 0 return if isinstance(tlv, proto.SMP2TLV): if self.state != 2: self.abort(appdata=appdata) return msg = tlv.mpis mp = msg[6] mq = msg[7] if not check_group(msg[0]) or not check_group(msg[3]) \ or not check_group(msg[6]) or not check_group(msg[7]) \ or not check_exp(msg[2]) or not check_exp(msg[5]) \ or not check_exp(msg[9]) or not check_exp(msg[10]) \ or not check_known_log(msg[1], msg[2], self.g1, msg[0], 3) \ or not check_known_log(msg[4], msg[5], self.g1, msg[3], 4): logger.error('invalid SMP2TLV received') self.abort(appdata=appdata) return self.g3o = msg[3] self.g2 = pow(msg[0], self.x2, DH1536_MODULUS) self.g3 = pow(msg[3], self.x3, DH1536_MODULUS) if not self.check_equal_coords(msg[6:11], 5): logger.error('invalid SMP2TLV received') self.abort(appdata=appdata) return r = bytes_to_long(RNG.read(192)) self.p = pow(self.g3, r, DH1536_MODULUS) msg = [self.p] qa1 = pow(self.g1, r, DH1536_MODULUS) qa2 = pow(self.g2, self.secret, DH1536_MODULUS) self.q = qa1*qa2 % DH1536_MODULUS msg.append(self.q) msg += self.proof_equal_coords(r, 6) inv = invMod(mp) self.pab = self.p * inv % DH1536_MODULUS inv = invMod(mq) self.qab = self.q * inv % DH1536_MODULUS msg.append(pow(self.qab, self.x3, DH1536_MODULUS)) msg += self.proof_equal_logs(7) self.state = 4 self.prog = SMPPROG_OK self.sendTLV(proto.SMP3TLV(msg), appdata=appdata) return if isinstance(tlv, proto.SMP3TLV): if self.state != 3: self.abort(appdata=appdata) return msg = tlv.mpis if not check_group(msg[0]) or not check_group(msg[1]) \ or not check_group(msg[5]) or not check_exp(msg[3]) \ or not check_exp(msg[4]) or not check_exp(msg[7]) \ or not self.check_equal_coords(msg[:5], 6): logger.error('invalid SMP3TLV received') self.abort(appdata=appdata) return inv = invMod(self.p) self.pab = msg[0] * inv % DH1536_MODULUS inv = invMod(self.q) self.qab = msg[1] * inv % DH1536_MODULUS if not self.check_equal_logs(msg[5:8], 7): logger.error('invalid SMP3TLV received') self.abort(appdata=appdata) return md = msg[5] msg = [pow(self.qab, self.x3, DH1536_MODULUS)] msg += self.proof_equal_logs(8) rab = pow(md, self.x3, DH1536_MODULUS) self.prog = SMPPROG_SUCCEEDED if self.pab == rab else SMPPROG_FAILED if self.prog != SMPPROG_SUCCEEDED: logger.error('secrets don\'t match') self.abort(appdata=appdata) self.crypto.ctx.setCurrentTrust('') return logger.info('secrets matched') if not self.questionReceived: self.crypto.ctx.setCurrentTrust('smp') self.state = 1 self.sendTLV(proto.SMP4TLV(msg), appdata=appdata) return if isinstance(tlv, proto.SMP4TLV): if self.state != 4: self.abort(appdata=appdata) return msg = tlv.mpis if not check_group(msg[0]) or not check_exp(msg[2]) \ or not self.check_equal_logs(msg[:3], 8): logger.error('invalid SMP4TLV received') self.abort(appdata=appdata) return rab = pow(msg[0], self.x3, DH1536_MODULUS) self.prog = SMPPROG_SUCCEEDED if self.pab == rab else SMPPROG_FAILED if self.prog != SMPPROG_SUCCEEDED: logger.error('secrets don\'t match') self.abort(appdata=appdata) self.crypto.ctx.setCurrentTrust('') return logger.info('secrets matched') self.crypto.ctx.setCurrentTrust('smp') self.state = 1 return