2020-01-22 03:56:20 +03:00
// SPDX-License-Identifier: GPL-2.0
/* Multipath TCP cryptographic functions
* Copyright ( c ) 2017 - 2019 , Intel Corporation .
*
* Note : This code is based on mptcp_ctrl . c , mptcp_ipv4 . c , and
* mptcp_ipv6 from multipath - tcp . org , authored by :
*
* Sébastien Barré < sebastien . barre @ uclouvain . be >
* Christoph Paasch < christoph . paasch @ uclouvain . be >
* Jaakko Korkeaniemi < jaakko . korkeaniemi @ aalto . fi >
* Gregory Detal < gregory . detal @ uclouvain . be >
* Fabien Duchêne < fabien . duchene @ uclouvain . be >
* Andreas Seelinger < Andreas . Seelinger @ rwth - aachen . de >
* Lavkesh Lahngir < lavkesh51 @ gmail . com >
* Andreas Ripke < ripke @ neclab . eu >
* Vlad Dogaru < vlad . dogaru @ intel . com >
* Octavian Purdila < octavian . purdila @ intel . com >
* John Ronan < jronan @ tssg . org >
* Catalin Nicutar < catalin . nicutar @ gmail . com >
* Brandon Heller < brandonh @ stanford . edu >
*/
# include <linux/kernel.h>
2020-01-22 03:56:30 +03:00
# include <crypto/sha.h>
2020-01-22 03:56:20 +03:00
# include <asm/unaligned.h>
# include "protocol.h"
2020-01-22 03:56:30 +03:00
# define SHA256_DIGEST_WORDS (SHA256_DIGEST_SIZE / 4)
2020-01-22 03:56:20 +03:00
void mptcp_crypto_key_sha ( u64 key , u32 * token , u64 * idsn )
{
2020-01-22 03:56:30 +03:00
__be32 mptcp_hashed_key [ SHA256_DIGEST_WORDS ] ;
__be64 input = cpu_to_be64 ( key ) ;
struct sha256_state state ;
2020-01-22 03:56:20 +03:00
2020-01-22 03:56:30 +03:00
sha256_init ( & state ) ;
sha256_update ( & state , ( __force u8 * ) & input , sizeof ( input ) ) ;
sha256_final ( & state , ( u8 * ) mptcp_hashed_key ) ;
2020-01-22 03:56:20 +03:00
if ( token )
* token = be32_to_cpu ( mptcp_hashed_key [ 0 ] ) ;
if ( idsn )
2020-01-22 03:56:30 +03:00
* idsn = be64_to_cpu ( * ( ( __be64 * ) & mptcp_hashed_key [ 6 ] ) ) ;
2020-01-22 03:56:20 +03:00
}
2020-03-28 00:48:37 +03:00
void mptcp_crypto_hmac_sha ( u64 key1 , u64 key2 , u8 * msg , int len , void * hmac )
2020-01-22 03:56:20 +03:00
{
2020-01-22 03:56:30 +03:00
u8 input [ SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE ] ;
struct sha256_state state ;
2020-01-22 03:56:20 +03:00
u8 key1be [ 8 ] ;
u8 key2be [ 8 ] ;
int i ;
2020-03-28 00:48:37 +03:00
if ( WARN_ON_ONCE ( len > SHA256_DIGEST_SIZE ) )
len = SHA256_DIGEST_SIZE ;
2020-01-22 03:56:20 +03:00
put_unaligned_be64 ( key1 , key1be ) ;
put_unaligned_be64 ( key2 , key2be ) ;
/* Generate key xored with ipad */
2020-05-02 21:24:21 +03:00
memset ( input , 0x36 , SHA256_BLOCK_SIZE ) ;
2020-01-22 03:56:20 +03:00
for ( i = 0 ; i < 8 ; i + + )
input [ i ] ^ = key1be [ i ] ;
for ( i = 0 ; i < 8 ; i + + )
input [ i + 8 ] ^ = key2be [ i ] ;
2020-03-28 00:48:37 +03:00
memcpy ( & input [ SHA256_BLOCK_SIZE ] , msg , len ) ;
2020-01-22 03:56:20 +03:00
2020-01-22 03:56:30 +03:00
sha256_init ( & state ) ;
2020-03-28 00:48:37 +03:00
sha256_update ( & state , input , SHA256_BLOCK_SIZE + len ) ;
2020-01-22 03:56:20 +03:00
/* emit sha256(K1 || msg) on the second input block, so we can
* reuse ' input ' for the last hashing
*/
2020-01-22 03:56:30 +03:00
sha256_final ( & state , & input [ SHA256_BLOCK_SIZE ] ) ;
2020-01-22 03:56:20 +03:00
/* Prepare second part of hmac */
2020-05-02 21:24:21 +03:00
memset ( input , 0x5C , SHA256_BLOCK_SIZE ) ;
2020-01-22 03:56:20 +03:00
for ( i = 0 ; i < 8 ; i + + )
input [ i ] ^ = key1be [ i ] ;
for ( i = 0 ; i < 8 ; i + + )
input [ i + 8 ] ^ = key2be [ i ] ;
2020-01-22 03:56:30 +03:00
sha256_init ( & state ) ;
sha256_update ( & state , input , SHA256_BLOCK_SIZE + SHA256_DIGEST_SIZE ) ;
2020-05-22 05:10:49 +03:00
sha256_final ( & state , ( u8 * ) hmac ) ;
2020-01-22 03:56:30 +03:00
}
2020-06-26 20:30:01 +03:00
# if IS_MODULE(CONFIG_MPTCP_KUNIT_TESTS)
EXPORT_SYMBOL_GPL ( mptcp_crypto_hmac_sha ) ;
2020-01-22 03:56:30 +03:00
# endif