Пример #1
0
func deriveKeys(chainKey []byte, kdf io.Reader) (send, recv []string, err error) {
	buffer := make([]byte, 64)
	for i := 0; i < msg.NumOfFutureKeys; i++ {
		if _, err := io.ReadFull(kdf, buffer); err != nil {
			return nil, nil, err
		}
		send = append(send, base64.Encode(cipher.HMAC(chainKey, buffer)))
		if _, err := io.ReadFull(kdf, buffer); err != nil {
			return nil, nil, err
		}
		recv = append(recv, base64.Encode(cipher.HMAC(chainKey, buffer)))
	}
	return
}
Пример #2
0
// generateMessageKeys generates the next numOfKeys many session keys from
// from rootKey for given senderIdentity and recipientIdentity.
// If recipientKeys is true the generated sender and reciever keys are stored in
// reverse order.
// It uses senderSessionPub and recipientPub in the process and calls
// keyStore.StoresSession and keyStore.SetSessionState to store the result.
func generateMessageKeys(
	senderIdentity, recipientIdentity string,
	senderIdentityPubkeyHash, recipientIdentityPubkeyHash string,
	rootKey *[32]byte,
	recipientKeys bool,
	senderSessionPub, recipientPub *[32]byte,
	numOfKeys uint64,
	keyStore session.Store,
) error {
	var (
		identities string
		send       []string
		recv       []string
	)

	// identity_fix = HASH(SORT(SenderNym, RecipientNym))
	if senderIdentity < recipientIdentity {
		identities = senderIdentity + recipientIdentity
	} else {
		identities = recipientIdentity + senderIdentity
	}
	identityFix := cipher.SHA512([]byte(identities))
	recipientPubHash := cipher.SHA512(recipientPub[:])
	senderSessionPubHash := cipher.SHA512(senderSessionPub[:])

	chainKey := rootKey[:]
	for i := uint64(0); i < numOfKeys; i++ {
		// messagekey_send[i] = HMAC_HASH(chainkey, "MESSAGE" | HASH(RecipientPub) | identity_fix)
		buffer := append([]byte("MESSAGE"), recipientPubHash...)
		buffer = append(buffer, identityFix...)
		send = append(send, base64.Encode(cipher.HMAC(chainKey, buffer)))

		// messagekey_recv[i] = HMAC_HASH(chainkey, "MESSAGE" | HASH(SenderSessionPub) | identity_fix)
		buffer = append([]byte("MESSAGE"), senderSessionPubHash...)
		buffer = append(buffer, identityFix...)
		recv = append(recv, base64.Encode(cipher.HMAC(chainKey, buffer)))

		// chainkey = HMAC_HASH(chainkey, "CHAIN" )
		chainKey = cipher.HMAC(chainKey, []byte("CHAIN"))[:32]
	}

	// calculate root key hash
	rootKeyHash := base64.Encode(cipher.SHA512(rootKey[:]))
	bzero.Bytes(rootKey[:])

	// reverse key material, if necessary
	if recipientKeys {
		send, recv = recv, send
	}

	// store session
	var sessionKey string
	if recipientKeys {
		key := recipientIdentityPubkeyHash
		key += senderIdentityPubkeyHash
		key += base64.Encode(cipher.SHA512(recipientPub[:]))
		key += base64.Encode(cipher.SHA512(senderSessionPub[:]))
		sessionKey = base64.Encode(cipher.SHA512([]byte(key)))
	} else {
		key := senderIdentityPubkeyHash
		key += recipientIdentityPubkeyHash
		key += base64.Encode(cipher.SHA512(senderSessionPub[:]))
		key += base64.Encode(cipher.SHA512(recipientPub[:]))
		sessionKey = base64.Encode(cipher.SHA512([]byte(key)))
	}
	err := keyStore.StoreSession(sessionKey, rootKeyHash,
		base64.Encode(chainKey), send, recv)
	if err != nil {
		return err
	}

	return nil
}