示例#1
0
    def deriveSecrets(self, masterKey):
        """
        Derive various session keys from the given `masterKey'.

        The argument `masterKey' is used to derive two session keys and nonces
        for AES-CTR and two HMAC keys.  The derivation is done using
        HKDF-SHA256.
        """

        assert len(masterKey) == const.MASTER_KEY_LENGTH

        log.debug("Deriving session keys from %d-byte master key." %
                  len(masterKey))

        # We need key material for two symmetric AES-CTR keys, nonces and
        # HMACs.  In total, this equals 144 bytes of key material.
        hkdf = mycrypto.HKDF_SHA256(masterKey, "", (32 * 4) + (8 * 2))
        okm = hkdf.expand()
        assert len(okm) >= ((32 * 4) + (8 * 2))

        # Set AES-CTR keys and nonces for our two AES instances.
        self.sendCrypter.setSessionKey(okm[0:32], okm[32:40])
        self.recvCrypter.setSessionKey(okm[40:72], okm[72:80])

        # Set the keys for the two HMACs protecting our data integrity.
        self.sendHMAC = okm[80:112]
        self.recvHMAC = okm[112:144]

        if self.weAreServer:
            self.sendHMAC, self.recvHMAC = self.recvHMAC, self.sendHMAC
            self.sendCrypter, self.recvCrypter = self.recvCrypter, \
                                                 self.sendCrypter
示例#2
0
    def test4_HKDF_TestCase4( self ):

        self.assertRaises(ValueError,
                          mycrypto.HKDF_SHA256, "x" * 40, length=(32*255)+1)

        self.assertRaises(ValueError,
                          mycrypto.HKDF_SHA256, "tooShort")

        # Accidental re-use should raise an exception.
        hkdf = mycrypto.HKDF_SHA256("x" * 40)
        hkdf.expand()
        self.assertRaises(base.PluggableTransportError, hkdf.expand)
示例#3
0
    def _deriveSecrets(self, masterKey):
        """Derives session keys (AES keys, counter nonces, HMAC keys and magic
        values) from the given master secret. All key material is derived using
        HKDF-SHA256."""

        log.debug("Master key: 0x%s." % masterKey.encode('hex'))

        # We need key material for two magic values, symmetric keys, nonces and
        # HMACs. All of them are 32 bytes in size.
        hkdf = mycrypto.HKDF_SHA256(masterKey, "", 32 * 8)
        okm = hkdf.expand()

        # Set the symmetric AES keys.
        self.sendCrypter.setSessionKey(okm[0:32], okm[32:64])
        self.recvCrypter.setSessionKey(okm[64:96], okm[96:128])

        # Derive a magic value for the client as well as the server. They must
        # be distinct to prevent fingerprinting (e.g. look for two identical
        # 256-bit strings).
        self.sendMagic = okm[128:160]
        self.recvMagic = okm[160:192]

        # Set the HMAC keys.
        self.sendHMAC = okm[192:224]
        self.recvHMAC = okm[224:256]

        if self.weAreServer:
            self.sendHMAC, self.recvHMAC = util.swap(self.sendHMAC,
                                                     self.recvHMAC)
            self.sendCrypter, self.recvCrypter = util.swap(self.sendCrypter, \
                    self.recvCrypter)
            self.sendMagic, self.recvMagic = util.swap(self.sendMagic, \
                    self.recvMagic)

        log.debug("Magic values derived from session key: send=0x%s, " \
                "recv=0x%s." % (self.sendMagic.encode('hex'), \
                self.recvMagic.encode('hex')))
示例#4
0
 def runHKDF( self, ikm, salt, info, prk, okm ):
     myprk = self.extract(salt, ikm)
     self.failIf(myprk != prk)
     myokm = mycrypto.HKDF_SHA256(myprk, info).expand()
     self.failUnless(myokm in okm)