18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/* Multipath TCP cryptographic functions
38c2ecf20Sopenharmony_ci * Copyright (c) 2017 - 2019, Intel Corporation.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Note: This code is based on mptcp_ctrl.c, mptcp_ipv4.c, and
68c2ecf20Sopenharmony_ci *       mptcp_ipv6 from multipath-tcp.org, authored by:
78c2ecf20Sopenharmony_ci *
88c2ecf20Sopenharmony_ci *       Sébastien Barré <sebastien.barre@uclouvain.be>
98c2ecf20Sopenharmony_ci *       Christoph Paasch <christoph.paasch@uclouvain.be>
108c2ecf20Sopenharmony_ci *       Jaakko Korkeaniemi <jaakko.korkeaniemi@aalto.fi>
118c2ecf20Sopenharmony_ci *       Gregory Detal <gregory.detal@uclouvain.be>
128c2ecf20Sopenharmony_ci *       Fabien Duchêne <fabien.duchene@uclouvain.be>
138c2ecf20Sopenharmony_ci *       Andreas Seelinger <Andreas.Seelinger@rwth-aachen.de>
148c2ecf20Sopenharmony_ci *       Lavkesh Lahngir <lavkesh51@gmail.com>
158c2ecf20Sopenharmony_ci *       Andreas Ripke <ripke@neclab.eu>
168c2ecf20Sopenharmony_ci *       Vlad Dogaru <vlad.dogaru@intel.com>
178c2ecf20Sopenharmony_ci *       Octavian Purdila <octavian.purdila@intel.com>
188c2ecf20Sopenharmony_ci *       John Ronan <jronan@tssg.org>
198c2ecf20Sopenharmony_ci *       Catalin Nicutar <catalin.nicutar@gmail.com>
208c2ecf20Sopenharmony_ci *       Brandon Heller <brandonh@stanford.edu>
218c2ecf20Sopenharmony_ci */
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#include <linux/kernel.h>
248c2ecf20Sopenharmony_ci#include <crypto/sha.h>
258c2ecf20Sopenharmony_ci#include <asm/unaligned.h>
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci#include "protocol.h"
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / 4)
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_civoid mptcp_crypto_key_sha(u64 key, u32 *token, u64 *idsn)
328c2ecf20Sopenharmony_ci{
338c2ecf20Sopenharmony_ci	__be32 mptcp_hashed_key[SHA256_DIGEST_WORDS];
348c2ecf20Sopenharmony_ci	__be64 input = cpu_to_be64(key);
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	sha256((__force u8 *)&input, sizeof(input), (u8 *)mptcp_hashed_key);
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci	if (token)
398c2ecf20Sopenharmony_ci		*token = be32_to_cpu(mptcp_hashed_key[0]);
408c2ecf20Sopenharmony_ci	if (idsn)
418c2ecf20Sopenharmony_ci		*idsn = be64_to_cpu(*((__be64 *)&mptcp_hashed_key[6]));
428c2ecf20Sopenharmony_ci}
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_civoid mptcp_crypto_hmac_sha(u64 key1, u64 key2, u8 *msg, int len, void *hmac)
458c2ecf20Sopenharmony_ci{
468c2ecf20Sopenharmony_ci	u8 input[SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE];
478c2ecf20Sopenharmony_ci	u8 key1be[8];
488c2ecf20Sopenharmony_ci	u8 key2be[8];
498c2ecf20Sopenharmony_ci	int i;
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	if (WARN_ON_ONCE(len > SHA256_DIGEST_SIZE))
528c2ecf20Sopenharmony_ci		len = SHA256_DIGEST_SIZE;
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	put_unaligned_be64(key1, key1be);
558c2ecf20Sopenharmony_ci	put_unaligned_be64(key2, key2be);
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci	/* Generate key xored with ipad */
588c2ecf20Sopenharmony_ci	memset(input, 0x36, SHA256_BLOCK_SIZE);
598c2ecf20Sopenharmony_ci	for (i = 0; i < 8; i++)
608c2ecf20Sopenharmony_ci		input[i] ^= key1be[i];
618c2ecf20Sopenharmony_ci	for (i = 0; i < 8; i++)
628c2ecf20Sopenharmony_ci		input[i + 8] ^= key2be[i];
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	memcpy(&input[SHA256_BLOCK_SIZE], msg, len);
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	/* emit sha256(K1 || msg) on the second input block, so we can
678c2ecf20Sopenharmony_ci	 * reuse 'input' for the last hashing
688c2ecf20Sopenharmony_ci	 */
698c2ecf20Sopenharmony_ci	sha256(input, SHA256_BLOCK_SIZE + len, &input[SHA256_BLOCK_SIZE]);
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	/* Prepare second part of hmac */
728c2ecf20Sopenharmony_ci	memset(input, 0x5C, SHA256_BLOCK_SIZE);
738c2ecf20Sopenharmony_ci	for (i = 0; i < 8; i++)
748c2ecf20Sopenharmony_ci		input[i] ^= key1be[i];
758c2ecf20Sopenharmony_ci	for (i = 0; i < 8; i++)
768c2ecf20Sopenharmony_ci		input[i + 8] ^= key2be[i];
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	sha256(input, SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE, hmac);
798c2ecf20Sopenharmony_ci}
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci#if IS_MODULE(CONFIG_MPTCP_KUNIT_TESTS)
828c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(mptcp_crypto_hmac_sha);
838c2ecf20Sopenharmony_ci#endif
84