xref: /openbmc/linux/net/mptcp/crypto.c (revision 79c0949e9a09f6a14a6dd18dc8396029423f9b68)
1*79c0949eSPeter Krystad // SPDX-License-Identifier: GPL-2.0
2*79c0949eSPeter Krystad /* Multipath TCP cryptographic functions
3*79c0949eSPeter Krystad  * Copyright (c) 2017 - 2019, Intel Corporation.
4*79c0949eSPeter Krystad  *
5*79c0949eSPeter Krystad  * Note: This code is based on mptcp_ctrl.c, mptcp_ipv4.c, and
6*79c0949eSPeter Krystad  *       mptcp_ipv6 from multipath-tcp.org, authored by:
7*79c0949eSPeter Krystad  *
8*79c0949eSPeter Krystad  *       Sébastien Barré <sebastien.barre@uclouvain.be>
9*79c0949eSPeter Krystad  *       Christoph Paasch <christoph.paasch@uclouvain.be>
10*79c0949eSPeter Krystad  *       Jaakko Korkeaniemi <jaakko.korkeaniemi@aalto.fi>
11*79c0949eSPeter Krystad  *       Gregory Detal <gregory.detal@uclouvain.be>
12*79c0949eSPeter Krystad  *       Fabien Duchêne <fabien.duchene@uclouvain.be>
13*79c0949eSPeter Krystad  *       Andreas Seelinger <Andreas.Seelinger@rwth-aachen.de>
14*79c0949eSPeter Krystad  *       Lavkesh Lahngir <lavkesh51@gmail.com>
15*79c0949eSPeter Krystad  *       Andreas Ripke <ripke@neclab.eu>
16*79c0949eSPeter Krystad  *       Vlad Dogaru <vlad.dogaru@intel.com>
17*79c0949eSPeter Krystad  *       Octavian Purdila <octavian.purdila@intel.com>
18*79c0949eSPeter Krystad  *       John Ronan <jronan@tssg.org>
19*79c0949eSPeter Krystad  *       Catalin Nicutar <catalin.nicutar@gmail.com>
20*79c0949eSPeter Krystad  *       Brandon Heller <brandonh@stanford.edu>
21*79c0949eSPeter Krystad  */
22*79c0949eSPeter Krystad 
23*79c0949eSPeter Krystad #include <linux/kernel.h>
24*79c0949eSPeter Krystad #include <linux/cryptohash.h>
25*79c0949eSPeter Krystad #include <asm/unaligned.h>
26*79c0949eSPeter Krystad 
27*79c0949eSPeter Krystad #include "protocol.h"
28*79c0949eSPeter Krystad 
29*79c0949eSPeter Krystad struct sha1_state {
30*79c0949eSPeter Krystad 	u32 workspace[SHA_WORKSPACE_WORDS];
31*79c0949eSPeter Krystad 	u32 digest[SHA_DIGEST_WORDS];
32*79c0949eSPeter Krystad 	unsigned int count;
33*79c0949eSPeter Krystad };
34*79c0949eSPeter Krystad 
35*79c0949eSPeter Krystad static void sha1_init(struct sha1_state *state)
36*79c0949eSPeter Krystad {
37*79c0949eSPeter Krystad 	sha_init(state->digest);
38*79c0949eSPeter Krystad 	state->count = 0;
39*79c0949eSPeter Krystad }
40*79c0949eSPeter Krystad 
41*79c0949eSPeter Krystad static void sha1_update(struct sha1_state *state, u8 *input)
42*79c0949eSPeter Krystad {
43*79c0949eSPeter Krystad 	sha_transform(state->digest, input, state->workspace);
44*79c0949eSPeter Krystad 	state->count += SHA_MESSAGE_BYTES;
45*79c0949eSPeter Krystad }
46*79c0949eSPeter Krystad 
47*79c0949eSPeter Krystad static void sha1_pad_final(struct sha1_state *state, u8 *input,
48*79c0949eSPeter Krystad 			   unsigned int length, __be32 *mptcp_hashed_key)
49*79c0949eSPeter Krystad {
50*79c0949eSPeter Krystad 	int i;
51*79c0949eSPeter Krystad 
52*79c0949eSPeter Krystad 	input[length] = 0x80;
53*79c0949eSPeter Krystad 	memset(&input[length + 1], 0, SHA_MESSAGE_BYTES - length - 9);
54*79c0949eSPeter Krystad 	put_unaligned_be64((length + state->count) << 3,
55*79c0949eSPeter Krystad 			   &input[SHA_MESSAGE_BYTES - 8]);
56*79c0949eSPeter Krystad 
57*79c0949eSPeter Krystad 	sha_transform(state->digest, input, state->workspace);
58*79c0949eSPeter Krystad 	for (i = 0; i < SHA_DIGEST_WORDS; ++i)
59*79c0949eSPeter Krystad 		put_unaligned_be32(state->digest[i], &mptcp_hashed_key[i]);
60*79c0949eSPeter Krystad 
61*79c0949eSPeter Krystad 	memzero_explicit(state->workspace, SHA_WORKSPACE_WORDS << 2);
62*79c0949eSPeter Krystad }
63*79c0949eSPeter Krystad 
64*79c0949eSPeter Krystad void mptcp_crypto_key_sha(u64 key, u32 *token, u64 *idsn)
65*79c0949eSPeter Krystad {
66*79c0949eSPeter Krystad 	__be32 mptcp_hashed_key[SHA_DIGEST_WORDS];
67*79c0949eSPeter Krystad 	u8 input[SHA_MESSAGE_BYTES];
68*79c0949eSPeter Krystad 	struct sha1_state state;
69*79c0949eSPeter Krystad 
70*79c0949eSPeter Krystad 	sha1_init(&state);
71*79c0949eSPeter Krystad 	put_unaligned_be64(key, input);
72*79c0949eSPeter Krystad 	sha1_pad_final(&state, input, 8, mptcp_hashed_key);
73*79c0949eSPeter Krystad 
74*79c0949eSPeter Krystad 	if (token)
75*79c0949eSPeter Krystad 		*token = be32_to_cpu(mptcp_hashed_key[0]);
76*79c0949eSPeter Krystad 	if (idsn)
77*79c0949eSPeter Krystad 		*idsn = be64_to_cpu(*((__be64 *)&mptcp_hashed_key[3]));
78*79c0949eSPeter Krystad }
79*79c0949eSPeter Krystad 
80*79c0949eSPeter Krystad void mptcp_crypto_hmac_sha(u64 key1, u64 key2, u32 nonce1, u32 nonce2,
81*79c0949eSPeter Krystad 			   u32 *hash_out)
82*79c0949eSPeter Krystad {
83*79c0949eSPeter Krystad 	u8 input[SHA_MESSAGE_BYTES * 2];
84*79c0949eSPeter Krystad 	struct sha1_state state;
85*79c0949eSPeter Krystad 	u8 key1be[8];
86*79c0949eSPeter Krystad 	u8 key2be[8];
87*79c0949eSPeter Krystad 	int i;
88*79c0949eSPeter Krystad 
89*79c0949eSPeter Krystad 	put_unaligned_be64(key1, key1be);
90*79c0949eSPeter Krystad 	put_unaligned_be64(key2, key2be);
91*79c0949eSPeter Krystad 
92*79c0949eSPeter Krystad 	/* Generate key xored with ipad */
93*79c0949eSPeter Krystad 	memset(input, 0x36, SHA_MESSAGE_BYTES);
94*79c0949eSPeter Krystad 	for (i = 0; i < 8; i++)
95*79c0949eSPeter Krystad 		input[i] ^= key1be[i];
96*79c0949eSPeter Krystad 	for (i = 0; i < 8; i++)
97*79c0949eSPeter Krystad 		input[i + 8] ^= key2be[i];
98*79c0949eSPeter Krystad 
99*79c0949eSPeter Krystad 	put_unaligned_be32(nonce1, &input[SHA_MESSAGE_BYTES]);
100*79c0949eSPeter Krystad 	put_unaligned_be32(nonce2, &input[SHA_MESSAGE_BYTES + 4]);
101*79c0949eSPeter Krystad 
102*79c0949eSPeter Krystad 	sha1_init(&state);
103*79c0949eSPeter Krystad 	sha1_update(&state, input);
104*79c0949eSPeter Krystad 
105*79c0949eSPeter Krystad 	/* emit sha256(K1 || msg) on the second input block, so we can
106*79c0949eSPeter Krystad 	 * reuse 'input' for the last hashing
107*79c0949eSPeter Krystad 	 */
108*79c0949eSPeter Krystad 	sha1_pad_final(&state, &input[SHA_MESSAGE_BYTES], 8,
109*79c0949eSPeter Krystad 		       (__force __be32 *)&input[SHA_MESSAGE_BYTES]);
110*79c0949eSPeter Krystad 
111*79c0949eSPeter Krystad 	/* Prepare second part of hmac */
112*79c0949eSPeter Krystad 	memset(input, 0x5C, SHA_MESSAGE_BYTES);
113*79c0949eSPeter Krystad 	for (i = 0; i < 8; i++)
114*79c0949eSPeter Krystad 		input[i] ^= key1be[i];
115*79c0949eSPeter Krystad 	for (i = 0; i < 8; i++)
116*79c0949eSPeter Krystad 		input[i + 8] ^= key2be[i];
117*79c0949eSPeter Krystad 
118*79c0949eSPeter Krystad 	sha1_init(&state);
119*79c0949eSPeter Krystad 	sha1_update(&state, input);
120*79c0949eSPeter Krystad 	sha1_pad_final(&state, &input[SHA_MESSAGE_BYTES], SHA_DIGEST_WORDS << 2,
121*79c0949eSPeter Krystad 		       (__be32 *)hash_out);
122*79c0949eSPeter Krystad }
123