mirror of
https://gitlab.com/qemu-project/ipxe.git
synced 2025-11-03 07:59:06 +08:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 93a6e18086 | |||
| af4583b214 | |||
| 36a27b22b1 | |||
| 0cc0f47443 | |||
| 65d69d33da | |||
| 963ec1c4f3 | |||
| 8f6a9399b3 | |||
| a881a26061 | |||
| b234226dbc | |||
| 8e2469c861 | |||
| 989dbe0bc4 | |||
| 6f70e8be83 | |||
| 17135c83fb | |||
| 27398f1360 | |||
| de8a0821c7 | |||
| 2eea04c02c | |||
| 908174ec7e |
@ -46,8 +46,12 @@ static void efiarm_cpu_nap ( void ) {
|
||||
* The EFI shell doesn't seem to bother sleeping the CPU; it
|
||||
* just sits there idly burning power.
|
||||
*
|
||||
* If a shutdown is in progess, there may be nothing to
|
||||
* generate an interrupt since the timer is disabled in the
|
||||
* first step of ExitBootServices().
|
||||
*/
|
||||
__asm__ __volatile__ ( "wfi" );
|
||||
if ( ! efi_shutdown_in_progress )
|
||||
__asm__ __volatile__ ( "wfi" );
|
||||
}
|
||||
|
||||
PROVIDE_NAP ( efiarm, cpu_nap, efiarm_cpu_nap );
|
||||
|
||||
@ -53,34 +53,37 @@ bigint_add_raw ( const uint64_t *addend0, uint64_t *value0,
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_addend_i;
|
||||
uint64_t discard_value_i;
|
||||
uint64_t discard_carry;
|
||||
uint64_t discard_temp;
|
||||
unsigned int discard_size;
|
||||
__asm__ __volatile__ ( "move $t0, $zero\n"
|
||||
"1:\n\t"
|
||||
"ld.d %3, %0, 0\n\t"
|
||||
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
/* Load addend[i] and value[i] */
|
||||
"ld.d %3, %0, 0\n\t"
|
||||
"ld.d %4, %1, 0\n\t"
|
||||
/* Add carry flag and addend */
|
||||
"add.d %4, %4, %5\n\t"
|
||||
"sltu %6, %4, %5\n\t"
|
||||
"add.d %4, %4, %3\n\t"
|
||||
"sltu %5, %4, %3\n\t"
|
||||
"or %5, %5, %6\n\t"
|
||||
/* Store value[i] */
|
||||
"st.d %4, %1, 0\n\t"
|
||||
/* Loop */
|
||||
"addi.d %0, %0, 8\n\t"
|
||||
"ld.d %4, %1, 0\n\t"
|
||||
|
||||
"add.d %4, %4, $t0\n\t"
|
||||
"sltu $t0, %4, $t0\n\t"
|
||||
|
||||
"add.d %4, %4, %3\n\t"
|
||||
"sltu $t1, %4, %3\n\t"
|
||||
|
||||
"or $t0, $t0, $t1\n\t"
|
||||
"st.d %4, %1, 0\n\t"
|
||||
"addi.d %1, %1, 8\n\t"
|
||||
"addi.w %2, %2, -1\n\t"
|
||||
"bnez %2, 1b"
|
||||
"bnez %2, 1b\n\t"
|
||||
: "=r" ( discard_addend ),
|
||||
"=r" ( discard_value ),
|
||||
"=r" ( discard_size ),
|
||||
"=r" ( discard_addend_i ),
|
||||
"=r" ( discard_value_i ),
|
||||
"=r" ( discard_carry ),
|
||||
"=r" ( discard_temp ),
|
||||
"+m" ( *value )
|
||||
: "0" ( addend0 ),
|
||||
"1" ( value0 ),
|
||||
"2" ( size )
|
||||
: "t0", "t1" );
|
||||
: "0" ( addend0 ), "1" ( value0 ),
|
||||
"2" ( size ), "5" ( 0 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -93,35 +96,43 @@ bigint_add_raw ( const uint64_t *addend0, uint64_t *value0,
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_subtract_raw ( const uint64_t *subtrahend0, uint64_t *value0,
|
||||
unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint64_t *discard_subtrahend;
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_subtrahend_i;
|
||||
uint64_t discard_value_i;
|
||||
uint64_t discard_carry;
|
||||
uint64_t discard_temp;
|
||||
unsigned int discard_size;
|
||||
unsigned int flag = 0;
|
||||
|
||||
discard_subtrahend = (uint64_t*) subtrahend0;
|
||||
discard_value = value0;
|
||||
discard_size = size;
|
||||
|
||||
do {
|
||||
discard_subtrahend_i = *discard_subtrahend;
|
||||
discard_subtrahend++;
|
||||
discard_value_i = *discard_value;
|
||||
|
||||
discard_value_i = discard_value_i - discard_subtrahend_i - flag;
|
||||
|
||||
if ( *discard_value < (discard_subtrahend_i + flag)) {
|
||||
flag = 1;
|
||||
} else {
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
*discard_value = discard_value_i;
|
||||
|
||||
discard_value++;
|
||||
discard_size -= 1;
|
||||
} while (discard_size != 0);
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
/* Load subtrahend[i] and value[i] */
|
||||
"ld.d %3, %0, 0\n\t"
|
||||
"ld.d %4, %1, 0\n\t"
|
||||
/* Subtract carry flag and subtrahend */
|
||||
"sltu %6, %4, %5\n\t"
|
||||
"sub.d %4, %4, %5\n\t"
|
||||
"sltu %5, %4, %3\n\t"
|
||||
"sub.d %4, %4, %3\n\t"
|
||||
"or %5, %5, %6\n\t"
|
||||
/* Store value[i] */
|
||||
"st.d %4, %1, 0\n\t"
|
||||
/* Loop */
|
||||
"addi.d %0, %0, 8\n\t"
|
||||
"addi.d %1, %1, 8\n\t"
|
||||
"addi.w %2, %2, -1\n\t"
|
||||
"bnez %2, 1b\n\t"
|
||||
: "=r" ( discard_subtrahend ),
|
||||
"=r" ( discard_value ),
|
||||
"=r" ( discard_size ),
|
||||
"=r" ( discard_subtrahend_i ),
|
||||
"=r" ( discard_value_i ),
|
||||
"=r" ( discard_carry ),
|
||||
"=r" ( discard_temp ),
|
||||
"+m" ( *value )
|
||||
: "0" ( subtrahend0 ), "1" ( value0 ),
|
||||
"2" ( size ), "5" ( 0 ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,30 +143,37 @@ bigint_subtract_raw ( const uint64_t *subtrahend0, uint64_t *value0,
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_rol_raw ( uint64_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_value_i;
|
||||
uint64_t discard_carry;
|
||||
uint64_t discard_temp;
|
||||
unsigned int discard_size;
|
||||
uint64_t current_value_i;
|
||||
unsigned int flag = 0;
|
||||
|
||||
discard_value = value0;
|
||||
discard_size = size;
|
||||
do {
|
||||
discard_value_i = *discard_value;
|
||||
current_value_i = discard_value_i;
|
||||
|
||||
discard_value_i += discard_value_i + flag;
|
||||
|
||||
if (discard_value_i < current_value_i) {
|
||||
flag = 1;
|
||||
} else {
|
||||
flag = 0;
|
||||
}
|
||||
|
||||
*discard_value = discard_value_i;
|
||||
discard_value++;
|
||||
discard_size -= 1;
|
||||
} while ( discard_size != 0 );
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
/* Load value[i] */
|
||||
"ld.d %2, %0, 0\n\t"
|
||||
/* Shift left */
|
||||
"rotri.d %2, %2, 63\n\t"
|
||||
"andi %4, %2, 1\n\t"
|
||||
"xor %2, %2, %4\n\t"
|
||||
"or %2, %2, %3\n\t"
|
||||
"move %3, %4\n\t"
|
||||
/* Store value[i] */
|
||||
"st.d %2, %0, 0\n\t"
|
||||
/* Loop */
|
||||
"addi.d %0, %0, 8\n\t"
|
||||
"addi.w %1, %1, -1\n\t"
|
||||
"bnez %1, 1b\n\t"
|
||||
: "=r" ( discard_value ),
|
||||
"=r" ( discard_size ),
|
||||
"=r" ( discard_value_i ),
|
||||
"=r" ( discard_carry ),
|
||||
"=r" ( discard_temp ),
|
||||
"+m" ( *value )
|
||||
: "0" ( value0 ), "1" ( size ), "3" ( 0 )
|
||||
: "cc" );
|
||||
}
|
||||
|
||||
/**
|
||||
@ -166,27 +184,37 @@ bigint_rol_raw ( uint64_t *value0, unsigned int size ) {
|
||||
*/
|
||||
static inline __attribute__ (( always_inline )) void
|
||||
bigint_ror_raw ( uint64_t *value0, unsigned int size ) {
|
||||
bigint_t ( size ) __attribute__ (( may_alias )) *value =
|
||||
( ( void * ) value0 );
|
||||
uint64_t *discard_value;
|
||||
uint64_t discard_value_i;
|
||||
uint64_t discard_value_j;
|
||||
uint64_t discard_carry;
|
||||
uint64_t discard_temp;
|
||||
unsigned int discard_size;
|
||||
|
||||
discard_value = value0;
|
||||
discard_size = size;
|
||||
|
||||
discard_value_j = 0;
|
||||
|
||||
do {
|
||||
discard_size -= 1;
|
||||
|
||||
discard_value_i = *(discard_value + discard_size);
|
||||
|
||||
discard_value_j = (discard_value_j << 63) | (discard_value_i >> 1);
|
||||
|
||||
*(discard_value + discard_size) = discard_value_j;
|
||||
|
||||
discard_value_j = discard_value_i;
|
||||
} while ( discard_size > 0 );
|
||||
__asm__ __volatile__ ( "\n1:\n\t"
|
||||
/* Load value[i] */
|
||||
"ld.d %2, %0, -8\n\t"
|
||||
/* Shift right */
|
||||
"andi %4, %2, 1\n\t"
|
||||
"xor %2, %2, %4\n\t"
|
||||
"or %2, %2, %3\n\t"
|
||||
"move %3, %4\n\t"
|
||||
"rotri.d %2, %2, 1\n\t"
|
||||
/* Store value[i] */
|
||||
"st.d %2, %0, -8\n\t"
|
||||
/* Loop */
|
||||
"addi.d %0, %0, -8\n\t"
|
||||
"addi.w %1, %1, -1\n\t"
|
||||
"bnez %1, 1b\n\t"
|
||||
: "=r" ( discard_value ),
|
||||
"=r" ( discard_size ),
|
||||
"=r" ( discard_value_i ),
|
||||
"=r" ( discard_carry ),
|
||||
"=r" ( discard_temp ),
|
||||
"+m" ( *value )
|
||||
: "0" ( value0 + size ), "1" ( size ), "3" ( 0 )
|
||||
: "cc" );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -46,8 +46,12 @@ static void efiloong64_cpu_nap ( void ) {
|
||||
* The EFI shell doesn't seem to bother sleeping the CPU; it
|
||||
* just sits there idly burning power.
|
||||
*
|
||||
* If a shutdown is in progess, there may be nothing to
|
||||
* generate an interrupt since the timer is disabled in the
|
||||
* first step of ExitBootServices().
|
||||
*/
|
||||
__asm__ __volatile__ ( "idle 0" );
|
||||
if ( ! efi_shutdown_in_progress )
|
||||
__asm__ __volatile__ ( "idle 0" );
|
||||
}
|
||||
|
||||
PROVIDE_NAP ( efiloong64, cpu_nap, efiloong64_cpu_nap );
|
||||
|
||||
@ -46,8 +46,12 @@ static void efix86_cpu_nap ( void ) {
|
||||
* The EFI shell doesn't seem to bother sleeping the CPU; it
|
||||
* just sits there idly burning power.
|
||||
*
|
||||
* If a shutdown is in progess, there may be nothing to
|
||||
* generate an interrupt since the timer is disabled in the
|
||||
* first step of ExitBootServices().
|
||||
*/
|
||||
__asm__ __volatile__ ( "hlt" );
|
||||
if ( ! efi_shutdown_in_progress )
|
||||
__asm__ __volatile__ ( "hlt" );
|
||||
}
|
||||
|
||||
PROVIDE_NAP ( efix86, cpu_nap, efix86_cpu_nap );
|
||||
|
||||
@ -83,6 +83,11 @@ REQUIRE_OBJECT ( oid_sha512_224 );
|
||||
REQUIRE_OBJECT ( oid_sha512_256 );
|
||||
#endif
|
||||
|
||||
/* X25519 */
|
||||
#if defined ( CRYPTO_CURVE_X25519 )
|
||||
REQUIRE_OBJECT ( oid_x25519 );
|
||||
#endif
|
||||
|
||||
/* RSA and MD5 */
|
||||
#if defined ( CRYPTO_PUBKEY_RSA ) && defined ( CRYPTO_DIGEST_MD5 )
|
||||
REQUIRE_OBJECT ( rsa_md5 );
|
||||
@ -114,25 +119,79 @@ REQUIRE_OBJECT ( rsa_sha512 );
|
||||
#endif
|
||||
|
||||
/* RSA, AES-CBC, and SHA-1 */
|
||||
#if defined ( CRYPTO_PUBKEY_RSA ) && defined ( CRYPTO_CIPHER_AES_CBC ) && \
|
||||
defined ( CRYPTO_DIGEST_SHA1 )
|
||||
#if defined ( CRYPTO_EXCHANGE_PUBKEY ) && defined ( CRYPTO_PUBKEY_RSA ) && \
|
||||
defined ( CRYPTO_CIPHER_AES_CBC ) && defined ( CRYPTO_DIGEST_SHA1 )
|
||||
REQUIRE_OBJECT ( rsa_aes_cbc_sha1 );
|
||||
#endif
|
||||
|
||||
/* RSA, AES-CBC, and SHA-256 */
|
||||
#if defined ( CRYPTO_PUBKEY_RSA ) && defined ( CRYPTO_CIPHER_AES_CBC ) && \
|
||||
defined ( CRYPTO_DIGEST_SHA256 )
|
||||
#if defined ( CRYPTO_EXCHANGE_PUBKEY ) && defined ( CRYPTO_PUBKEY_RSA ) && \
|
||||
defined ( CRYPTO_CIPHER_AES_CBC ) && defined ( CRYPTO_DIGEST_SHA256 )
|
||||
REQUIRE_OBJECT ( rsa_aes_cbc_sha256 );
|
||||
#endif
|
||||
|
||||
/* RSA, AES-GCM, and SHA-256 */
|
||||
#if defined ( CRYPTO_PUBKEY_RSA ) && defined ( CRYPTO_CIPHER_AES_GCM ) && \
|
||||
defined ( CRYPTO_DIGEST_SHA256 )
|
||||
#if defined ( CRYPTO_EXCHANGE_PUBKEY ) && defined ( CRYPTO_PUBKEY_RSA ) && \
|
||||
defined ( CRYPTO_CIPHER_AES_GCM ) && defined ( CRYPTO_DIGEST_SHA256 )
|
||||
REQUIRE_OBJECT ( rsa_aes_gcm_sha256 );
|
||||
#endif
|
||||
|
||||
/* RSA, AES-GCM, and SHA-384 */
|
||||
#if defined ( CRYPTO_PUBKEY_RSA ) && defined ( CRYPTO_CIPHER_AES_GCM ) && \
|
||||
defined ( CRYPTO_DIGEST_SHA384 )
|
||||
#if defined ( CRYPTO_EXCHANGE_PUBKEY ) && defined ( CRYPTO_PUBKEY_RSA ) && \
|
||||
defined ( CRYPTO_CIPHER_AES_GCM ) && defined ( CRYPTO_DIGEST_SHA384 )
|
||||
REQUIRE_OBJECT ( rsa_aes_gcm_sha384 );
|
||||
#endif
|
||||
|
||||
/* DHE, RSA, AES-CBC, and SHA-1 */
|
||||
#if defined ( CRYPTO_EXCHANGE_DHE ) && defined ( CRYPTO_PUBKEY_RSA ) && \
|
||||
defined ( CRYPTO_CIPHER_AES_CBC ) && defined ( CRYPTO_DIGEST_SHA1 )
|
||||
REQUIRE_OBJECT ( dhe_rsa_aes_cbc_sha1 );
|
||||
#endif
|
||||
|
||||
/* DHE, RSA, AES-CBC, and SHA-256 */
|
||||
#if defined ( CRYPTO_EXCHANGE_DHE ) && defined ( CRYPTO_PUBKEY_RSA ) && \
|
||||
defined ( CRYPTO_CIPHER_AES_CBC ) && defined ( CRYPTO_DIGEST_SHA256 )
|
||||
REQUIRE_OBJECT ( dhe_rsa_aes_cbc_sha256 );
|
||||
#endif
|
||||
|
||||
/* DHE, RSA, AES-GCM, and SHA-256 */
|
||||
#if defined ( CRYPTO_EXCHANGE_DHE ) && defined ( CRYPTO_PUBKEY_RSA ) && \
|
||||
defined ( CRYPTO_CIPHER_AES_GCM ) && defined ( CRYPTO_DIGEST_SHA256 )
|
||||
REQUIRE_OBJECT ( dhe_rsa_aes_gcm_sha256 );
|
||||
#endif
|
||||
|
||||
/* DHE, RSA, AES-GCM, and SHA-384 */
|
||||
#if defined ( CRYPTO_EXCHANGE_DHE ) && defined ( CRYPTO_PUBKEY_RSA ) && \
|
||||
defined ( CRYPTO_CIPHER_AES_GCM ) && defined ( CRYPTO_DIGEST_SHA384 )
|
||||
REQUIRE_OBJECT ( dhe_rsa_aes_gcm_sha384 );
|
||||
#endif
|
||||
|
||||
/* ECDHE, RSA, AES-CBC, and SHA-1 */
|
||||
#if defined ( CRYPTO_EXCHANGE_ECDHE ) && defined ( CRYPTO_PUBKEY_RSA ) && \
|
||||
defined ( CRYPTO_CIPHER_AES_CBC ) && defined ( CRYPTO_DIGEST_SHA1 )
|
||||
REQUIRE_OBJECT ( ecdhe_rsa_aes_cbc_sha1 );
|
||||
#endif
|
||||
|
||||
/* ECDHE, RSA, AES-CBC, and SHA-256 */
|
||||
#if defined ( CRYPTO_EXCHANGE_ECDHE ) && defined ( CRYPTO_PUBKEY_RSA ) && \
|
||||
defined ( CRYPTO_CIPHER_AES_CBC ) && defined ( CRYPTO_DIGEST_SHA256 )
|
||||
REQUIRE_OBJECT ( ecdhe_rsa_aes_cbc_sha256 );
|
||||
#endif
|
||||
|
||||
/* ECDHE, RSA, AES-CBC, and SHA-384 */
|
||||
#if defined ( CRYPTO_EXCHANGE_ECDHE ) && defined ( CRYPTO_PUBKEY_RSA ) && \
|
||||
defined ( CRYPTO_CIPHER_AES_CBC ) && defined ( CRYPTO_DIGEST_SHA384 )
|
||||
REQUIRE_OBJECT ( ecdhe_rsa_aes_cbc_sha384 );
|
||||
#endif
|
||||
|
||||
/* ECDHE, RSA, AES-GCM, and SHA-256 */
|
||||
#if defined ( CRYPTO_EXCHANGE_ECDHE ) && defined ( CRYPTO_PUBKEY_RSA ) && \
|
||||
defined ( CRYPTO_CIPHER_AES_GCM ) && defined ( CRYPTO_DIGEST_SHA256 )
|
||||
REQUIRE_OBJECT ( ecdhe_rsa_aes_gcm_sha256 );
|
||||
#endif
|
||||
|
||||
/* ECDHE, RSA, AES-GCM, and SHA-384 */
|
||||
#if defined ( CRYPTO_EXCHANGE_ECDHE ) && defined ( CRYPTO_PUBKEY_RSA ) && \
|
||||
defined ( CRYPTO_CIPHER_AES_GCM ) && defined ( CRYPTO_DIGEST_SHA384 )
|
||||
REQUIRE_OBJECT ( ecdhe_rsa_aes_gcm_sha384 );
|
||||
#endif
|
||||
|
||||
@ -12,6 +12,15 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
/** Minimum TLS version */
|
||||
#define TLS_VERSION_MIN TLS_VERSION_TLS_1_1
|
||||
|
||||
/** Public-key exchange algorithm */
|
||||
#define CRYPTO_EXCHANGE_PUBKEY
|
||||
|
||||
/** DHE key exchange algorithm */
|
||||
#define CRYPTO_EXCHANGE_DHE
|
||||
|
||||
/** ECDHE key exchange algorithm */
|
||||
#define CRYPTO_EXCHANGE_ECDHE
|
||||
|
||||
/** RSA public-key algorithm */
|
||||
#define CRYPTO_PUBKEY_RSA
|
||||
|
||||
@ -48,6 +57,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
/** SHA-512/256 digest algorithm */
|
||||
//#define CRYPTO_DIGEST_SHA512_256
|
||||
|
||||
/** X25519 elliptic curve */
|
||||
#define CRYPTO_CURVE_X25519
|
||||
|
||||
/** Margin of error (in seconds) allowed in signed timestamps
|
||||
*
|
||||
* We default to allowing a reasonable margin of error: 12 hours to
|
||||
|
||||
695
src/crypto/des.c
Normal file
695
src/crypto/des.c
Normal file
@ -0,0 +1,695 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* DES algorithm
|
||||
*
|
||||
* DES was not designed to be implemented in software, and therefore
|
||||
* contains a large number of bit permutation operations that are
|
||||
* essentially free in hardware (requiring only wires, no gates) but
|
||||
* expensive in software.
|
||||
*
|
||||
* Since DES is no longer used as a practical block cipher for large
|
||||
* volumes of data, we optimise for code size, and do not attempt to
|
||||
* obtain fast throughput.
|
||||
*
|
||||
* The algorithm is specified in NIST SP 800-67, downloadable from
|
||||
* https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-67r2.pdf
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rotate.h>
|
||||
#include <ipxe/crypto.h>
|
||||
#include <ipxe/ecb.h>
|
||||
#include <ipxe/cbc.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/des.h>
|
||||
|
||||
/**
|
||||
* DES shift schedule
|
||||
*
|
||||
* The DES shift schedule (ordered from round 16 down to round 1) is
|
||||
* {1,2,2,2,2,2,2,1,2,2,2,2,2,2,1,1}. In binary, this may be
|
||||
* represented as {1,10,10,10,10,10,10,1,10,10,10,10,10,10,1,1} and
|
||||
* concatenated (without padding) to produce a single binary integer
|
||||
* 1101010101010110101010101011 (equal to 0x0d556aab in hexadecimal).
|
||||
*
|
||||
* This integer may then be consumed LSB-first, where a 1 bit
|
||||
* indicates a shift and the generation of a round key, and a 0 bit
|
||||
* indicates a shift without the generation of a round key.
|
||||
*/
|
||||
#define DES_SCHEDULE 0x0d556aab
|
||||
|
||||
/**
|
||||
* Define an element pair in a DES S-box
|
||||
*
|
||||
* @v x Upper element of element pair
|
||||
* @v y Lower element of element pair
|
||||
*
|
||||
* DES S-box elements are 4-bit values. We encode two values per
|
||||
* byte, ordering the elements so that the six-bit input value may be
|
||||
* used directly as a lookup index.
|
||||
*
|
||||
* Specifically, if the input value is {r1,c3,c2,c1,c0,r0}, where
|
||||
* {r1,r0} is the table row index and {c3,c2,c1,c0} is the table
|
||||
* column index (as used in the DES specification), then:
|
||||
*
|
||||
* - {r1,c3,c2,c1,c0} is the byte index into the table
|
||||
*
|
||||
* - (4*r0) is the required bit shift to extract the 4-bit value
|
||||
*/
|
||||
#define SBYTE( x, y ) ( ( (y) << 4 ) | (x) )
|
||||
|
||||
/**
|
||||
* Define a row pair in a DES S-box
|
||||
*
|
||||
* @v x0..xf Upper row of row pair
|
||||
* @v y0..yf Lower row of row pair
|
||||
*/
|
||||
#define SBOX( x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, xa, xb, xc, xd, xe, xf, \
|
||||
y0, y1, y2, y3, y4, y5, y6, y7, y8, y9, ya, yb, yc, yd, ye, yf ) \
|
||||
SBYTE ( x0, y0 ), SBYTE ( x1, y1 ), SBYTE ( x2, y2 ), SBYTE ( x3, y3 ),\
|
||||
SBYTE ( x4, y4 ), SBYTE ( x5, y5 ), SBYTE ( x6, y6 ), SBYTE ( x7, y7 ),\
|
||||
SBYTE ( x8, y8 ), SBYTE ( x9, y9 ), SBYTE ( xa, ya ), SBYTE ( xb, yb ),\
|
||||
SBYTE ( xc, yc ), SBYTE ( xd, yd ), SBYTE ( xe, ye ), SBYTE ( xf, yf )
|
||||
|
||||
/** DES S-boxes S1..S8 */
|
||||
static const uint8_t des_s[8][32] = { {
|
||||
/* S1 */
|
||||
SBOX ( 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
|
||||
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 ),
|
||||
SBOX ( 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
|
||||
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 )
|
||||
}, {
|
||||
/* S2 */
|
||||
SBOX ( 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
|
||||
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 ),
|
||||
SBOX ( 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
|
||||
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 )
|
||||
}, {
|
||||
/* S3 */
|
||||
SBOX ( 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
|
||||
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 ),
|
||||
SBOX ( 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
|
||||
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 )
|
||||
}, {
|
||||
/* S4 */
|
||||
SBOX ( 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
|
||||
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 ),
|
||||
SBOX ( 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
|
||||
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 )
|
||||
}, {
|
||||
/* S5 */
|
||||
SBOX ( 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
|
||||
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 ),
|
||||
SBOX ( 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
|
||||
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 )
|
||||
}, {
|
||||
/* S6 */
|
||||
SBOX ( 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
|
||||
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 ),
|
||||
SBOX ( 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
|
||||
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 )
|
||||
}, {
|
||||
/* S7 */
|
||||
SBOX ( 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
|
||||
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 ),
|
||||
SBOX ( 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
|
||||
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 )
|
||||
}, {
|
||||
/* S8 */
|
||||
SBOX ( 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
|
||||
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 ),
|
||||
SBOX ( 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
|
||||
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 )
|
||||
} };
|
||||
|
||||
/**
|
||||
* Define a bit index within permuted choice 2 (PC2)
|
||||
*
|
||||
* @v bit Bit index
|
||||
*
|
||||
* Permuted choice 2 (PC2) is used to select bits from a concatenated
|
||||
* pair of 28-bit registers ("C" and "D") as part of the key schedule.
|
||||
* We store these as 32-bit registers and so must add 4 to indexes
|
||||
* above 28.
|
||||
*/
|
||||
#define DES_PC2( x ) ( (x) + ( ( (x) > 28 ) ? 4 : 0 ) )
|
||||
|
||||
/**
|
||||
* Define six bits of permuted choice 2 (PC2)
|
||||
*
|
||||
* @v r1:r0 Bits corresponding to S-box row index
|
||||
* @v c3:c0 Bits corresponding to S-box column index
|
||||
*
|
||||
* There are 8 steps within a DES round (one step per S-box). Each
|
||||
* step requires six bits of the round key, corresponding to the S-box
|
||||
* input value {r1,c3,c2,c1,c0,r0}, where {r1,r0} is the table row
|
||||
* index and {c3,c2,c1,c0} is the table column index.
|
||||
*
|
||||
* As an optimisation, we store the least significant of the 6 bits in
|
||||
* the sign bit of a signed 8-bit value, and the remaining 5 bits in
|
||||
* the least significant 5 bits of the 8-bit value. See the comments
|
||||
* in des_sbox() for further details.
|
||||
*/
|
||||
#define DES_PC2R( r1, c3, c2, c1, c0, r0 ) \
|
||||
DES_PC2 ( r0 ), /* LSB stored in sign bit */ \
|
||||
DES_PC2 ( r0 ), /* Unused bit */ \
|
||||
DES_PC2 ( r0 ), /* Unused bit */ \
|
||||
DES_PC2 ( r1 ), /* Remaining 5 bits */ \
|
||||
DES_PC2 ( c3 ), /* ... */ \
|
||||
DES_PC2 ( c2 ), /* ... */ \
|
||||
DES_PC2 ( c1 ), /* ... */ \
|
||||
DES_PC2 ( c0 ) /* ... */
|
||||
|
||||
/**
|
||||
* A DES systematic permutation generator
|
||||
*
|
||||
* Many of the permutations used in DES comprise systematic bit
|
||||
* patterns. We generate these permutations at runtime to save on
|
||||
* code size.
|
||||
*/
|
||||
struct des_generator {
|
||||
/** Permutation */
|
||||
uint8_t *permutation;
|
||||
/** Seed value */
|
||||
uint32_t seed;
|
||||
};
|
||||
|
||||
/**
|
||||
* Define a DES permutation generator
|
||||
*
|
||||
* @v PERMUTATION Permutation
|
||||
* @v OFFSET Fixed input bit offset (0 or 1)
|
||||
* @v INV<n> Input bit index bit <n> should be inverted
|
||||
* @v BIT<n> Source bit for input bit index bit <n>
|
||||
* @ret generator Permutation generator
|
||||
*/
|
||||
#define DES_GENERATOR( PERMUTATION, OFFSET, INV5, BIT5, INV4, BIT4, \
|
||||
INV3, BIT3, INV2, BIT2, INV1, BIT1, INV0, BIT0 ) \
|
||||
{ \
|
||||
.permutation = (PERMUTATION), \
|
||||
.seed = ( ( (INV0) << 31 ) | ( (BIT0) << 28 ) | \
|
||||
( (INV1) << 27 ) | ( (BIT1) << 24 ) | \
|
||||
( (INV2) << 23 ) | ( (BIT2) << 20 ) | \
|
||||
( (INV3) << 19 ) | ( (BIT3) << 16 ) | \
|
||||
( (INV4) << 15 ) | ( (BIT4) << 12 ) | \
|
||||
( (INV5) << 11 ) | ( (BIT5) << 8 ) | \
|
||||
( ( uint32_t ) sizeof (PERMUTATION) - 1 ) | \
|
||||
(OFFSET) ), \
|
||||
}
|
||||
|
||||
/** DES permuted choice 1 (PC1) "C" register */
|
||||
static uint8_t des_pc1c[29];
|
||||
|
||||
/** DES permuted choice 1 (PC1) "D" register */
|
||||
static uint8_t des_pc1d[33];
|
||||
|
||||
/** DES permuted choice 2 (PC2) */
|
||||
static const uint8_t des_pc2[65] = {
|
||||
DES_PC2R ( 14, 17, 11, 24, 1, 5 ),
|
||||
DES_PC2R ( 3, 28, 15, 6, 21, 10 ),
|
||||
DES_PC2R ( 23, 19, 12, 4, 26, 8 ),
|
||||
DES_PC2R ( 16, 7, 27, 20, 13, 2 ),
|
||||
DES_PC2R ( 41, 52, 31, 37, 47, 55 ),
|
||||
DES_PC2R ( 30, 40, 51, 45, 33, 48 ),
|
||||
DES_PC2R ( 44, 49, 39, 56, 34, 53 ),
|
||||
DES_PC2R ( 46, 42, 50, 36, 29, 32 ),
|
||||
0 /* terminator */
|
||||
};
|
||||
|
||||
/** DES initial permutation (IP) */
|
||||
static uint8_t des_ip[65];
|
||||
|
||||
/** DES data permutation (P) */
|
||||
static const uint8_t des_p[33] = {
|
||||
16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
|
||||
2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25,
|
||||
0 /* terminator */
|
||||
};
|
||||
|
||||
/** DES final / inverse initial permutation (FP / IP^-1) */
|
||||
static uint8_t des_fp[65];
|
||||
|
||||
/** DES permutation generators */
|
||||
static struct des_generator des_generators[] = {
|
||||
|
||||
/* The DES initial permutation transforms the bit index
|
||||
* {x5,x4,x3,x2,x1,x0}+1 into {~x2,~x1,~x0,x4,x3,~x5}+1
|
||||
*/
|
||||
DES_GENERATOR ( des_ip, 1, 1, 2, 1, 1, 1, 0, 0, 4, 0, 3, 1, 5 ),
|
||||
|
||||
/* The DES final permutation transforms the bit index
|
||||
* {x5,x4,x3,x2,x1,x0}+1 into {~x0,x2,x1,~x5,~x4,~x3}+1
|
||||
*
|
||||
* There is an asymmetry in the DES block diagram for the last
|
||||
* of the 16 rounds, which is functionally equivalent to
|
||||
* performing 16 identical rounds and then swapping the left
|
||||
* and right halves before applying the final permutation. We
|
||||
* may therefore account for this asymmetry by inverting the
|
||||
* MSB in each bit index, to point to the corresponding bit in
|
||||
* the other half.
|
||||
*
|
||||
* This is equivalent to using a permutation that transforms
|
||||
* {x5,x4,x3,x2,x1,x0}+1 into {x0,x2,x1,~x5,~x4,~x3}+1
|
||||
*/
|
||||
DES_GENERATOR ( des_fp, 1, 0, 0, 0, 2, 0, 1, 1, 5, 1, 4, 1, 3 ),
|
||||
|
||||
/* The "C" half of DES permuted choice 1 (PC1) transforms the
|
||||
* bit index {x5,x4,x3,x2,x1,x0}+1 into {~x2,~x1,~x0,x5,x4,x3}+1
|
||||
*/
|
||||
DES_GENERATOR ( des_pc1c, 1, 1, 2, 1, 1, 1, 0, 0, 5, 0, 4, 0, 3 ),
|
||||
|
||||
/* The "D" half of DES permuted choice 1 (PC1) transforms the
|
||||
* bit index {x5,x4,x3,x2,x1,x0}+1 into {~x2,~x1,~x0,~x5,~x4,~x3}+0
|
||||
*
|
||||
* Due to the idosyncratic design choice of using 28-bit
|
||||
* registers in the DES key expansion schedule, the final four
|
||||
* permutation values appear at indices [28:31] instead of
|
||||
* [24:27]. This is adjusted for in @c des_setkey().
|
||||
*/
|
||||
DES_GENERATOR ( des_pc1d, 0, 1, 2, 1, 1, 1, 0, 1, 5, 1, 4, 1, 3 ),
|
||||
};
|
||||
|
||||
/**
|
||||
* Generate DES permutation
|
||||
*
|
||||
* @v generator Generator
|
||||
*/
|
||||
static __attribute__ (( noinline )) void
|
||||
des_generate ( struct des_generator *generator ) {
|
||||
uint8_t *permutation = generator->permutation;
|
||||
uint32_t seed = generator->seed;
|
||||
unsigned int index = 0;
|
||||
uint8_t accum;
|
||||
uint8_t bit;
|
||||
|
||||
/* Generate permutations
|
||||
*
|
||||
* This loop is optimised for code size on a
|
||||
* register-constrained architecture such as i386.
|
||||
*/
|
||||
do {
|
||||
/* Rotate seed to access MSB's bit descriptor */
|
||||
seed = ror32 ( seed, 8 );
|
||||
|
||||
/* Initialise accumulator with six flag bits */
|
||||
accum = 0xfc;
|
||||
|
||||
/* Accumulate bits until all six flag bits are cleared */
|
||||
do {
|
||||
/* Extract specified bit from index. Use a
|
||||
* rotation instead of a shift, since this
|
||||
* will allow the mask to be elided.
|
||||
*/
|
||||
bit = ror8 ( index, ( seed & 0x07 ) );
|
||||
seed = ror32 ( seed, 3 );
|
||||
|
||||
/* Toggle bit if applicable */
|
||||
bit ^= seed;
|
||||
seed = ror32 ( seed, 1 );
|
||||
|
||||
/* Add bit to accumulator and clear one flag bit */
|
||||
accum <<= 1;
|
||||
accum |= ( bit & 0x01 );
|
||||
|
||||
} while ( accum & 0x80 );
|
||||
|
||||
/* Add constant offset if applicable */
|
||||
accum += ( seed & 0x01 );
|
||||
|
||||
/* Store permutation */
|
||||
permutation[index] = accum;
|
||||
|
||||
/* Loop until reaching length (which is always even) */
|
||||
} while ( ++index < ( seed & 0xfe ) );
|
||||
DBGC2 ( permutation, "DES generated permutation %p:\n", permutation );
|
||||
DBGC2_HDA ( permutation, 0, permutation,
|
||||
( ( seed & 0xfe ) + 1 /* zero terminator */ ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialise permutations
|
||||
*/
|
||||
static void des_init ( void ) {
|
||||
unsigned int i;
|
||||
|
||||
/* Generate all generated permutations */
|
||||
for ( i = 0 ; i < ( sizeof ( des_generators ) /
|
||||
sizeof ( des_generators[0] ) ) ; i++ ) {
|
||||
des_generate ( &des_generators[i] );
|
||||
}
|
||||
}
|
||||
|
||||
/** Initialisation function */
|
||||
struct init_fn des_init_fn __init_fn ( INIT_NORMAL ) = {
|
||||
.initialise = des_init,
|
||||
};
|
||||
|
||||
/**
|
||||
* Perform bit permutation
|
||||
*
|
||||
* @v permutation Bit permutation (zero-terminated)
|
||||
* @v in Input value
|
||||
* @v out Output value
|
||||
*/
|
||||
static void des_permute ( const uint8_t *permutation, const uint8_t *in,
|
||||
uint8_t *out ) {
|
||||
uint8_t mask = 0x80;
|
||||
uint8_t accum = 0;
|
||||
unsigned int bit;
|
||||
|
||||
/* Extract individual input bits to construct output value */
|
||||
while ( ( bit = *(permutation++) ) ) {
|
||||
bit--;
|
||||
if ( in[ bit / 8 ] & ( 0x80 >> ( bit % 8 ) ) )
|
||||
accum |= mask;
|
||||
*out = accum;
|
||||
mask = ror8 ( mask, 1 );
|
||||
if ( mask == 0x80 ) {
|
||||
out++;
|
||||
accum = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform DES S-box substitution
|
||||
*
|
||||
* @v in 32-bit input value (native endian)
|
||||
* @v rkey 48-bit round key
|
||||
* @ret out 32-bit output value (native endian)
|
||||
*/
|
||||
static uint32_t des_sbox ( uint32_t in, const union des_round_key *rkey ) {
|
||||
uint32_t out = 0;
|
||||
uint32_t lookup;
|
||||
int32_t key;
|
||||
uint8_t sub;
|
||||
unsigned int i;
|
||||
|
||||
/* Perform input expansion, key addition, and S-box substitution */
|
||||
for ( i = 0 ; i < 8 ; i++ ) {
|
||||
|
||||
/* Rotate input and output */
|
||||
out = rol32 ( out, 4 );
|
||||
in = rol32 ( in, 4 );
|
||||
|
||||
/* Extract step key from relevant 6 bits of round key
|
||||
*
|
||||
* The least significant of the 6 bits (corresponding
|
||||
* to bit r0 in the S-box lookup index) is stored in
|
||||
* the sign bit of the step key byte. It will
|
||||
* therefore be propagated via sign extension to the
|
||||
* MSB of the 32-bit step key.
|
||||
*
|
||||
* The remaining 5 of the 6 bits (corresponding to
|
||||
* bits {r1,c3,c2,c1,c0} in the S-box lookup index)
|
||||
* are stored in the least significant 5 bits of the
|
||||
* step key byte and will end up in the least
|
||||
* significant 5 bits of the 32-bit step key.
|
||||
*/
|
||||
key = rkey->step[i];
|
||||
|
||||
/* Add step key to input to produce S-box lookup index
|
||||
*
|
||||
* We do not ever perform an explicit expansion of the
|
||||
* input value from 32 to 48 bits. Instead, we rotate
|
||||
* the 32-bit input value by 4 bits on each step, and
|
||||
* extract the relevant 6 bits.
|
||||
*
|
||||
* The least significant of the 6 bits (corresponding
|
||||
* to bit r0 in the S-box lookup index) is currently
|
||||
* in the MSB of the 32-bit (rotated) input value.
|
||||
*
|
||||
* The remaining 5 of the 6 bits (corresponding to
|
||||
* bits {r1,c3,c2,c1,c0} in the S-box lookup index)
|
||||
* are currently in the least significant 5 bits of
|
||||
* the 32-bit (rotated) input value.
|
||||
*
|
||||
* This aligns with the placement of the bits in the
|
||||
* step key (see above), and we can therefore perform
|
||||
* a single XOR to add the 6-bit step key to the
|
||||
* relevant 6 bits of the input value.
|
||||
*/
|
||||
lookup = ( in ^ key );
|
||||
|
||||
/* Look up S[i][in ^ key] from S-box
|
||||
*
|
||||
* We have bits {r1,c3,c2,c1,c0} in the least
|
||||
* significant 5 bits of the lookup index, and so can
|
||||
* use the masked lookup index directly as a byte
|
||||
* index into the relevant S-box to extract the byte
|
||||
* containing both {r1,c3,c2,c1,c0,'0'} and
|
||||
* {r1,c3,c2,c1,c0,'1'}.
|
||||
*
|
||||
* We then use the MSB of the 32-bit lookup index to
|
||||
* extract the relevant nibble for the full lookup
|
||||
* index {r1,c3,c2,c1,c0,r0}.
|
||||
*/
|
||||
sub = des_s[i][ lookup & 0x1f ];
|
||||
sub >>= ( ( lookup >> 29 ) & 4 );
|
||||
sub &= 0x0f;
|
||||
|
||||
/* Substitute S[i][input ^ key] into output */
|
||||
out |= sub;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a single DES round
|
||||
*
|
||||
* @v block DES block
|
||||
* @v rkey 48-bit round key
|
||||
*/
|
||||
static void des_round ( union des_block *block,
|
||||
const union des_round_key *rkey ) {
|
||||
union des_dword sbox;
|
||||
uint32_t left;
|
||||
uint32_t right;
|
||||
|
||||
/* Extract left and right halves L[n-1] and R[n-1] */
|
||||
left = block->left.dword;
|
||||
right = block->right.dword;
|
||||
DBGC2 ( block, "DES L=%08x R=%08x K=%08x%08x", be32_to_cpu ( left ),
|
||||
be32_to_cpu ( right ), be32_to_cpu ( rkey->dword[0] ),
|
||||
be32_to_cpu ( rkey->dword[1] ) );
|
||||
|
||||
/* L[n] = R[n-1] */
|
||||
block->left.dword = right;
|
||||
|
||||
/* Calculate Feistel function f(R[n-1], K[n]) */
|
||||
sbox.dword = cpu_to_be32 ( des_sbox ( be32_to_cpu ( right ), rkey ) );
|
||||
des_permute ( des_p, sbox.byte, block->right.byte );
|
||||
|
||||
/* R[n] = L[n-1] + f(R[n-1], K[n]) */
|
||||
block->right.dword ^= left;
|
||||
DBGC2 ( block, " => L=%08x R=%08x\n",
|
||||
be32_to_cpu ( block->left.dword ),
|
||||
be32_to_cpu ( block->right.dword ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform all DES rounds
|
||||
*
|
||||
* @v in Input DES block
|
||||
* @v out Output DES block
|
||||
* @v rkey Starting 48-bit round key
|
||||
* @v offset Byte offset between round keys
|
||||
*/
|
||||
static void des_rounds ( const union des_block *in, union des_block *out,
|
||||
const union des_round_key *rkey,
|
||||
ssize_t offset ) {
|
||||
union des_block tmp;
|
||||
unsigned int i;
|
||||
|
||||
/* Apply initial permutation */
|
||||
des_permute ( des_ip, in->byte, tmp.byte );
|
||||
|
||||
/* Perform all DES rounds, consuming keys in the specified order */
|
||||
for ( i = 0 ; i < DES_ROUNDS ; i++ ) {
|
||||
des_round ( &tmp, rkey );
|
||||
rkey = ( ( ( void * ) rkey ) + offset );
|
||||
}
|
||||
|
||||
/* Apply final permutation */
|
||||
DBGC ( &tmp, "DES %scrypted %08x%08x => ",
|
||||
( ( offset > 0 ) ? "en" : "de" ), be32_to_cpu ( in->dword[0] ),
|
||||
be32_to_cpu ( in->dword[1] ) );
|
||||
des_permute ( des_fp, tmp.byte, out->byte );
|
||||
DBGC ( &tmp, "%08x%08x\n", be32_to_cpu ( out->dword[0] ),
|
||||
be32_to_cpu ( out->dword[1] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate 28-bit word
|
||||
*
|
||||
* @v dword 28-bit dword value
|
||||
* @ret dword Rotated 28-bit dword value
|
||||
*/
|
||||
static uint32_t des_rol28 ( uint32_t dword ) {
|
||||
int32_t sdword;
|
||||
|
||||
/* Convert to native-endian */
|
||||
sdword = be32_to_cpu ( dword );
|
||||
|
||||
/* Signed shift right by 4 places to copy bit 31 to bits 27:31 */
|
||||
sdword >>= 4;
|
||||
|
||||
/* Rotate left */
|
||||
sdword = rol32 ( sdword, 1 );
|
||||
|
||||
/* Shift left by 4 places to restore bit positions */
|
||||
sdword <<= 4;
|
||||
|
||||
/* Convert back to big-endian */
|
||||
dword = cpu_to_be32 ( sdword );
|
||||
|
||||
return dword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set key
|
||||
*
|
||||
* @v ctx Context
|
||||
* @v key Key
|
||||
* @v keylen Key length
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int des_setkey ( void *ctx, const void *key, size_t keylen ) {
|
||||
struct des_context *des = ctx;
|
||||
union des_round_key *rkey = des->rkey;
|
||||
union des_block reg;
|
||||
uint32_t schedule;
|
||||
|
||||
/* Validate key length */
|
||||
if ( keylen != DES_BLOCKSIZE )
|
||||
return -EINVAL;
|
||||
DBGC ( des, "DES %p new key:\n", des );
|
||||
DBGC_HDA ( des, 0, key, keylen );
|
||||
|
||||
/* Apply permuted choice 1 */
|
||||
des_permute ( des_pc1c, key, reg.c.byte );
|
||||
des_permute ( des_pc1d, key, reg.d.byte );
|
||||
reg.d.byte[3] <<= 4; /* see comment for @c des_pc1d */
|
||||
DBGC2 ( des, "DES %p C[ 0]=%07x D[ 0]=%07x\n",
|
||||
des, ( be32_to_cpu ( reg.c.dword ) >> 4 ),
|
||||
( be32_to_cpu ( reg.d.dword ) >> 4 ) );
|
||||
|
||||
/* Generate round keys */
|
||||
for ( schedule = DES_SCHEDULE ; schedule ; schedule >>= 1 ) {
|
||||
|
||||
/* Shift 28-bit words */
|
||||
reg.c.dword = des_rol28 ( reg.c.dword );
|
||||
reg.d.dword = des_rol28 ( reg.d.dword );
|
||||
|
||||
/* Skip rounds according to shift schedule */
|
||||
if ( ! ( schedule & 1 ) )
|
||||
continue;
|
||||
|
||||
/* Apply permuted choice 2 */
|
||||
des_permute ( des_pc2, reg.byte, rkey->byte );
|
||||
DBGC2 ( des, "DES %p C[%2zd]=%07x D[%2zd]=%07x K[%2zd]="
|
||||
"%08x%08x\n", des, ( ( rkey - des->rkey ) + 1 ),
|
||||
( be32_to_cpu ( reg.c.dword ) >> 4 ),
|
||||
( ( rkey - des->rkey ) + 1 ),
|
||||
( be32_to_cpu ( reg.d.dword ) >> 4 ),
|
||||
( ( rkey - des->rkey ) + 1 ),
|
||||
be32_to_cpu ( rkey->dword[0] ),
|
||||
be32_to_cpu ( rkey->dword[1] ) );
|
||||
|
||||
/* Move to next key */
|
||||
rkey++;
|
||||
}
|
||||
|
||||
/* Sanity check */
|
||||
assert ( rkey == &des->rkey[DES_ROUNDS] );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt data
|
||||
*
|
||||
* @v ctx Context
|
||||
* @v src Data to encrypt
|
||||
* @v dst Buffer for encrypted data
|
||||
* @v len Length of data
|
||||
*/
|
||||
static void des_encrypt ( void *ctx, const void *src, void *dst, size_t len ) {
|
||||
struct des_context *des = ctx;
|
||||
|
||||
/* Sanity check */
|
||||
assert ( len == DES_BLOCKSIZE );
|
||||
|
||||
/* Cipher using keys in forward direction */
|
||||
des_rounds ( src, dst, &des->rkey[0], sizeof ( des->rkey[0] ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt data
|
||||
*
|
||||
* @v ctx Context
|
||||
* @v src Data to decrypt
|
||||
* @v dst Buffer for decrypted data
|
||||
* @v len Length of data
|
||||
*/
|
||||
static void des_decrypt ( void *ctx, const void *src, void *dst, size_t len ) {
|
||||
struct des_context *des = ctx;
|
||||
|
||||
/* Sanity check */
|
||||
assert ( len == DES_BLOCKSIZE );
|
||||
|
||||
/* Cipher using keys in reverse direction */
|
||||
des_rounds ( src, dst, &des->rkey[ DES_ROUNDS - 1 ],
|
||||
-sizeof ( des->rkey[0] ) );
|
||||
}
|
||||
|
||||
/** Basic DES algorithm */
|
||||
struct cipher_algorithm des_algorithm = {
|
||||
.name = "des",
|
||||
.ctxsize = sizeof ( struct des_context ),
|
||||
.blocksize = DES_BLOCKSIZE,
|
||||
.alignsize = 0,
|
||||
.authsize = 0,
|
||||
.setkey = des_setkey,
|
||||
.setiv = cipher_null_setiv,
|
||||
.encrypt = des_encrypt,
|
||||
.decrypt = des_decrypt,
|
||||
.auth = cipher_null_auth,
|
||||
};
|
||||
|
||||
/* DES in Electronic Codebook mode */
|
||||
ECB_CIPHER ( des_ecb, des_ecb_algorithm,
|
||||
des_algorithm, struct des_context, DES_BLOCKSIZE );
|
||||
|
||||
/* DES in Cipher Block Chaining mode */
|
||||
CBC_CIPHER ( des_cbc, des_cbc_algorithm,
|
||||
des_algorithm, struct des_context, DES_BLOCKSIZE );
|
||||
61
src/crypto/mishmash/dhe_rsa_aes_cbc_sha1.c
Normal file
61
src/crypto/mishmash/dhe_rsa_aes_cbc_sha1.c
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/aes.h>
|
||||
#include <ipxe/sha1.h>
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** TLS_DHE_RSA_WITH_AES_128_CBC_SHA cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_dhe_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 15 ) = {
|
||||
.code = htons ( TLS_DHE_RSA_WITH_AES_128_CBC_SHA ),
|
||||
.key_len = ( 128 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
.record_iv_len = AES_BLOCKSIZE,
|
||||
.mac_len = SHA1_DIGEST_SIZE,
|
||||
.exchange = &tls_dhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_cbc_algorithm,
|
||||
.digest = &sha1_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
|
||||
/** TLS_DHE_RSA_WITH_AES_256_CBC_SHA cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_dhe_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 16 ) = {
|
||||
.code = htons ( TLS_DHE_RSA_WITH_AES_256_CBC_SHA ),
|
||||
.key_len = ( 256 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
.record_iv_len = AES_BLOCKSIZE,
|
||||
.mac_len = SHA1_DIGEST_SIZE,
|
||||
.exchange = &tls_dhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_cbc_algorithm,
|
||||
.digest = &sha1_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
60
src/crypto/mishmash/dhe_rsa_aes_cbc_sha256.c
Normal file
60
src/crypto/mishmash/dhe_rsa_aes_cbc_sha256.c
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/aes.h>
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_dhe_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 13 ) = {
|
||||
.code = htons ( TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ),
|
||||
.key_len = ( 128 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
.record_iv_len = AES_BLOCKSIZE,
|
||||
.mac_len = SHA256_DIGEST_SIZE,
|
||||
.exchange = &tls_dhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_cbc_algorithm,
|
||||
.digest = &sha256_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
|
||||
/** TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_dhe_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 14 ) = {
|
||||
.code = htons ( TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 ),
|
||||
.key_len = ( 256 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
.record_iv_len = AES_BLOCKSIZE,
|
||||
.mac_len = SHA256_DIGEST_SIZE,
|
||||
.exchange = &tls_dhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_cbc_algorithm,
|
||||
.digest = &sha256_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
45
src/crypto/mishmash/dhe_rsa_aes_gcm_sha256.c
Normal file
45
src/crypto/mishmash/dhe_rsa_aes_gcm_sha256.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/aes.h>
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_dhe_rsa_with_aes_128_gcm_sha256 __tls_cipher_suite ( 11 ) = {
|
||||
.code = htons ( TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ),
|
||||
.key_len = ( 128 / 8 ),
|
||||
.fixed_iv_len = 4,
|
||||
.record_iv_len = 8,
|
||||
.mac_len = 0,
|
||||
.exchange = &tls_dhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_gcm_algorithm,
|
||||
.digest = &sha256_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
45
src/crypto/mishmash/dhe_rsa_aes_gcm_sha384.c
Normal file
45
src/crypto/mishmash/dhe_rsa_aes_gcm_sha384.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/aes.h>
|
||||
#include <ipxe/sha512.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_dhe_rsa_with_aes_256_gcm_sha384 __tls_cipher_suite ( 12 ) = {
|
||||
.code = htons ( TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 ),
|
||||
.key_len = ( 256 / 8 ),
|
||||
.fixed_iv_len = 4,
|
||||
.record_iv_len = 8,
|
||||
.mac_len = 0,
|
||||
.exchange = &tls_dhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_gcm_algorithm,
|
||||
.digest = &sha384_algorithm,
|
||||
.handshake = &sha384_algorithm,
|
||||
};
|
||||
61
src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha1.c
Normal file
61
src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha1.c
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/aes.h>
|
||||
#include <ipxe/sha1.h>
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_ecdhe_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 05 ) = {
|
||||
.code = htons ( TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA ),
|
||||
.key_len = ( 128 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
.record_iv_len = AES_BLOCKSIZE,
|
||||
.mac_len = SHA1_DIGEST_SIZE,
|
||||
.exchange = &tls_ecdhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_cbc_algorithm,
|
||||
.digest = &sha1_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
|
||||
/** TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_ecdhe_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 06 ) = {
|
||||
.code = htons ( TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA ),
|
||||
.key_len = ( 256 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
.record_iv_len = AES_BLOCKSIZE,
|
||||
.mac_len = SHA1_DIGEST_SIZE,
|
||||
.exchange = &tls_ecdhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_cbc_algorithm,
|
||||
.digest = &sha1_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
45
src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha256.c
Normal file
45
src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha256.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/aes.h>
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_ecdhe_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 03 ) = {
|
||||
.code = htons ( TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 ),
|
||||
.key_len = ( 128 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
.record_iv_len = AES_BLOCKSIZE,
|
||||
.mac_len = SHA256_DIGEST_SIZE,
|
||||
.exchange = &tls_ecdhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_cbc_algorithm,
|
||||
.digest = &sha256_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
45
src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha384.c
Normal file
45
src/crypto/mishmash/ecdhe_rsa_aes_cbc_sha384.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/aes.h>
|
||||
#include <ipxe/sha512.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_ecdhe_rsa_with_aes_256_cbc_sha384 __tls_cipher_suite ( 04 ) = {
|
||||
.code = htons ( TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 ),
|
||||
.key_len = ( 256 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
.record_iv_len = AES_BLOCKSIZE,
|
||||
.mac_len = SHA384_DIGEST_SIZE,
|
||||
.exchange = &tls_ecdhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_cbc_algorithm,
|
||||
.digest = &sha384_algorithm,
|
||||
.handshake = &sha384_algorithm,
|
||||
};
|
||||
45
src/crypto/mishmash/ecdhe_rsa_aes_gcm_sha256.c
Normal file
45
src/crypto/mishmash/ecdhe_rsa_aes_gcm_sha256.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/aes.h>
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_ecdhe_rsa_with_aes_128_gcm_sha256 __tls_cipher_suite ( 01 ) = {
|
||||
.code = htons ( TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 ),
|
||||
.key_len = ( 128 / 8 ),
|
||||
.fixed_iv_len = 4,
|
||||
.record_iv_len = 8,
|
||||
.mac_len = 0,
|
||||
.exchange = &tls_ecdhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_gcm_algorithm,
|
||||
.digest = &sha256_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
45
src/crypto/mishmash/ecdhe_rsa_aes_gcm_sha384.c
Normal file
45
src/crypto/mishmash/ecdhe_rsa_aes_gcm_sha384.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/rsa.h>
|
||||
#include <ipxe/aes.h>
|
||||
#include <ipxe/sha512.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_ecdhe_rsa_with_aes_256_gcm_sha384 __tls_cipher_suite ( 02 ) = {
|
||||
.code = htons ( TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 ),
|
||||
.key_len = ( 256 / 8 ),
|
||||
.fixed_iv_len = 4,
|
||||
.record_iv_len = 8,
|
||||
.mac_len = 0,
|
||||
.exchange = &tls_ecdhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_gcm_algorithm,
|
||||
.digest = &sha384_algorithm,
|
||||
.handshake = &sha384_algorithm,
|
||||
};
|
||||
45
src/crypto/mishmash/oid_x25519.c
Normal file
45
src/crypto/mishmash/oid_x25519.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/x25519.h>
|
||||
#include <ipxe/asn1.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** "x25519" object identifier */
|
||||
static uint8_t oid_x25519[] = { ASN1_OID_X25519 };
|
||||
|
||||
/** "x25519" OID-identified algorithm */
|
||||
struct asn1_algorithm x25519_algorithm __asn1_algorithm = {
|
||||
.name = "x25519",
|
||||
.curve = &x25519_curve,
|
||||
.oid = ASN1_CURSOR ( oid_x25519 ),
|
||||
};
|
||||
|
||||
/** X25519 named curve */
|
||||
struct tls_named_curve tls_x25519_named_curve __tls_named_curve ( 01 ) = {
|
||||
.curve = &x25519_curve,
|
||||
.code = htons ( TLS_NAMED_CURVE_X25519 ),
|
||||
};
|
||||
@ -30,39 +30,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** TLS_DHE_RSA_WITH_AES_128_CBC_SHA cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_dhe_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 05 ) = {
|
||||
.code = htons ( TLS_DHE_RSA_WITH_AES_128_CBC_SHA ),
|
||||
.key_len = ( 128 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
.record_iv_len = AES_BLOCKSIZE,
|
||||
.mac_len = SHA1_DIGEST_SIZE,
|
||||
.exchange = &tls_dhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_cbc_algorithm,
|
||||
.digest = &sha1_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
|
||||
/** TLS_DHE_RSA_WITH_AES_256_CBC_SHA cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_dhe_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 06 ) = {
|
||||
.code = htons ( TLS_DHE_RSA_WITH_AES_256_CBC_SHA ),
|
||||
.key_len = ( 256 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
.record_iv_len = AES_BLOCKSIZE,
|
||||
.mac_len = SHA1_DIGEST_SIZE,
|
||||
.exchange = &tls_dhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_cbc_algorithm,
|
||||
.digest = &sha1_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
|
||||
/** TLS_RSA_WITH_AES_128_CBC_SHA cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 15 ) = {
|
||||
tls_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 25 ) = {
|
||||
.code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA ),
|
||||
.key_len = ( 128 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
@ -77,7 +47,7 @@ tls_rsa_with_aes_128_cbc_sha __tls_cipher_suite ( 15 ) = {
|
||||
|
||||
/** TLS_RSA_WITH_AES_256_CBC_SHA cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 16 ) = {
|
||||
tls_rsa_with_aes_256_cbc_sha __tls_cipher_suite ( 26 ) = {
|
||||
.code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA ),
|
||||
.key_len = ( 256 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
|
||||
@ -29,39 +29,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_dhe_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 03 ) = {
|
||||
.code = htons ( TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 ),
|
||||
.key_len = ( 128 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
.record_iv_len = AES_BLOCKSIZE,
|
||||
.mac_len = SHA256_DIGEST_SIZE,
|
||||
.exchange = &tls_dhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_cbc_algorithm,
|
||||
.digest = &sha256_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
|
||||
/** TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_dhe_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 04 ) = {
|
||||
.code = htons ( TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 ),
|
||||
.key_len = ( 256 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
.record_iv_len = AES_BLOCKSIZE,
|
||||
.mac_len = SHA256_DIGEST_SIZE,
|
||||
.exchange = &tls_dhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_cbc_algorithm,
|
||||
.digest = &sha256_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
|
||||
/** TLS_RSA_WITH_AES_128_CBC_SHA256 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 13 ) = {
|
||||
tls_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 23 ) = {
|
||||
.code = htons ( TLS_RSA_WITH_AES_128_CBC_SHA256 ),
|
||||
.key_len = ( 128 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
@ -76,7 +46,7 @@ tls_rsa_with_aes_128_cbc_sha256 __tls_cipher_suite ( 13 ) = {
|
||||
|
||||
/** TLS_RSA_WITH_AES_256_CBC_SHA256 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 14 ) = {
|
||||
tls_rsa_with_aes_256_cbc_sha256 __tls_cipher_suite ( 24 ) = {
|
||||
.code = htons ( TLS_RSA_WITH_AES_256_CBC_SHA256 ),
|
||||
.key_len = ( 256 / 8 ),
|
||||
.fixed_iv_len = 0,
|
||||
|
||||
@ -29,24 +29,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <ipxe/sha256.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_dhe_rsa_with_aes_128_gcm_sha256 __tls_cipher_suite ( 01 ) = {
|
||||
.code = htons ( TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 ),
|
||||
.key_len = ( 128 / 8 ),
|
||||
.fixed_iv_len = 4,
|
||||
.record_iv_len = 8,
|
||||
.mac_len = 0,
|
||||
.exchange = &tls_dhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_gcm_algorithm,
|
||||
.digest = &sha256_algorithm,
|
||||
.handshake = &sha256_algorithm,
|
||||
};
|
||||
|
||||
/** TLS_RSA_WITH_AES_128_GCM_SHA256 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_rsa_with_aes_128_gcm_sha256 __tls_cipher_suite ( 11 ) = {
|
||||
tls_rsa_with_aes_128_gcm_sha256 __tls_cipher_suite ( 21 ) = {
|
||||
.code = htons ( TLS_RSA_WITH_AES_128_GCM_SHA256 ),
|
||||
.key_len = ( 128 / 8 ),
|
||||
.fixed_iv_len = 4,
|
||||
|
||||
@ -29,24 +29,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <ipxe/sha512.h>
|
||||
#include <ipxe/tls.h>
|
||||
|
||||
/** TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_dhe_rsa_with_aes_256_gcm_sha384 __tls_cipher_suite ( 02 ) = {
|
||||
.code = htons ( TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 ),
|
||||
.key_len = ( 256 / 8 ),
|
||||
.fixed_iv_len = 4,
|
||||
.record_iv_len = 8,
|
||||
.mac_len = 0,
|
||||
.exchange = &tls_dhe_exchange_algorithm,
|
||||
.pubkey = &rsa_algorithm,
|
||||
.cipher = &aes_gcm_algorithm,
|
||||
.digest = &sha384_algorithm,
|
||||
.handshake = &sha384_algorithm,
|
||||
};
|
||||
|
||||
/** TLS_RSA_WITH_AES_256_GCM_SHA384 cipher suite */
|
||||
struct tls_cipher_suite
|
||||
tls_rsa_with_aes_256_gcm_sha384 __tls_cipher_suite ( 12 ) = {
|
||||
tls_rsa_with_aes_256_gcm_sha384 __tls_cipher_suite ( 22 ) = {
|
||||
.code = htons ( TLS_RSA_WITH_AES_256_GCM_SHA384 ),
|
||||
.key_len = ( 256 / 8 ),
|
||||
.fixed_iv_len = 4,
|
||||
|
||||
@ -59,7 +59,9 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <ipxe/init.h>
|
||||
#include <ipxe/crypto.h>
|
||||
#include <ipxe/x25519.h>
|
||||
|
||||
/** X25519 reduction constant
|
||||
@ -299,6 +301,11 @@ static const uint8_t x25519_121665_raw[] = { 0x01, 0xdb, 0x41 };
|
||||
/** Constant 121665 (used in the Montgomery ladder) */
|
||||
static union x25519_oct258 x25519_121665;
|
||||
|
||||
/** Constant g=9 (the group generator) */
|
||||
static struct x25519_value x25519_generator = {
|
||||
.raw = { 9, }
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialise constants
|
||||
*
|
||||
@ -781,10 +788,11 @@ static void x25519_reverse ( struct x25519_value *value ) {
|
||||
* @v base Base point
|
||||
* @v scalar Scalar multiple
|
||||
* @v result Point to hold result (may overlap base point)
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
void x25519_key ( const struct x25519_value *base,
|
||||
const struct x25519_value *scalar,
|
||||
struct x25519_value *result ) {
|
||||
int x25519_key ( const struct x25519_value *base,
|
||||
const struct x25519_value *scalar,
|
||||
struct x25519_value *result ) {
|
||||
struct x25519_value *tmp = result;
|
||||
union x25519_quad257 point;
|
||||
|
||||
@ -805,4 +813,32 @@ void x25519_key ( const struct x25519_value *base,
|
||||
/* Reverse result */
|
||||
bigint_done ( &point.value, result->raw, sizeof ( result->raw ) );
|
||||
x25519_reverse ( result );
|
||||
|
||||
/* Fail if result was all zeros (as required by RFC8422) */
|
||||
return ( bigint_is_zero ( &point.value ) ? -EPERM : 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply scalar by curve point
|
||||
*
|
||||
* @v base Base point (or NULL to use generator)
|
||||
* @v scalar Scalar multiple
|
||||
* @v result Result point to fill in
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int x25519_curve_multiply ( const void *base, const void *scalar,
|
||||
void *result ) {
|
||||
|
||||
/* Use base point if applicable */
|
||||
if ( ! base )
|
||||
base = &x25519_generator;
|
||||
|
||||
return x25519_key ( base, scalar, result );
|
||||
}
|
||||
|
||||
/** X25519 elliptic curve */
|
||||
struct elliptic_curve x25519_curve = {
|
||||
.name = "x25519",
|
||||
.keysize = sizeof ( struct x25519_value ),
|
||||
.multiply = x25519_curve_multiply,
|
||||
};
|
||||
|
||||
@ -722,7 +722,9 @@ static int bnxt_hwrm_ver_get ( struct bnxt *bp )
|
||||
( resp->dev_caps_cfg & SHORT_CMD_REQUIRED ) )
|
||||
FLAG_SET ( bp->flags, BNXT_FLAG_HWRM_SHORT_CMD_SUPP );
|
||||
bp->hwrm_max_ext_req_len = resp->max_ext_req_len;
|
||||
if ( bp->chip_num == CHIP_NUM_57500 )
|
||||
if ( ( bp->chip_num == CHIP_NUM_57508 ) ||
|
||||
( bp->chip_num == CHIP_NUM_57504 ) ||
|
||||
( bp->chip_num == CHIP_NUM_57502 ) )
|
||||
bp->thor = 1;
|
||||
dbg_fw_ver ( resp, bp->hwrm_cmd_timeout );
|
||||
return STATUS_SUCCESS;
|
||||
|
||||
@ -868,4 +868,6 @@ struct bnxt {
|
||||
FUNC_VF_CFG_REQ_ENABLES_ASYNC_EVENT_CR | \
|
||||
FUNC_VF_CFG_REQ_ENABLES_DFLT_MAC_ADDR)
|
||||
|
||||
#define CHIP_NUM_57500 0x1750
|
||||
#define CHIP_NUM_57508 0x1750
|
||||
#define CHIP_NUM_57504 0x1751
|
||||
#define CHIP_NUM_57502 0x1752
|
||||
|
||||
@ -187,6 +187,11 @@ struct asn1_builder_header {
|
||||
ASN1_OID_SINGLE ( 3 ), ASN1_OID_SINGLE ( 2 ), \
|
||||
ASN1_OID_SINGLE ( 26 )
|
||||
|
||||
/** ASN.1 OID for id-x25519 (1.3.101.110) */
|
||||
#define ASN1_OID_X25519 \
|
||||
ASN1_OID_INITIAL ( 1, 3 ), ASN1_OID_SINGLE ( 101 ), \
|
||||
ASN1_OID_SINGLE ( 110 )
|
||||
|
||||
/** ASN.1 OID for id-sha256 (2.16.840.1.101.3.4.2.1) */
|
||||
#define ASN1_OID_SHA256 \
|
||||
ASN1_OID_INITIAL ( 2, 16 ), ASN1_OID_DOUBLE ( 840 ), \
|
||||
@ -312,6 +317,8 @@ struct asn1_algorithm {
|
||||
struct pubkey_algorithm *pubkey;
|
||||
/** Digest algorithm (if applicable) */
|
||||
struct digest_algorithm *digest;
|
||||
/** Elliptic curve (if applicable) */
|
||||
struct elliptic_curve *curve;
|
||||
};
|
||||
|
||||
/** ASN.1 OID-identified algorithms */
|
||||
|
||||
@ -77,19 +77,19 @@ static void _cbc_name ## _setiv ( void *ctx, const void *iv, \
|
||||
size_t ivlen ) { \
|
||||
struct _cbc_name ## _context * _cbc_name ## _ctx = ctx; \
|
||||
cbc_setiv ( &_cbc_name ## _ctx->raw_ctx, iv, ivlen, \
|
||||
&_raw_cipher, &aes_cbc_ctx->cbc_ctx ); \
|
||||
&_raw_cipher, &_cbc_name ## _ctx->cbc_ctx ); \
|
||||
} \
|
||||
static void _cbc_name ## _encrypt ( void *ctx, const void *src, \
|
||||
void *dst, size_t len ) { \
|
||||
struct _cbc_name ## _context * _cbc_name ## _ctx = ctx; \
|
||||
cbc_encrypt ( &_cbc_name ## _ctx->raw_ctx, src, dst, len, \
|
||||
&_raw_cipher, &aes_cbc_ctx->cbc_ctx ); \
|
||||
&_raw_cipher, &_cbc_name ## _ctx->cbc_ctx ); \
|
||||
} \
|
||||
static void _cbc_name ## _decrypt ( void *ctx, const void *src, \
|
||||
void *dst, size_t len ) { \
|
||||
struct _cbc_name ## _context * _cbc_name ## _ctx = ctx; \
|
||||
cbc_decrypt ( &_cbc_name ## _ctx->raw_ctx, src, dst, len, \
|
||||
&_raw_cipher, &aes_cbc_ctx->cbc_ctx ); \
|
||||
&_raw_cipher, &_cbc_name ## _ctx->cbc_ctx ); \
|
||||
} \
|
||||
struct cipher_algorithm _cbc_cipher = { \
|
||||
.name = #_cbc_name, \
|
||||
|
||||
@ -195,6 +195,23 @@ struct pubkey_algorithm {
|
||||
const void *public_key, size_t public_key_len );
|
||||
};
|
||||
|
||||
/** An elliptic curve */
|
||||
struct elliptic_curve {
|
||||
/** Curve name */
|
||||
const char *name;
|
||||
/** Key size */
|
||||
size_t keysize;
|
||||
/** Multiply scalar by curve point
|
||||
*
|
||||
* @v base Base point (or NULL to use generator)
|
||||
* @v scalar Scalar multiple
|
||||
* @v result Result point to fill in
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
int ( * multiply ) ( const void *base, const void *scalar,
|
||||
void *result );
|
||||
};
|
||||
|
||||
static inline void digest_init ( struct digest_algorithm *digest,
|
||||
void *ctx ) {
|
||||
digest->init ( ctx );
|
||||
@ -302,6 +319,12 @@ static inline int pubkey_match ( struct pubkey_algorithm *pubkey,
|
||||
public_key_len );
|
||||
}
|
||||
|
||||
static inline int elliptic_multiply ( struct elliptic_curve *curve,
|
||||
const void *base, const void *scalar,
|
||||
void *result ) {
|
||||
return curve->multiply ( base, scalar, result );
|
||||
}
|
||||
|
||||
extern void digest_null_init ( void *ctx );
|
||||
extern void digest_null_update ( void *ctx, const void *src, size_t len );
|
||||
extern void digest_null_final ( void *ctx, void *out );
|
||||
|
||||
91
src/include/ipxe/des.h
Normal file
91
src/include/ipxe/des.h
Normal file
@ -0,0 +1,91 @@
|
||||
#ifndef _IPXE_DES_H
|
||||
#define _IPXE_DES_H
|
||||
|
||||
/** @file
|
||||
*
|
||||
* DES algorithm
|
||||
*
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <ipxe/crypto.h>
|
||||
|
||||
/** A DES 32-bit dword value
|
||||
*
|
||||
* DES views data as 64-bit big-endian values, typically handled as a
|
||||
* most-significant "left" half and a least-significant "right" half.
|
||||
*/
|
||||
union des_dword {
|
||||
/** Raw bytes */
|
||||
uint8_t byte[4];
|
||||
/** 32-bit big-endian dword */
|
||||
uint32_t dword;
|
||||
};
|
||||
|
||||
/** A DES 64-bit block */
|
||||
union des_block {
|
||||
/** Raw bytes */
|
||||
uint8_t byte[8];
|
||||
/** 32-bit big-endian dwords */
|
||||
uint32_t dword[2];
|
||||
/** Named left and right halves */
|
||||
struct {
|
||||
/** Left (most significant) half */
|
||||
union des_dword left;
|
||||
/** Right (least significant) half */
|
||||
union des_dword right;
|
||||
};
|
||||
/** Named "C" and "D" halves */
|
||||
struct {
|
||||
/** "C" (most significant) half */
|
||||
union des_dword c;
|
||||
/** "D" (least significant) half */
|
||||
union des_dword d;
|
||||
};
|
||||
};
|
||||
|
||||
/** DES blocksize */
|
||||
#define DES_BLOCKSIZE sizeof ( union des_block )
|
||||
|
||||
/** A DES round key
|
||||
*
|
||||
* A DES round key is a 48-bit value, consumed as 8 groups of 6 bits.
|
||||
* We store these as 8 separate bytes, for simplicity of consumption.
|
||||
*/
|
||||
union des_round_key {
|
||||
/** Raw bytes */
|
||||
uint8_t byte[8];
|
||||
/** 32-bit big-endian dwords */
|
||||
uint32_t dword[2];
|
||||
/** 6-bit step key byte
|
||||
*
|
||||
* There are 8 steps within a DES round (one step per S-box).
|
||||
* Each step requires six bits of the round key.
|
||||
*
|
||||
* As an optimisation, we store the least significant of the 6
|
||||
* bits in the sign bit of a signed 8-bit value, and the
|
||||
* remaining 5 bits in the least significant 5 bits of the
|
||||
* 8-bit value. See the comments in des_sbox() for further
|
||||
* details.
|
||||
*/
|
||||
int8_t step[8];
|
||||
};
|
||||
|
||||
/** Number of DES rounds */
|
||||
#define DES_ROUNDS 16
|
||||
|
||||
/** DES context */
|
||||
struct des_context {
|
||||
/** Round keys */
|
||||
union des_round_key rkey[DES_ROUNDS];
|
||||
};
|
||||
|
||||
/** DES context size */
|
||||
#define DES_CTX_SIZE sizeof ( struct des_context )
|
||||
|
||||
extern struct cipher_algorithm des_algorithm;
|
||||
extern struct cipher_algorithm des_ecb_algorithm;
|
||||
extern struct cipher_algorithm des_cbc_algorithm;
|
||||
|
||||
#endif /* _IPXE_DES_H */
|
||||
@ -407,6 +407,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
#define ERRFILE_efi_rng ( ERRFILE_OTHER | 0x005c0000 )
|
||||
#define ERRFILE_efi_shim ( ERRFILE_OTHER | 0x005d0000 )
|
||||
#define ERRFILE_efi_settings ( ERRFILE_OTHER | 0x005e0000 )
|
||||
#define ERRFILE_x25519 ( ERRFILE_OTHER | 0x005f0000 )
|
||||
#define ERRFILE_des ( ERRFILE_OTHER | 0x00600000 )
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
@ -96,6 +96,12 @@ struct tls_header {
|
||||
#define TLS_RSA_WITH_AES_256_GCM_SHA384 0x009d
|
||||
#define TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 0x009e
|
||||
#define TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 0x009f
|
||||
#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA 0xc013
|
||||
#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 0xc014
|
||||
#define TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 0xc027
|
||||
#define TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 0xc028
|
||||
#define TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0xc02f
|
||||
#define TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0xc030
|
||||
|
||||
/* TLS hash algorithm identifiers */
|
||||
#define TLS_MD5_ALGORITHM 1
|
||||
@ -119,6 +125,10 @@ struct tls_header {
|
||||
#define TLS_MAX_FRAGMENT_LENGTH_2048 3
|
||||
#define TLS_MAX_FRAGMENT_LENGTH_4096 4
|
||||
|
||||
/* TLS named curve extension */
|
||||
#define TLS_NAMED_CURVE 10
|
||||
#define TLS_NAMED_CURVE_X25519 29
|
||||
|
||||
/* TLS signature algorithms extension */
|
||||
#define TLS_SIGNATURE_ALGORITHMS 13
|
||||
|
||||
@ -205,6 +215,25 @@ struct tls_cipher_suite {
|
||||
#define __tls_cipher_suite( pref ) \
|
||||
__table_entry ( TLS_CIPHER_SUITES, pref )
|
||||
|
||||
/** TLS named curved type */
|
||||
#define TLS_NAMED_CURVE_TYPE 3
|
||||
|
||||
/** A TLS named curve */
|
||||
struct tls_named_curve {
|
||||
/** Elliptic curve */
|
||||
struct elliptic_curve *curve;
|
||||
/** Numeric code (in network-endian order) */
|
||||
uint16_t code;
|
||||
};
|
||||
|
||||
/** TLS named curve table */
|
||||
#define TLS_NAMED_CURVES \
|
||||
__table ( struct tls_named_curve, "tls_named_curves" )
|
||||
|
||||
/** Declare a TLS named curve */
|
||||
#define __tls_named_curve( pref ) \
|
||||
__table_entry ( TLS_NAMED_CURVES, pref )
|
||||
|
||||
/** A TLS cipher specification */
|
||||
struct tls_cipherspec {
|
||||
/** Cipher suite */
|
||||
@ -425,6 +454,7 @@ struct tls_connection {
|
||||
|
||||
extern struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm;
|
||||
extern struct tls_key_exchange_algorithm tls_dhe_exchange_algorithm;
|
||||
extern struct tls_key_exchange_algorithm tls_ecdhe_exchange_algorithm;
|
||||
|
||||
extern int add_tls ( struct interface *xfer, const char *name,
|
||||
struct x509_root *root, struct private_key *key );
|
||||
|
||||
@ -11,6 +11,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
#include <stdint.h>
|
||||
#include <ipxe/bigint.h>
|
||||
#include <ipxe/crypto.h>
|
||||
|
||||
/** X25519 unsigned big integer size
|
||||
*
|
||||
@ -84,8 +85,10 @@ extern void x25519_multiply ( const union x25519_oct258 *multiplicand,
|
||||
extern void x25519_invert ( const union x25519_oct258 *invertend,
|
||||
union x25519_quad257 *result );
|
||||
extern void x25519_reduce ( union x25519_quad257 *value );
|
||||
extern void x25519_key ( const struct x25519_value *base,
|
||||
const struct x25519_value *scalar,
|
||||
struct x25519_value *result );
|
||||
extern int x25519_key ( const struct x25519_value *base,
|
||||
const struct x25519_value *scalar,
|
||||
struct x25519_value *result );
|
||||
|
||||
extern struct elliptic_curve x25519_curve;
|
||||
|
||||
#endif /* _IPXE_X25519_H */
|
||||
|
||||
562
src/net/tls.c
562
src/net/tls.c
@ -158,6 +158,10 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||
#define EINFO_ENOTSUP_VERSION \
|
||||
__einfo_uniqify ( EINFO_ENOTSUP, 0x04, \
|
||||
"Unsupported protocol version" )
|
||||
#define ENOTSUP_CURVE __einfo_error ( EINFO_ENOTSUP_CURVE )
|
||||
#define EINFO_ENOTSUP_CURVE \
|
||||
__einfo_uniqify ( EINFO_ENOTSUP, 0x05, \
|
||||
"Unsupported elliptic curve" )
|
||||
#define EPERM_ALERT __einfo_error ( EINFO_EPERM_ALERT )
|
||||
#define EINFO_EPERM_ALERT \
|
||||
__einfo_uniqify ( EINFO_EPERM, 0x01, \
|
||||
@ -1042,6 +1046,35 @@ tls_signature_hash_digest ( struct tls_signature_hash_id code ) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Ephemeral Elliptic Curve Diffie-Hellman key exchange
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/** Number of supported named curves */
|
||||
#define TLS_NUM_NAMED_CURVES table_num_entries ( TLS_NAMED_CURVES )
|
||||
|
||||
/**
|
||||
* Identify named curve
|
||||
*
|
||||
* @v named_curve Named curve specification
|
||||
* @ret curve Named curve, or NULL
|
||||
*/
|
||||
static struct tls_named_curve *
|
||||
tls_find_named_curve ( unsigned int named_curve ) {
|
||||
struct tls_named_curve *curve;
|
||||
|
||||
/* Identify named curve */
|
||||
for_each_table_entry ( curve, TLS_NAMED_CURVES ) {
|
||||
if ( curve->code == named_curve )
|
||||
return curve;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
*
|
||||
* Record handling
|
||||
@ -1121,6 +1154,67 @@ static int tls_client_hello ( struct tls_connection *tls,
|
||||
size_t len ) ) {
|
||||
struct tls_session *session = tls->session;
|
||||
size_t name_len = strlen ( session->name );
|
||||
struct {
|
||||
uint16_t type;
|
||||
uint16_t len;
|
||||
struct {
|
||||
uint16_t len;
|
||||
struct {
|
||||
uint8_t type;
|
||||
uint16_t len;
|
||||
uint8_t name[name_len];
|
||||
} __attribute__ (( packed )) list[1];
|
||||
} __attribute__ (( packed )) data;
|
||||
} __attribute__ (( packed )) *server_name_ext;
|
||||
struct {
|
||||
uint16_t type;
|
||||
uint16_t len;
|
||||
struct {
|
||||
uint8_t max;
|
||||
} __attribute__ (( packed )) data;
|
||||
} __attribute__ (( packed )) *max_fragment_length_ext;
|
||||
struct {
|
||||
uint16_t type;
|
||||
uint16_t len;
|
||||
struct {
|
||||
uint16_t len;
|
||||
struct tls_signature_hash_id
|
||||
code[TLS_NUM_SIG_HASH_ALGORITHMS];
|
||||
} __attribute__ (( packed )) data;
|
||||
} __attribute__ (( packed )) *signature_algorithms_ext;
|
||||
struct {
|
||||
uint16_t type;
|
||||
uint16_t len;
|
||||
struct {
|
||||
uint8_t len;
|
||||
uint8_t data[ tls->secure_renegotiation ?
|
||||
sizeof ( tls->verify.client ) :0 ];
|
||||
} __attribute__ (( packed )) data;
|
||||
} __attribute__ (( packed )) *renegotiation_info_ext;
|
||||
struct {
|
||||
uint16_t type;
|
||||
uint16_t len;
|
||||
struct {
|
||||
uint8_t data[session->ticket_len];
|
||||
} __attribute__ (( packed )) data;
|
||||
} __attribute__ (( packed )) *session_ticket_ext;
|
||||
struct {
|
||||
uint16_t type;
|
||||
uint16_t len;
|
||||
struct {
|
||||
uint16_t len;
|
||||
uint16_t code[TLS_NUM_NAMED_CURVES];
|
||||
} __attribute__ (( packed )) data;
|
||||
} __attribute__ (( packed )) *named_curve_ext;
|
||||
struct {
|
||||
typeof ( *server_name_ext ) server_name;
|
||||
typeof ( *max_fragment_length_ext ) max_fragment_length;
|
||||
typeof ( *signature_algorithms_ext ) signature_algorithms;
|
||||
typeof ( *renegotiation_info_ext ) renegotiation_info;
|
||||
typeof ( *session_ticket_ext ) session_ticket;
|
||||
typeof ( *named_curve_ext )
|
||||
named_curve[TLS_NUM_NAMED_CURVES ? 1 : 0];
|
||||
} __attribute__ (( packed )) *extensions;
|
||||
struct {
|
||||
uint32_t type_length;
|
||||
uint16_t version;
|
||||
@ -1132,45 +1226,11 @@ static int tls_client_hello ( struct tls_connection *tls,
|
||||
uint8_t compression_methods_len;
|
||||
uint8_t compression_methods[1];
|
||||
uint16_t extensions_len;
|
||||
struct {
|
||||
uint16_t server_name_type;
|
||||
uint16_t server_name_len;
|
||||
struct {
|
||||
uint16_t len;
|
||||
struct {
|
||||
uint8_t type;
|
||||
uint16_t len;
|
||||
uint8_t name[name_len];
|
||||
} __attribute__ (( packed )) list[1];
|
||||
} __attribute__ (( packed )) server_name;
|
||||
uint16_t max_fragment_length_type;
|
||||
uint16_t max_fragment_length_len;
|
||||
struct {
|
||||
uint8_t max;
|
||||
} __attribute__ (( packed )) max_fragment_length;
|
||||
uint16_t signature_algorithms_type;
|
||||
uint16_t signature_algorithms_len;
|
||||
struct {
|
||||
uint16_t len;
|
||||
struct tls_signature_hash_id
|
||||
code[TLS_NUM_SIG_HASH_ALGORITHMS];
|
||||
} __attribute__ (( packed )) signature_algorithms;
|
||||
uint16_t renegotiation_info_type;
|
||||
uint16_t renegotiation_info_len;
|
||||
struct {
|
||||
uint8_t len;
|
||||
uint8_t data[ tls->secure_renegotiation ?
|
||||
sizeof ( tls->verify.client ) :0];
|
||||
} __attribute__ (( packed )) renegotiation_info;
|
||||
uint16_t session_ticket_type;
|
||||
uint16_t session_ticket_len;
|
||||
struct {
|
||||
uint8_t data[session->ticket_len];
|
||||
} __attribute__ (( packed )) session_ticket;
|
||||
} __attribute__ (( packed )) extensions;
|
||||
typeof ( *extensions ) extensions;
|
||||
} __attribute__ (( packed )) hello;
|
||||
struct tls_cipher_suite *suite;
|
||||
struct tls_signature_hash_algorithm *sighash;
|
||||
struct tls_named_curve *curve;
|
||||
unsigned int i;
|
||||
|
||||
/* Construct record */
|
||||
@ -1188,43 +1248,66 @@ static int tls_client_hello ( struct tls_connection *tls,
|
||||
hello.cipher_suites[i++] = suite->code;
|
||||
hello.compression_methods_len = sizeof ( hello.compression_methods );
|
||||
hello.extensions_len = htons ( sizeof ( hello.extensions ) );
|
||||
hello.extensions.server_name_type = htons ( TLS_SERVER_NAME );
|
||||
hello.extensions.server_name_len
|
||||
= htons ( sizeof ( hello.extensions.server_name ) );
|
||||
hello.extensions.server_name.len
|
||||
= htons ( sizeof ( hello.extensions.server_name.list ) );
|
||||
hello.extensions.server_name.list[0].type = TLS_SERVER_NAME_HOST_NAME;
|
||||
hello.extensions.server_name.list[0].len
|
||||
= htons ( sizeof ( hello.extensions.server_name.list[0].name ));
|
||||
memcpy ( hello.extensions.server_name.list[0].name, session->name,
|
||||
sizeof ( hello.extensions.server_name.list[0].name ) );
|
||||
hello.extensions.max_fragment_length_type
|
||||
= htons ( TLS_MAX_FRAGMENT_LENGTH );
|
||||
hello.extensions.max_fragment_length_len
|
||||
= htons ( sizeof ( hello.extensions.max_fragment_length ) );
|
||||
hello.extensions.max_fragment_length.max
|
||||
= TLS_MAX_FRAGMENT_LENGTH_4096;
|
||||
hello.extensions.signature_algorithms_type
|
||||
= htons ( TLS_SIGNATURE_ALGORITHMS );
|
||||
hello.extensions.signature_algorithms_len
|
||||
= htons ( sizeof ( hello.extensions.signature_algorithms ) );
|
||||
hello.extensions.signature_algorithms.len
|
||||
= htons ( sizeof ( hello.extensions.signature_algorithms.code));
|
||||
extensions = &hello.extensions;
|
||||
|
||||
/* Construct server name extension */
|
||||
server_name_ext = &extensions->server_name;
|
||||
server_name_ext->type = htons ( TLS_SERVER_NAME );
|
||||
server_name_ext->len = htons ( sizeof ( server_name_ext->data ) );
|
||||
server_name_ext->data.len
|
||||
= htons ( sizeof ( server_name_ext->data.list ) );
|
||||
server_name_ext->data.list[0].type = TLS_SERVER_NAME_HOST_NAME;
|
||||
server_name_ext->data.list[0].len
|
||||
= htons ( sizeof ( server_name_ext->data.list[0].name ) );
|
||||
memcpy ( server_name_ext->data.list[0].name, session->name,
|
||||
sizeof ( server_name_ext->data.list[0].name ) );
|
||||
|
||||
/* Construct maximum fragment length extension */
|
||||
max_fragment_length_ext = &extensions->max_fragment_length;
|
||||
max_fragment_length_ext->type = htons ( TLS_MAX_FRAGMENT_LENGTH );
|
||||
max_fragment_length_ext->len
|
||||
= htons ( sizeof ( max_fragment_length_ext->data ) );
|
||||
max_fragment_length_ext->data.max = TLS_MAX_FRAGMENT_LENGTH_4096;
|
||||
|
||||
/* Construct supported signature algorithms extension */
|
||||
signature_algorithms_ext = &extensions->signature_algorithms;
|
||||
signature_algorithms_ext->type = htons ( TLS_SIGNATURE_ALGORITHMS );
|
||||
signature_algorithms_ext->len
|
||||
= htons ( sizeof ( signature_algorithms_ext->data ) );
|
||||
signature_algorithms_ext->data.len
|
||||
= htons ( sizeof ( signature_algorithms_ext->data.code ) );
|
||||
i = 0 ; for_each_table_entry ( sighash, TLS_SIG_HASH_ALGORITHMS )
|
||||
hello.extensions.signature_algorithms.code[i++] = sighash->code;
|
||||
hello.extensions.renegotiation_info_type
|
||||
= htons ( TLS_RENEGOTIATION_INFO );
|
||||
hello.extensions.renegotiation_info_len
|
||||
= htons ( sizeof ( hello.extensions.renegotiation_info ) );
|
||||
hello.extensions.renegotiation_info.len
|
||||
= sizeof ( hello.extensions.renegotiation_info.data );
|
||||
memcpy ( hello.extensions.renegotiation_info.data, tls->verify.client,
|
||||
sizeof ( hello.extensions.renegotiation_info.data ) );
|
||||
hello.extensions.session_ticket_type = htons ( TLS_SESSION_TICKET );
|
||||
hello.extensions.session_ticket_len
|
||||
= htons ( sizeof ( hello.extensions.session_ticket ) );
|
||||
memcpy ( hello.extensions.session_ticket.data, session->ticket,
|
||||
sizeof ( hello.extensions.session_ticket.data ) );
|
||||
signature_algorithms_ext->data.code[i++] = sighash->code;
|
||||
|
||||
/* Construct renegotiation information extension */
|
||||
renegotiation_info_ext = &extensions->renegotiation_info;
|
||||
renegotiation_info_ext->type = htons ( TLS_RENEGOTIATION_INFO );
|
||||
renegotiation_info_ext->len
|
||||
= htons ( sizeof ( renegotiation_info_ext->data ) );
|
||||
renegotiation_info_ext->data.len
|
||||
= sizeof ( renegotiation_info_ext->data.data );
|
||||
memcpy ( renegotiation_info_ext->data.data, tls->verify.client,
|
||||
sizeof ( renegotiation_info_ext->data.data ) );
|
||||
|
||||
/* Construct session ticket extension */
|
||||
session_ticket_ext = &extensions->session_ticket;
|
||||
session_ticket_ext->type = htons ( TLS_SESSION_TICKET );
|
||||
session_ticket_ext->len
|
||||
= htons ( sizeof ( session_ticket_ext->data ) );
|
||||
memcpy ( session_ticket_ext->data.data, session->ticket,
|
||||
sizeof ( session_ticket_ext->data.data ) );
|
||||
|
||||
/* Construct named curves extension, if applicable */
|
||||
if ( sizeof ( extensions->named_curve ) ) {
|
||||
named_curve_ext = &extensions->named_curve[0];
|
||||
named_curve_ext->type = htons ( TLS_NAMED_CURVE );
|
||||
named_curve_ext->len
|
||||
= htons ( sizeof ( named_curve_ext->data ) );
|
||||
named_curve_ext->data.len
|
||||
= htons ( sizeof ( named_curve_ext->data.code ) );
|
||||
i = 0 ; for_each_table_entry ( curve, TLS_NAMED_CURVES )
|
||||
named_curve_ext->data.code[i++] = curve->code;
|
||||
}
|
||||
|
||||
return action ( tls, &hello, sizeof ( hello ) );
|
||||
}
|
||||
@ -1336,13 +1419,6 @@ static int tls_send_client_key_exchange_pubkey ( struct tls_connection *tls ) {
|
||||
tls_generate_master_secret ( tls, &pre_master_secret,
|
||||
sizeof ( pre_master_secret ) );
|
||||
|
||||
/* Generate keys */
|
||||
if ( ( rc = tls_generate_keys ( tls ) ) != 0 ) {
|
||||
DBGC ( tls, "TLS %p could not generate keys: %s\n",
|
||||
tls, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Encrypt pre-master secret using server's public key */
|
||||
memset ( &key_xchg, 0, sizeof ( key_xchg ) );
|
||||
len = pubkey_encrypt ( pubkey, cipherspec->pubkey_ctx,
|
||||
@ -1374,21 +1450,18 @@ struct tls_key_exchange_algorithm tls_pubkey_exchange_algorithm = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Transmit Client Key Exchange record using DHE key exchange
|
||||
* Verify Diffie-Hellman parameter signature
|
||||
*
|
||||
* @v tls TLS connection
|
||||
* @v param_len Diffie-Hellman parameter length
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int tls_send_client_key_exchange_dhe ( struct tls_connection *tls ) {
|
||||
static int tls_verify_dh_params ( struct tls_connection *tls,
|
||||
size_t param_len ) {
|
||||
struct tls_cipherspec *cipherspec = &tls->tx_cipherspec_pending;
|
||||
struct pubkey_algorithm *pubkey;
|
||||
struct digest_algorithm *digest;
|
||||
int use_sig_hash = tls_version ( tls, TLS_VERSION_TLS_1_2 );
|
||||
uint8_t private[ sizeof ( tls->client_random.random ) ];
|
||||
const struct {
|
||||
uint16_t len;
|
||||
uint8_t data[0];
|
||||
} __attribute__ (( packed )) *dh_val[3];
|
||||
const struct {
|
||||
struct tls_signature_hash_id sig_hash[use_sig_hash];
|
||||
uint16_t signature_len;
|
||||
@ -1396,7 +1469,91 @@ static int tls_send_client_key_exchange_dhe ( struct tls_connection *tls ) {
|
||||
} __attribute__ (( packed )) *sig;
|
||||
const void *data;
|
||||
size_t remaining;
|
||||
int rc;
|
||||
|
||||
/* Signature follows parameters */
|
||||
assert ( param_len <= tls->server_key_len );
|
||||
data = ( tls->server_key + param_len );
|
||||
remaining = ( tls->server_key_len - param_len );
|
||||
|
||||
/* Parse signature from ServerKeyExchange */
|
||||
sig = data;
|
||||
if ( ( sizeof ( *sig ) > remaining ) ||
|
||||
( ntohs ( sig->signature_len ) > ( remaining -
|
||||
sizeof ( *sig ) ) ) ) {
|
||||
DBGC ( tls, "TLS %p received underlength ServerKeyExchange\n",
|
||||
tls );
|
||||
DBGC_HDA ( tls, 0, tls->server_key, tls->server_key_len );
|
||||
return -EINVAL_KEY_EXCHANGE;
|
||||
}
|
||||
|
||||
/* Identify signature and hash algorithm */
|
||||
if ( use_sig_hash ) {
|
||||
pubkey = tls_signature_hash_pubkey ( sig->sig_hash[0] );
|
||||
digest = tls_signature_hash_digest ( sig->sig_hash[0] );
|
||||
if ( ( ! pubkey ) || ( ! digest ) ) {
|
||||
DBGC ( tls, "TLS %p ServerKeyExchange unsupported "
|
||||
"signature and hash algorithm\n", tls );
|
||||
return -ENOTSUP_SIG_HASH;
|
||||
}
|
||||
if ( pubkey != cipherspec->suite->pubkey ) {
|
||||
DBGC ( tls, "TLS %p ServerKeyExchange incorrect "
|
||||
"signature algorithm %s (expected %s)\n", tls,
|
||||
pubkey->name, cipherspec->suite->pubkey->name );
|
||||
return -EPERM_KEY_EXCHANGE;
|
||||
}
|
||||
} else {
|
||||
pubkey = cipherspec->suite->pubkey;
|
||||
digest = &md5_sha1_algorithm;
|
||||
}
|
||||
|
||||
/* Verify signature */
|
||||
{
|
||||
const void *signature = sig->signature;
|
||||
size_t signature_len = ntohs ( sig->signature_len );
|
||||
uint8_t ctx[digest->ctxsize];
|
||||
uint8_t hash[digest->digestsize];
|
||||
|
||||
/* Calculate digest */
|
||||
digest_init ( digest, ctx );
|
||||
digest_update ( digest, ctx, &tls->client_random,
|
||||
sizeof ( tls->client_random ) );
|
||||
digest_update ( digest, ctx, tls->server_random,
|
||||
sizeof ( tls->server_random ) );
|
||||
digest_update ( digest, ctx, tls->server_key, param_len );
|
||||
digest_final ( digest, ctx, hash );
|
||||
|
||||
/* Verify signature */
|
||||
if ( ( rc = pubkey_verify ( pubkey, cipherspec->pubkey_ctx,
|
||||
digest, hash, signature,
|
||||
signature_len ) ) != 0 ) {
|
||||
DBGC ( tls, "TLS %p ServerKeyExchange failed "
|
||||
"verification\n", tls );
|
||||
DBGC_HDA ( tls, 0, tls->server_key,
|
||||
tls->server_key_len );
|
||||
return -EPERM_KEY_EXCHANGE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transmit Client Key Exchange record using DHE key exchange
|
||||
*
|
||||
* @v tls TLS connection
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int tls_send_client_key_exchange_dhe ( struct tls_connection *tls ) {
|
||||
uint8_t private[ sizeof ( tls->client_random.random ) ];
|
||||
const struct {
|
||||
uint16_t len;
|
||||
uint8_t data[0];
|
||||
} __attribute__ (( packed )) *dh_val[3];
|
||||
const void *data;
|
||||
size_t remaining;
|
||||
size_t frag_len;
|
||||
size_t param_len;
|
||||
unsigned int i;
|
||||
int rc;
|
||||
|
||||
@ -1419,68 +1576,11 @@ static int tls_send_client_key_exchange_dhe ( struct tls_connection *tls ) {
|
||||
data += frag_len;
|
||||
remaining -= frag_len;
|
||||
}
|
||||
sig = data;
|
||||
if ( ( sizeof ( *sig ) > remaining ) ||
|
||||
( ntohs ( sig->signature_len ) > ( remaining -
|
||||
sizeof ( *sig ) ) ) ) {
|
||||
DBGC ( tls, "TLS %p received underlength ServerKeyExchange\n",
|
||||
tls );
|
||||
DBGC_HDA ( tls, 0, tls->server_key, tls->server_key_len );
|
||||
rc = -EINVAL_KEY_EXCHANGE;
|
||||
goto err_header;
|
||||
}
|
||||
param_len = ( tls->server_key_len - remaining );
|
||||
|
||||
/* Identify signature and hash algorithm */
|
||||
if ( use_sig_hash ) {
|
||||
pubkey = tls_signature_hash_pubkey ( sig->sig_hash[0] );
|
||||
digest = tls_signature_hash_digest ( sig->sig_hash[0] );
|
||||
if ( ( ! pubkey ) || ( ! digest ) ) {
|
||||
DBGC ( tls, "TLS %p ServerKeyExchange unsupported "
|
||||
"signature and hash algorithm\n", tls );
|
||||
rc = -ENOTSUP_SIG_HASH;
|
||||
goto err_sig_hash;
|
||||
}
|
||||
if ( pubkey != cipherspec->suite->pubkey ) {
|
||||
DBGC ( tls, "TLS %p ServerKeyExchange incorrect "
|
||||
"signature algorithm %s (expected %s)\n", tls,
|
||||
pubkey->name, cipherspec->suite->pubkey->name );
|
||||
rc = -EPERM_KEY_EXCHANGE;
|
||||
goto err_sig_hash;
|
||||
}
|
||||
} else {
|
||||
pubkey = cipherspec->suite->pubkey;
|
||||
digest = &md5_sha1_algorithm;
|
||||
}
|
||||
|
||||
/* Verify signature */
|
||||
{
|
||||
const void *signature = sig->signature;
|
||||
size_t signature_len = ntohs ( sig->signature_len );
|
||||
uint8_t ctx[digest->ctxsize];
|
||||
uint8_t hash[digest->digestsize];
|
||||
|
||||
/* Calculate digest */
|
||||
digest_init ( digest, ctx );
|
||||
digest_update ( digest, ctx, &tls->client_random,
|
||||
sizeof ( tls->client_random ) );
|
||||
digest_update ( digest, ctx, tls->server_random,
|
||||
sizeof ( tls->server_random ) );
|
||||
digest_update ( digest, ctx, tls->server_key,
|
||||
( tls->server_key_len - remaining ) );
|
||||
digest_final ( digest, ctx, hash );
|
||||
|
||||
/* Verify signature */
|
||||
if ( ( rc = pubkey_verify ( pubkey, cipherspec->pubkey_ctx,
|
||||
digest, hash, signature,
|
||||
signature_len ) ) != 0 ) {
|
||||
DBGC ( tls, "TLS %p ServerKeyExchange failed "
|
||||
"verification\n", tls );
|
||||
DBGC_HDA ( tls, 0, tls->server_key,
|
||||
tls->server_key_len );
|
||||
rc = -EPERM_KEY_EXCHANGE;
|
||||
goto err_verify;
|
||||
}
|
||||
}
|
||||
/* Verify parameter signature */
|
||||
if ( ( rc = tls_verify_dh_params ( tls, param_len ) ) != 0 )
|
||||
goto err_verify;
|
||||
|
||||
/* Generate Diffie-Hellman private key */
|
||||
if ( ( rc = tls_generate_random ( tls, private,
|
||||
@ -1540,13 +1640,6 @@ static int tls_send_client_key_exchange_dhe ( struct tls_connection *tls ) {
|
||||
/* Generate master secret */
|
||||
tls_generate_master_secret ( tls, pre_master_secret, len );
|
||||
|
||||
/* Generate keys */
|
||||
if ( ( rc = tls_generate_keys ( tls ) ) != 0 ) {
|
||||
DBGC ( tls, "TLS %p could not generate keys: %s\n",
|
||||
tls, strerror ( rc ) );
|
||||
goto err_generate_keys;
|
||||
}
|
||||
|
||||
/* Transmit Client Key Exchange record */
|
||||
if ( ( rc = tls_send_handshake ( tls, key_xchg,
|
||||
sizeof ( *key_xchg ) ) ) !=0){
|
||||
@ -1554,14 +1647,12 @@ static int tls_send_client_key_exchange_dhe ( struct tls_connection *tls ) {
|
||||
}
|
||||
|
||||
err_send_handshake:
|
||||
err_generate_keys:
|
||||
err_dhe_key:
|
||||
free ( dynamic );
|
||||
}
|
||||
err_alloc:
|
||||
err_random:
|
||||
err_verify:
|
||||
err_sig_hash:
|
||||
err_header:
|
||||
return rc;
|
||||
}
|
||||
@ -1572,6 +1663,119 @@ struct tls_key_exchange_algorithm tls_dhe_exchange_algorithm = {
|
||||
.exchange = tls_send_client_key_exchange_dhe,
|
||||
};
|
||||
|
||||
/**
|
||||
* Transmit Client Key Exchange record using ECDHE key exchange
|
||||
*
|
||||
* @v tls TLS connection
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int tls_send_client_key_exchange_ecdhe ( struct tls_connection *tls ) {
|
||||
struct tls_named_curve *curve;
|
||||
const struct {
|
||||
uint8_t curve_type;
|
||||
uint16_t named_curve;
|
||||
uint8_t public_len;
|
||||
uint8_t public[0];
|
||||
} __attribute__ (( packed )) *ecdh;
|
||||
size_t param_len;
|
||||
int rc;
|
||||
|
||||
/* Parse ServerKeyExchange record */
|
||||
ecdh = tls->server_key;
|
||||
if ( ( sizeof ( *ecdh ) > tls->server_key_len ) ||
|
||||
( ecdh->public_len > ( tls->server_key_len - sizeof ( *ecdh ) ))){
|
||||
DBGC ( tls, "TLS %p received underlength ServerKeyExchange\n",
|
||||
tls );
|
||||
DBGC_HDA ( tls, 0, tls->server_key, tls->server_key_len );
|
||||
return -EINVAL_KEY_EXCHANGE;
|
||||
}
|
||||
param_len = ( sizeof ( *ecdh ) + ecdh->public_len );
|
||||
|
||||
/* Verify parameter signature */
|
||||
if ( ( rc = tls_verify_dh_params ( tls, param_len ) ) != 0 )
|
||||
return rc;
|
||||
|
||||
/* Identify named curve */
|
||||
if ( ecdh->curve_type != TLS_NAMED_CURVE_TYPE ) {
|
||||
DBGC ( tls, "TLS %p unsupported curve type %d\n",
|
||||
tls, ecdh->curve_type );
|
||||
DBGC_HDA ( tls, 0, tls->server_key, tls->server_key_len );
|
||||
return -ENOTSUP_CURVE;
|
||||
}
|
||||
curve = tls_find_named_curve ( ecdh->named_curve );
|
||||
if ( ! curve ) {
|
||||
DBGC ( tls, "TLS %p unsupported named curve %d\n",
|
||||
tls, ntohs ( ecdh->named_curve ) );
|
||||
DBGC_HDA ( tls, 0, tls->server_key, tls->server_key_len );
|
||||
return -ENOTSUP_CURVE;
|
||||
}
|
||||
|
||||
/* Check key length */
|
||||
if ( ecdh->public_len != curve->curve->keysize ) {
|
||||
DBGC ( tls, "TLS %p invalid %s key\n",
|
||||
tls, curve->curve->name );
|
||||
DBGC_HDA ( tls, 0, tls->server_key, tls->server_key_len );
|
||||
return -EINVAL_KEY_EXCHANGE;
|
||||
}
|
||||
|
||||
/* Construct pre-master secret and ClientKeyExchange record */
|
||||
{
|
||||
size_t len = curve->curve->keysize;
|
||||
uint8_t private[len];
|
||||
uint8_t pre_master_secret[len];
|
||||
struct {
|
||||
uint32_t type_length;
|
||||
uint8_t public_len;
|
||||
uint8_t public[len];
|
||||
} __attribute__ (( packed )) key_xchg;
|
||||
|
||||
/* Generate ephemeral private key */
|
||||
if ( ( rc = tls_generate_random ( tls, private,
|
||||
sizeof ( private ) ) ) != 0){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Calculate pre-master secret */
|
||||
if ( ( rc = elliptic_multiply ( curve->curve,
|
||||
ecdh->public, private,
|
||||
pre_master_secret ) ) != 0 ) {
|
||||
DBGC ( tls, "TLS %p could not exchange ECDHE key: %s\n",
|
||||
tls, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Generate master secret */
|
||||
tls_generate_master_secret ( tls, pre_master_secret, len );
|
||||
|
||||
/* Generate Client Key Exchange record */
|
||||
key_xchg.type_length =
|
||||
( cpu_to_le32 ( TLS_CLIENT_KEY_EXCHANGE ) |
|
||||
htonl ( sizeof ( key_xchg ) -
|
||||
sizeof ( key_xchg.type_length ) ) );
|
||||
key_xchg.public_len = len;
|
||||
if ( ( rc = elliptic_multiply ( curve->curve, NULL, private,
|
||||
key_xchg.public ) ) != 0 ) {
|
||||
DBGC ( tls, "TLS %p could not generate ECDHE key: %s\n",
|
||||
tls, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Transmit Client Key Exchange record */
|
||||
if ( ( rc = tls_send_handshake ( tls, &key_xchg,
|
||||
sizeof ( key_xchg ) ) ) !=0){
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Ephemeral Elliptic Curve Diffie-Hellman key exchange algorithm */
|
||||
struct tls_key_exchange_algorithm tls_ecdhe_exchange_algorithm = {
|
||||
.name = "ecdhe",
|
||||
.exchange = tls_send_client_key_exchange_ecdhe,
|
||||
};
|
||||
|
||||
/**
|
||||
* Transmit Client Key Exchange record
|
||||
*
|
||||
@ -1581,9 +1785,23 @@ struct tls_key_exchange_algorithm tls_dhe_exchange_algorithm = {
|
||||
static int tls_send_client_key_exchange ( struct tls_connection *tls ) {
|
||||
struct tls_cipherspec *cipherspec = &tls->tx_cipherspec_pending;
|
||||
struct tls_cipher_suite *suite = cipherspec->suite;
|
||||
int rc;
|
||||
|
||||
/* Transmit Client Key Exchange record via key exchange algorithm */
|
||||
return suite->exchange->exchange ( tls );
|
||||
if ( ( rc = suite->exchange->exchange ( tls ) ) != 0 ) {
|
||||
DBGC ( tls, "TLS %p could not exchange keys: %s\n",
|
||||
tls, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Generate keys from master secret */
|
||||
if ( ( rc = tls_generate_keys ( tls ) ) != 0 ) {
|
||||
DBGC ( tls, "TLS %p could not generate keys: %s\n",
|
||||
tls, strerror ( rc ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2727,9 +2945,9 @@ static int tls_send_plaintext ( struct tls_connection *tls, unsigned int type,
|
||||
} __attribute__ (( packed )) iv;
|
||||
struct tls_auth_header authhdr;
|
||||
struct tls_header *tlshdr;
|
||||
void *plaintext = NULL;
|
||||
size_t plaintext_len = len;
|
||||
struct io_buffer *ciphertext = NULL;
|
||||
void *plaintext;
|
||||
size_t plaintext_len;
|
||||
struct io_buffer *ciphertext;
|
||||
size_t ciphertext_len;
|
||||
size_t padding_len;
|
||||
uint8_t mac[digest->digestsize];
|
||||
@ -2738,7 +2956,10 @@ static int tls_send_plaintext ( struct tls_connection *tls, unsigned int type,
|
||||
|
||||
/* Construct initialisation vector */
|
||||
memcpy ( iv.fixed, cipherspec->fixed_iv, sizeof ( iv.fixed ) );
|
||||
tls_generate_random ( tls, iv.record, sizeof ( iv.record ) );
|
||||
if ( ( rc = tls_generate_random ( tls, iv.record,
|
||||
sizeof ( iv.record ) ) ) != 0 ) {
|
||||
goto err_random;
|
||||
}
|
||||
|
||||
/* Construct authentication data */
|
||||
authhdr.seq = cpu_to_be64 ( tls->tx_seq );
|
||||
@ -2747,7 +2968,7 @@ static int tls_send_plaintext ( struct tls_connection *tls, unsigned int type,
|
||||
authhdr.header.length = htons ( len );
|
||||
|
||||
/* Calculate padding length */
|
||||
plaintext_len += suite->mac_len;
|
||||
plaintext_len = ( len + suite->mac_len );
|
||||
if ( is_block_cipher ( cipher ) ) {
|
||||
padding_len = ( ( ( cipher->blocksize - 1 ) &
|
||||
-( plaintext_len + 1 ) ) + 1 );
|
||||
@ -2762,7 +2983,7 @@ static int tls_send_plaintext ( struct tls_connection *tls, unsigned int type,
|
||||
DBGC ( tls, "TLS %p could not allocate %zd bytes for "
|
||||
"plaintext\n", tls, plaintext_len );
|
||||
rc = -ENOMEM_TX_PLAINTEXT;
|
||||
goto done;
|
||||
goto err_plaintext;
|
||||
}
|
||||
|
||||
/* Assemble plaintext */
|
||||
@ -2796,7 +3017,7 @@ static int tls_send_plaintext ( struct tls_connection *tls, unsigned int type,
|
||||
DBGC ( tls, "TLS %p could not allocate %zd bytes for "
|
||||
"ciphertext\n", tls, ciphertext_len );
|
||||
rc = -ENOMEM_TX_CIPHERTEXT;
|
||||
goto done;
|
||||
goto err_ciphertext;
|
||||
}
|
||||
|
||||
/* Assemble ciphertext */
|
||||
@ -2821,15 +3042,22 @@ static int tls_send_plaintext ( struct tls_connection *tls, unsigned int type,
|
||||
iob_disown ( ciphertext ) ) ) != 0 ) {
|
||||
DBGC ( tls, "TLS %p could not deliver ciphertext: %s\n",
|
||||
tls, strerror ( rc ) );
|
||||
goto done;
|
||||
goto err_deliver;
|
||||
}
|
||||
|
||||
/* Update TX state machine to next record */
|
||||
tls->tx_seq += 1;
|
||||
|
||||
done:
|
||||
free ( plaintext );
|
||||
assert ( plaintext == NULL );
|
||||
assert ( ciphertext == NULL );
|
||||
return 0;
|
||||
|
||||
err_deliver:
|
||||
free_iob ( ciphertext );
|
||||
err_ciphertext:
|
||||
free ( plaintext );
|
||||
err_plaintext:
|
||||
err_random:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
@ -63,11 +63,6 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
0x2c, 0x07, 0x3b, 0x61, 0x08, 0xd7, 0x2d, 0x98, 0x10, \
|
||||
0xa3, 0x09, 0x14, 0xdf, 0xf4 )
|
||||
|
||||
/** Dummy initialisation vector used for NIST ECB-mode test vectors */
|
||||
#define AES_IV_NIST_DUMMY \
|
||||
IV ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 )
|
||||
|
||||
/** Initialisation vector used for NIST CBC-mode test vectors */
|
||||
#define AES_IV_NIST_CBC \
|
||||
IV ( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, \
|
||||
@ -86,7 +81,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** AES-128-ECB (same test as AES-128-Core) */
|
||||
CIPHER_TEST ( aes_128_ecb, &aes_ecb_algorithm,
|
||||
AES_KEY_NIST_128, AES_IV_NIST_DUMMY, ADDITIONAL(), AES_PLAINTEXT_NIST,
|
||||
AES_KEY_NIST_128, IV(), ADDITIONAL(), AES_PLAINTEXT_NIST,
|
||||
CIPHERTEXT ( 0x3a, 0xd7, 0x7b, 0xb4, 0x0d, 0x7a, 0x36, 0x60,
|
||||
0xa8, 0x9e, 0xca, 0xf3, 0x24, 0x66, 0xef, 0x97,
|
||||
0xf5, 0xd3, 0xd5, 0x85, 0x03, 0xb9, 0x69, 0x9d,
|
||||
@ -110,7 +105,7 @@ CIPHER_TEST ( aes_128_cbc, &aes_cbc_algorithm,
|
||||
|
||||
/** AES-192-ECB (same test as AES-192-Core) */
|
||||
CIPHER_TEST ( aes_192_ecb, &aes_ecb_algorithm,
|
||||
AES_KEY_NIST_192, AES_IV_NIST_DUMMY, ADDITIONAL(), AES_PLAINTEXT_NIST,
|
||||
AES_KEY_NIST_192, IV(), ADDITIONAL(), AES_PLAINTEXT_NIST,
|
||||
CIPHERTEXT ( 0xbd, 0x33, 0x4f, 0x1d, 0x6e, 0x45, 0xf2, 0x5f,
|
||||
0xf7, 0x12, 0xa2, 0x14, 0x57, 0x1f, 0xa5, 0xcc,
|
||||
0x97, 0x41, 0x04, 0x84, 0x6d, 0x0a, 0xd3, 0xad,
|
||||
@ -134,7 +129,7 @@ CIPHER_TEST ( aes_192_cbc, &aes_cbc_algorithm,
|
||||
|
||||
/** AES-256-ECB (same test as AES-256-Core) */
|
||||
CIPHER_TEST ( aes_256_ecb, &aes_ecb_algorithm,
|
||||
AES_KEY_NIST_256, AES_IV_NIST_DUMMY, ADDITIONAL(), AES_PLAINTEXT_NIST,
|
||||
AES_KEY_NIST_256, IV(), ADDITIONAL(), AES_PLAINTEXT_NIST,
|
||||
CIPHERTEXT ( 0xf3, 0xee, 0xd1, 0xbd, 0xb5, 0xd2, 0xa0, 0x3c,
|
||||
0x06, 0x4b, 0x5a, 0x7e, 0x3d, 0xb1, 0x81, 0xf8,
|
||||
0x59, 0x1c, 0xcb, 0x10, 0xd4, 0x10, 0xed, 0x26,
|
||||
|
||||
@ -714,6 +714,15 @@ static void bigint_test_exec ( void ) {
|
||||
bigint_subtract_ok ( BIGINT ( 0xbb, 0x77, 0x32, 0x5a ),
|
||||
BIGINT ( 0x5a, 0xd5, 0xfe, 0x28 ),
|
||||
BIGINT ( 0x9f, 0x5e, 0xcb, 0xce ) );
|
||||
bigint_subtract_ok ( BIGINT ( 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff ),
|
||||
BIGINT ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x2a ),
|
||||
BIGINT ( 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x2b ) );
|
||||
bigint_subtract_ok ( BIGINT ( 0x7b, 0xaa, 0x16, 0xcf, 0x15, 0x87,
|
||||
0xe0, 0x4f, 0x2c, 0xa3, 0xec, 0x2f,
|
||||
0x46, 0xfb, 0x83, 0xc6, 0xe0, 0xee,
|
||||
|
||||
898
src/tests/des_test.c
Normal file
898
src/tests/des_test.c
Normal file
@ -0,0 +1,898 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
* 02110-1301, USA.
|
||||
*
|
||||
* You can also choose to distribute this program under the terms of
|
||||
* the Unmodified Binary Distribution Licence (as given in the file
|
||||
* COPYING.UBDL), provided that you have satisfied its requirements.
|
||||
*/
|
||||
|
||||
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
|
||||
/** @file
|
||||
*
|
||||
* DES tests
|
||||
*
|
||||
* These test vectors are originally provided by NBS (the precursor of
|
||||
* NIST) in SP 500-20, downloadable as a scan of the typewritten
|
||||
* original from:
|
||||
*
|
||||
* https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nbsspecialpublication500-20e1980.pdf
|
||||
*/
|
||||
|
||||
/* Forcibly enable assertions */
|
||||
#undef NDEBUG
|
||||
|
||||
#include <assert.h>
|
||||
#include <ipxe/des.h>
|
||||
#include <ipxe/test.h>
|
||||
#include "cipher_test.h"
|
||||
|
||||
/** Define a DES 64-bit test value */
|
||||
#define DES_VALUE(value) { \
|
||||
( ( ( ( uint64_t ) (value) ) >> 56 ) & 0xff ), \
|
||||
( ( ( ( uint64_t ) (value) ) >> 48 ) & 0xff ), \
|
||||
( ( ( ( uint64_t ) (value) ) >> 40 ) & 0xff ), \
|
||||
( ( ( ( uint64_t ) (value) ) >> 32 ) & 0xff ), \
|
||||
( ( ( ( uint64_t ) (value) ) >> 24 ) & 0xff ), \
|
||||
( ( ( ( uint64_t ) (value) ) >> 16 ) & 0xff ), \
|
||||
( ( ( ( uint64_t ) (value) ) >> 8 ) & 0xff ), \
|
||||
( ( ( ( uint64_t ) (value) ) >> 0 ) & 0xff ) \
|
||||
}
|
||||
|
||||
/** Define a DES test */
|
||||
#define DES_TEST( name, key, plaintext, ciphertext ) \
|
||||
CIPHER_TEST ( name, &des_ecb_algorithm, DES_VALUE ( key ), \
|
||||
IV(), ADDITIONAL(), DES_VALUE ( plaintext ), \
|
||||
DES_VALUE ( ciphertext ), AUTH() )
|
||||
|
||||
/* Sample round outputs (page 9) */
|
||||
DES_TEST ( des_round_sample,
|
||||
0x10316e028c8f3b4a, 0x0000000000000000, 0x82dcbafbdeab6602 );
|
||||
|
||||
/* Test 1: Initial permutation and expansion tests
|
||||
*
|
||||
* "Set Key=0 and encrypt the 64-bit data vectors e[i]: i=1,...,64"
|
||||
*
|
||||
* Appendix B, page 28 ("IP and E test")
|
||||
*/
|
||||
DES_TEST ( des_test1_1,
|
||||
0x0101010101010101, 0x8000000000000000, 0x95f8a5e5dd31d900 );
|
||||
DES_TEST ( des_test1_2,
|
||||
0x0101010101010101, 0x4000000000000000, 0xdd7f121ca5015619 );
|
||||
DES_TEST ( des_test1_3,
|
||||
0x0101010101010101, 0x2000000000000000, 0x2e8653104f3834ea );
|
||||
DES_TEST ( des_test1_4,
|
||||
0x0101010101010101, 0x1000000000000000, 0x4bd388ff6cd81d4f );
|
||||
DES_TEST ( des_test1_5,
|
||||
0x0101010101010101, 0x0800000000000000, 0x20b9e767b2fb1456 );
|
||||
DES_TEST ( des_test1_6,
|
||||
0x0101010101010101, 0x0400000000000000, 0x55579380d77138ef );
|
||||
DES_TEST ( des_test1_7,
|
||||
0x0101010101010101, 0x0200000000000000, 0x6cc5defaaf04512f );
|
||||
DES_TEST ( des_test1_8,
|
||||
0x0101010101010101, 0x0100000000000000, 0x0d9f279ba5d87260 );
|
||||
DES_TEST ( des_test1_9,
|
||||
0x0101010101010101, 0x0080000000000000, 0xd9031b0271bd5a0a );
|
||||
DES_TEST ( des_test1_10,
|
||||
0x0101010101010101, 0x0040000000000000, 0x424250b37c3dd951 );
|
||||
DES_TEST ( des_test1_11,
|
||||
0x0101010101010101, 0x0020000000000000, 0xb8061b7ecd9a21e5 );
|
||||
DES_TEST ( des_test1_12,
|
||||
0x0101010101010101, 0x0010000000000000, 0xf15d0f286b65bd28 );
|
||||
DES_TEST ( des_test1_13,
|
||||
0x0101010101010101, 0x0008000000000000, 0xadd0cc8d6e5deba1 );
|
||||
DES_TEST ( des_test1_14,
|
||||
0x0101010101010101, 0x0004000000000000, 0xe6d5f82752ad63d1 );
|
||||
DES_TEST ( des_test1_15,
|
||||
0x0101010101010101, 0x0002000000000000, 0xecbfe3bd3f591a5e );
|
||||
DES_TEST ( des_test1_16,
|
||||
0x0101010101010101, 0x0001000000000000, 0xf356834379d165cd );
|
||||
DES_TEST ( des_test1_17,
|
||||
0x0101010101010101, 0x0000800000000000, 0x2b9f982f20037fa9 );
|
||||
DES_TEST ( des_test1_18,
|
||||
0x0101010101010101, 0x0000400000000000, 0x889de068a16f0be6 );
|
||||
DES_TEST ( des_test1_19,
|
||||
0x0101010101010101, 0x0000200000000000, 0xe19e275d846a1298 );
|
||||
DES_TEST ( des_test1_20,
|
||||
0x0101010101010101, 0x0000100000000000, 0x329a8ed523d71aec );
|
||||
DES_TEST ( des_test1_21,
|
||||
0x0101010101010101, 0x0000080000000000, 0xe7fce22557d23c97 );
|
||||
DES_TEST ( des_test1_22,
|
||||
0x0101010101010101, 0x0000040000000000, 0x12a9f5817ff2d65d );
|
||||
DES_TEST ( des_test1_23,
|
||||
0x0101010101010101, 0x0000020000000000, 0xa484c3ad38dc9c19 );
|
||||
DES_TEST ( des_test1_24,
|
||||
0x0101010101010101, 0x0000010000000000, 0xfbe00a8a1ef8ad72 );
|
||||
DES_TEST ( des_test1_25,
|
||||
0x0101010101010101, 0x0000008000000000, 0x750d079407521363 );
|
||||
DES_TEST ( des_test1_26,
|
||||
0x0101010101010101, 0x0000004000000000, 0x64feed9c724c2faf );
|
||||
DES_TEST ( des_test1_27,
|
||||
0x0101010101010101, 0x0000002000000000, 0xf02b263b328e2b60 );
|
||||
DES_TEST ( des_test1_28,
|
||||
0x0101010101010101, 0x0000001000000000, 0x9d64555a9a10b852 );
|
||||
DES_TEST ( des_test1_29,
|
||||
0x0101010101010101, 0x0000000800000000, 0xd106ff0bed5255d7 );
|
||||
DES_TEST ( des_test1_30,
|
||||
0x0101010101010101, 0x0000000400000000, 0xe1652c6b138c64a5 );
|
||||
DES_TEST ( des_test1_31,
|
||||
0x0101010101010101, 0x0000000200000000, 0xe428581186ec8f46 );
|
||||
DES_TEST ( des_test1_32,
|
||||
0x0101010101010101, 0x0000000100000000, 0xaeb5f5ede22d1a36 );
|
||||
DES_TEST ( des_test1_33,
|
||||
0x0101010101010101, 0x0000000080000000, 0xe943d7568aec0c5c );
|
||||
DES_TEST ( des_test1_34,
|
||||
0x0101010101010101, 0x0000000040000000, 0xdf98c8276f54b04b );
|
||||
DES_TEST ( des_test1_35,
|
||||
0x0101010101010101, 0x0000000020000000, 0xb160e4680f6c696f );
|
||||
DES_TEST ( des_test1_36,
|
||||
0x0101010101010101, 0x0000000010000000, 0xfa0752b07d9c4ab8 );
|
||||
DES_TEST ( des_test1_37,
|
||||
0x0101010101010101, 0x0000000008000000, 0xca3a2b036dbc8502 );
|
||||
DES_TEST ( des_test1_38,
|
||||
0x0101010101010101, 0x0000000004000000, 0x5e0905517bb59bcf );
|
||||
DES_TEST ( des_test1_39,
|
||||
0x0101010101010101, 0x0000000002000000, 0x814eeb3b91d90726 );
|
||||
DES_TEST ( des_test1_40,
|
||||
0x0101010101010101, 0x0000000001000000, 0x4d49db1532919c9f );
|
||||
DES_TEST ( des_test1_41,
|
||||
0x0101010101010101, 0x0000000000800000, 0x25eb5fc3f8cf0621 );
|
||||
DES_TEST ( des_test1_42,
|
||||
0x0101010101010101, 0x0000000000400000, 0xab6a20c0620d1c6f );
|
||||
DES_TEST ( des_test1_43,
|
||||
0x0101010101010101, 0x0000000000200000, 0x79e90dbc98f92cca );
|
||||
DES_TEST ( des_test1_44,
|
||||
0x0101010101010101, 0x0000000000100000, 0x866ecedd8072bb0e );
|
||||
DES_TEST ( des_test1_45,
|
||||
0x0101010101010101, 0x0000000000080000, 0x8b54536f2f3e64a8 );
|
||||
DES_TEST ( des_test1_46,
|
||||
0x0101010101010101, 0x0000000000040000, 0xea51d3975595b86b );
|
||||
DES_TEST ( des_test1_47,
|
||||
0x0101010101010101, 0x0000000000020000, 0xcaffc6ac4542de31 );
|
||||
DES_TEST ( des_test1_48,
|
||||
0x0101010101010101, 0x0000000000010000, 0x8dd45a2ddf90796c );
|
||||
DES_TEST ( des_test1_49,
|
||||
0x0101010101010101, 0x0000000000008000, 0x1029d55e880ec2d0 );
|
||||
DES_TEST ( des_test1_50,
|
||||
0x0101010101010101, 0x0000000000004000, 0x5d86cb23639dbea9 );
|
||||
DES_TEST ( des_test1_51,
|
||||
0x0101010101010101, 0x0000000000002000, 0x1d1ca853ae7c0c5f );
|
||||
DES_TEST ( des_test1_52,
|
||||
0x0101010101010101, 0x0000000000001000, 0xce332329248f3228 );
|
||||
DES_TEST ( des_test1_53,
|
||||
0x0101010101010101, 0x0000000000000800, 0x8405d1abe24fb942 );
|
||||
DES_TEST ( des_test1_54,
|
||||
0x0101010101010101, 0x0000000000000400, 0xe643d78090ca4207 );
|
||||
DES_TEST ( des_test1_55,
|
||||
0x0101010101010101, 0x0000000000000200, 0x48221b9937748a23 );
|
||||
DES_TEST ( des_test1_56,
|
||||
0x0101010101010101, 0x0000000000000100, 0xdd7c0bbd61fafd54 );
|
||||
DES_TEST ( des_test1_57,
|
||||
0x0101010101010101, 0x0000000000000080, 0x2fbc291a570db5c4 );
|
||||
DES_TEST ( des_test1_58,
|
||||
0x0101010101010101, 0x0000000000000040, 0xe07c30d7e4e26e12 );
|
||||
DES_TEST ( des_test1_59,
|
||||
0x0101010101010101, 0x0000000000000020, 0x0953e2258e8e90a1 );
|
||||
DES_TEST ( des_test1_60,
|
||||
0x0101010101010101, 0x0000000000000010, 0x5b711bc4ceebf2ee );
|
||||
DES_TEST ( des_test1_61,
|
||||
0x0101010101010101, 0x0000000000000008, 0xcc083f1e6d9e85f6 );
|
||||
DES_TEST ( des_test1_62,
|
||||
0x0101010101010101, 0x0000000000000004, 0xd2fd8867d50d2dfe );
|
||||
DES_TEST ( des_test1_63,
|
||||
0x0101010101010101, 0x0000000000000002, 0x06e7ea22ce92708f );
|
||||
DES_TEST ( des_test1_64,
|
||||
0x0101010101010101, 0x0000000000000001, 0x166b40b44aba4bd6 );
|
||||
|
||||
/* Test 2: Inverse permutation and expansion tests
|
||||
*
|
||||
* "Set Key=0 and encrypt the results c[i] obtained in Test 1"
|
||||
*
|
||||
* Appendix B, page 28 ("IP and E test")
|
||||
*/
|
||||
DES_TEST ( des_test2_1,
|
||||
0x0101010101010101, 0x95f8a5e5dd31d900, 0x8000000000000000 );
|
||||
DES_TEST ( des_test2_2,
|
||||
0x0101010101010101, 0xdd7f121ca5015619, 0x4000000000000000 );
|
||||
DES_TEST ( des_test2_3,
|
||||
0x0101010101010101, 0x2e8653104f3834ea, 0x2000000000000000 );
|
||||
DES_TEST ( des_test2_4,
|
||||
0x0101010101010101, 0x4bd388ff6cd81d4f, 0x1000000000000000 );
|
||||
DES_TEST ( des_test2_5,
|
||||
0x0101010101010101, 0x20b9e767b2fb1456, 0x0800000000000000 );
|
||||
DES_TEST ( des_test2_6,
|
||||
0x0101010101010101, 0x55579380d77138ef, 0x0400000000000000 );
|
||||
DES_TEST ( des_test2_7,
|
||||
0x0101010101010101, 0x6cc5defaaf04512f, 0x0200000000000000 );
|
||||
DES_TEST ( des_test2_8,
|
||||
0x0101010101010101, 0x0d9f279ba5d87260, 0x0100000000000000 );
|
||||
DES_TEST ( des_test2_9,
|
||||
0x0101010101010101, 0xd9031b0271bd5a0a, 0x0080000000000000 );
|
||||
DES_TEST ( des_test2_10,
|
||||
0x0101010101010101, 0x424250b37c3dd951, 0x0040000000000000 );
|
||||
DES_TEST ( des_test2_11,
|
||||
0x0101010101010101, 0xb8061b7ecd9a21e5, 0x0020000000000000 );
|
||||
DES_TEST ( des_test2_12,
|
||||
0x0101010101010101, 0xf15d0f286b65bd28, 0x0010000000000000 );
|
||||
DES_TEST ( des_test2_13,
|
||||
0x0101010101010101, 0xadd0cc8d6e5deba1, 0x0008000000000000 );
|
||||
DES_TEST ( des_test2_14,
|
||||
0x0101010101010101, 0xe6d5f82752ad63d1, 0x0004000000000000 );
|
||||
DES_TEST ( des_test2_15,
|
||||
0x0101010101010101, 0xecbfe3bd3f591a5e, 0x0002000000000000 );
|
||||
DES_TEST ( des_test2_16,
|
||||
0x0101010101010101, 0xf356834379d165cd, 0x0001000000000000 );
|
||||
DES_TEST ( des_test2_17,
|
||||
0x0101010101010101, 0x2b9f982f20037fa9, 0x0000800000000000 );
|
||||
DES_TEST ( des_test2_18,
|
||||
0x0101010101010101, 0x889de068a16f0be6, 0x0000400000000000 );
|
||||
DES_TEST ( des_test2_19,
|
||||
0x0101010101010101, 0xe19e275d846a1298, 0x0000200000000000 );
|
||||
DES_TEST ( des_test2_20,
|
||||
0x0101010101010101, 0x329a8ed523d71aec, 0x0000100000000000 );
|
||||
DES_TEST ( des_test2_21,
|
||||
0x0101010101010101, 0xe7fce22557d23c97, 0x0000080000000000 );
|
||||
DES_TEST ( des_test2_22,
|
||||
0x0101010101010101, 0x12a9f5817ff2d65d, 0x0000040000000000 );
|
||||
DES_TEST ( des_test2_23,
|
||||
0x0101010101010101, 0xa484c3ad38dc9c19, 0x0000020000000000 );
|
||||
DES_TEST ( des_test2_24,
|
||||
0x0101010101010101, 0xfbe00a8a1ef8ad72, 0x0000010000000000 );
|
||||
DES_TEST ( des_test2_25,
|
||||
0x0101010101010101, 0x750d079407521363, 0x0000008000000000 );
|
||||
DES_TEST ( des_test2_26,
|
||||
0x0101010101010101, 0x64feed9c724c2faf, 0x0000004000000000 );
|
||||
DES_TEST ( des_test2_27,
|
||||
0x0101010101010101, 0xf02b263b328e2b60, 0x0000002000000000 );
|
||||
DES_TEST ( des_test2_28,
|
||||
0x0101010101010101, 0x9d64555a9a10b852, 0x0000001000000000 );
|
||||
DES_TEST ( des_test2_29,
|
||||
0x0101010101010101, 0xd106ff0bed5255d7, 0x0000000800000000 );
|
||||
DES_TEST ( des_test2_30,
|
||||
0x0101010101010101, 0xe1652c6b138c64a5, 0x0000000400000000 );
|
||||
DES_TEST ( des_test2_31,
|
||||
0x0101010101010101, 0xe428581186ec8f46, 0x0000000200000000 );
|
||||
DES_TEST ( des_test2_32,
|
||||
0x0101010101010101, 0xaeb5f5ede22d1a36, 0x0000000100000000 );
|
||||
DES_TEST ( des_test2_33,
|
||||
0x0101010101010101, 0xe943d7568aec0c5c, 0x0000000080000000 );
|
||||
DES_TEST ( des_test2_34,
|
||||
0x0101010101010101, 0xdf98c8276f54b04b, 0x0000000040000000 );
|
||||
DES_TEST ( des_test2_35,
|
||||
0x0101010101010101, 0xb160e4680f6c696f, 0x0000000020000000 );
|
||||
DES_TEST ( des_test2_36,
|
||||
0x0101010101010101, 0xfa0752b07d9c4ab8, 0x0000000010000000 );
|
||||
DES_TEST ( des_test2_37,
|
||||
0x0101010101010101, 0xca3a2b036dbc8502, 0x0000000008000000 );
|
||||
DES_TEST ( des_test2_38,
|
||||
0x0101010101010101, 0x5e0905517bb59bcf, 0x0000000004000000 );
|
||||
DES_TEST ( des_test2_39,
|
||||
0x0101010101010101, 0x814eeb3b91d90726, 0x0000000002000000 );
|
||||
DES_TEST ( des_test2_40,
|
||||
0x0101010101010101, 0x4d49db1532919c9f, 0x0000000001000000 );
|
||||
DES_TEST ( des_test2_41,
|
||||
0x0101010101010101, 0x25eb5fc3f8cf0621, 0x0000000000800000 );
|
||||
DES_TEST ( des_test2_42,
|
||||
0x0101010101010101, 0xab6a20c0620d1c6f, 0x0000000000400000 );
|
||||
DES_TEST ( des_test2_43,
|
||||
0x0101010101010101, 0x79e90dbc98f92cca, 0x0000000000200000 );
|
||||
DES_TEST ( des_test2_44,
|
||||
0x0101010101010101, 0x866ecedd8072bb0e, 0x0000000000100000 );
|
||||
DES_TEST ( des_test2_45,
|
||||
0x0101010101010101, 0x8b54536f2f3e64a8, 0x0000000000080000 );
|
||||
DES_TEST ( des_test2_46,
|
||||
0x0101010101010101, 0xea51d3975595b86b, 0x0000000000040000 );
|
||||
DES_TEST ( des_test2_47,
|
||||
0x0101010101010101, 0xcaffc6ac4542de31, 0x0000000000020000 );
|
||||
DES_TEST ( des_test2_48,
|
||||
0x0101010101010101, 0x8dd45a2ddf90796c, 0x0000000000010000 );
|
||||
DES_TEST ( des_test2_49,
|
||||
0x0101010101010101, 0x1029d55e880ec2d0, 0x0000000000008000 );
|
||||
DES_TEST ( des_test2_50,
|
||||
0x0101010101010101, 0x5d86cb23639dbea9, 0x0000000000004000 );
|
||||
DES_TEST ( des_test2_51,
|
||||
0x0101010101010101, 0x1d1ca853ae7c0c5f, 0x0000000000002000 );
|
||||
DES_TEST ( des_test2_52,
|
||||
0x0101010101010101, 0xce332329248f3228, 0x0000000000001000 );
|
||||
DES_TEST ( des_test2_53,
|
||||
0x0101010101010101, 0x8405d1abe24fb942, 0x0000000000000800 );
|
||||
DES_TEST ( des_test2_54,
|
||||
0x0101010101010101, 0xe643d78090ca4207, 0x0000000000000400 );
|
||||
DES_TEST ( des_test2_55,
|
||||
0x0101010101010101, 0x48221b9937748a23, 0x0000000000000200 );
|
||||
DES_TEST ( des_test2_56,
|
||||
0x0101010101010101, 0xdd7c0bbd61fafd54, 0x0000000000000100 );
|
||||
DES_TEST ( des_test2_57,
|
||||
0x0101010101010101, 0x2fbc291a570db5c4, 0x0000000000000080 );
|
||||
DES_TEST ( des_test2_58,
|
||||
0x0101010101010101, 0xe07c30d7e4e26e12, 0x0000000000000040 );
|
||||
DES_TEST ( des_test2_59,
|
||||
0x0101010101010101, 0x0953e2258e8e90a1, 0x0000000000000020 );
|
||||
DES_TEST ( des_test2_60,
|
||||
0x0101010101010101, 0x5b711bc4ceebf2ee, 0x0000000000000010 );
|
||||
DES_TEST ( des_test2_61,
|
||||
0x0101010101010101, 0xcc083f1e6d9e85f6, 0x0000000000000008 );
|
||||
DES_TEST ( des_test2_62,
|
||||
0x0101010101010101, 0xd2fd8867d50d2dfe, 0x0000000000000004 );
|
||||
DES_TEST ( des_test2_63,
|
||||
0x0101010101010101, 0x06e7ea22ce92708f, 0x0000000000000002 );
|
||||
DES_TEST ( des_test2_64,
|
||||
0x0101010101010101, 0x166b40b44aba4bd6, 0x0000000000000001 );
|
||||
|
||||
/* Test 3: Data permutation tests
|
||||
*
|
||||
* "Set the plaintext to zero and process the 32 keys in PTEST"
|
||||
*
|
||||
* Appendix B, page 32 ("PTEST")
|
||||
*/
|
||||
DES_TEST ( des_test3_1,
|
||||
0x1046913489980131, 0x0000000000000000, 0x88d55e54f54c97b4 );
|
||||
DES_TEST ( des_test3_2,
|
||||
0x1007103489988020, 0x0000000000000000, 0x0c0cc00c83ea48fd );
|
||||
DES_TEST ( des_test3_3,
|
||||
0x10071034c8980120, 0x0000000000000000, 0x83bc8ef3a6570183 );
|
||||
DES_TEST ( des_test3_4,
|
||||
0x1046103489988020, 0x0000000000000000, 0xdf725dcad94ea2e9 );
|
||||
DES_TEST ( des_test3_5,
|
||||
0x1086911519190101, 0x0000000000000000, 0xe652b53b550be8b0 );
|
||||
DES_TEST ( des_test3_6,
|
||||
0x1086911519580101, 0x0000000000000000, 0xaf527120c485cbb0 );
|
||||
DES_TEST ( des_test3_7,
|
||||
0x5107b01519580101, 0x0000000000000000, 0x0f04ce393db926d5 );
|
||||
DES_TEST ( des_test3_8,
|
||||
0x1007b01519190101, 0x0000000000000000, 0xc9f00ffc74079067 );
|
||||
DES_TEST ( des_test3_9,
|
||||
0x3107915498080101, 0x0000000000000000, 0x7cfd82a593252b4e );
|
||||
DES_TEST ( des_test3_10,
|
||||
0x3107919498080101, 0x0000000000000000, 0xcb49a2f9e91363e3 );
|
||||
DES_TEST ( des_test3_11,
|
||||
0x10079115b9080140, 0x0000000000000000, 0x00b588be70d23f56 );
|
||||
DES_TEST ( des_test3_12,
|
||||
0x3107911598080140, 0x0000000000000000, 0x406a9a6ab43399ae );
|
||||
DES_TEST ( des_test3_13,
|
||||
0x1007d01589980101, 0x0000000000000000, 0x6cb773611dca9ada );
|
||||
DES_TEST ( des_test3_14,
|
||||
0x9107911589980101, 0x0000000000000000, 0x67fd21c17dbb5d70 );
|
||||
DES_TEST ( des_test3_15,
|
||||
0x9107d01589190101, 0x0000000000000000, 0x9592cb4110430787 );
|
||||
DES_TEST ( des_test3_16,
|
||||
0x1007d01598980120, 0x0000000000000000, 0xa6b7ff68a318ddd3 );
|
||||
DES_TEST ( des_test3_17,
|
||||
0x1007940498190101, 0x0000000000000000, 0x4d102196c914ca16 );
|
||||
DES_TEST ( des_test3_18,
|
||||
0x0107910491190401, 0x0000000000000000, 0x2dfa9f4573594965 );
|
||||
DES_TEST ( des_test3_19,
|
||||
0x0107910491190101, 0x0000000000000000, 0xb46604816c0e0774 );
|
||||
DES_TEST ( des_test3_20,
|
||||
0x0107940491190401, 0x0000000000000000, 0x6e7e6221a4f34e87 );
|
||||
DES_TEST ( des_test3_21,
|
||||
0x19079210981a0101, 0x0000000000000000, 0xaa85e74643233199 );
|
||||
DES_TEST ( des_test3_22,
|
||||
0x1007911998190801, 0x0000000000000000, 0x2e5a19db4d1962d6 );
|
||||
DES_TEST ( des_test3_23,
|
||||
0x10079119981a0801, 0x0000000000000000, 0x23a866a809d30894 );
|
||||
DES_TEST ( des_test3_24,
|
||||
0x1007921098190101, 0x0000000000000000, 0xd812d961f017d320 );
|
||||
DES_TEST ( des_test3_25,
|
||||
0x100791159819010b, 0x0000000000000000, 0x055605816e58608f );
|
||||
DES_TEST ( des_test3_26,
|
||||
0x1004801598190101, 0x0000000000000000, 0xabd88e8b1b7716f1 );
|
||||
DES_TEST ( des_test3_27,
|
||||
0x1004801598190102, 0x0000000000000000, 0x537ac95be69da1e1 );
|
||||
DES_TEST ( des_test3_28,
|
||||
0x1004801598190108, 0x0000000000000000, 0xaed0f6ae3c25cdd8 );
|
||||
DES_TEST ( des_test3_29,
|
||||
0x1002911498100104, 0x0000000000000000, 0xb3e35a5ee53e7b8d );
|
||||
DES_TEST ( des_test3_30,
|
||||
0x1002911598190104, 0x0000000000000000, 0x61c79c71921a2ef8 );
|
||||
DES_TEST ( des_test3_31,
|
||||
0x1002911598100201, 0x0000000000000000, 0xe2f5728f0995013c );
|
||||
DES_TEST ( des_test3_32,
|
||||
0x1002911698100101, 0x0000000000000000, 0x1aeac39a61f0a464 );
|
||||
|
||||
/* Test 4: Key permutation tests
|
||||
*
|
||||
* "Set Data=0 and use the keys e[i]: i=1,...,64 ignoring i=8,16,...,64"
|
||||
*
|
||||
* Test 4 part 1 is the forward direction as described above. Test 4
|
||||
* part 2 ("set data=c[i] from part 1 ... then decipher") is carried
|
||||
* out for us automatically, since CIPHER_TEST() performs both
|
||||
* encryption and decryption tests.
|
||||
*
|
||||
* Appendix B, page 30 ("PC1 and PC2 test")
|
||||
*/
|
||||
DES_TEST ( des_test4_1,
|
||||
0x8001010101010101, 0x0000000000000000, 0x95a8d72813daa94d );
|
||||
DES_TEST ( des_test4_2,
|
||||
0x4001010101010101, 0x0000000000000000, 0x0eec1487dd8c26d5 );
|
||||
DES_TEST ( des_test4_3,
|
||||
0x2001010101010101, 0x0000000000000000, 0x7ad16ffb79c45926 );
|
||||
DES_TEST ( des_test4_4,
|
||||
0x1001010101010101, 0x0000000000000000, 0xd3746294ca6a6cf3 );
|
||||
DES_TEST ( des_test4_5,
|
||||
0x0801010101010101, 0x0000000000000000, 0x809f5f873c1fd761 );
|
||||
DES_TEST ( des_test4_6,
|
||||
0x0401010101010101, 0x0000000000000000, 0xc02faffec989d1fc );
|
||||
DES_TEST ( des_test4_7,
|
||||
0x0201010101010101, 0x0000000000000000, 0x4615aa1d33e72f10 );
|
||||
DES_TEST ( des_test4_8,
|
||||
0x0180010101010101, 0x0000000000000000, 0x2055123350c00858 );
|
||||
DES_TEST ( des_test4_9,
|
||||
0x0140010101010101, 0x0000000000000000, 0xdf3b99d6577397c8 );
|
||||
DES_TEST ( des_test4_10,
|
||||
0x0120010101010101, 0x0000000000000000, 0x31fe17369b5288c9 );
|
||||
DES_TEST ( des_test4_11,
|
||||
0x0110010101010101, 0x0000000000000000, 0xdfdd3cc64dae1642 );
|
||||
DES_TEST ( des_test4_12,
|
||||
0x0108010101010101, 0x0000000000000000, 0x178c83ce2b399d94 );
|
||||
DES_TEST ( des_test4_13,
|
||||
0x0104010101010101, 0x0000000000000000, 0x50f636324a9b7f80 );
|
||||
DES_TEST ( des_test4_14,
|
||||
0x0102010101010101, 0x0000000000000000, 0xa8468ee3bc18f06d );
|
||||
DES_TEST ( des_test4_15,
|
||||
0x0101800101010101, 0x0000000000000000, 0xa2dc9e92fd3cde92 );
|
||||
DES_TEST ( des_test4_16,
|
||||
0x0101400101010101, 0x0000000000000000, 0xcac09f797d031287 );
|
||||
DES_TEST ( des_test4_17,
|
||||
0x0101200101010101, 0x0000000000000000, 0x90ba680b22aeb525 );
|
||||
DES_TEST ( des_test4_18,
|
||||
0x0101100101010101, 0x0000000000000000, 0xce7a24f350e280b6 );
|
||||
DES_TEST ( des_test4_19,
|
||||
0x0101080101010101, 0x0000000000000000, 0x882bff0aa01a0b87 );
|
||||
DES_TEST ( des_test4_20,
|
||||
0x0101040101010101, 0x0000000000000000, 0x25610288924511c2 );
|
||||
DES_TEST ( des_test4_21,
|
||||
0x0101020101010101, 0x0000000000000000, 0xc71516c29c75d170 );
|
||||
DES_TEST ( des_test4_22,
|
||||
0x0101018001010101, 0x0000000000000000, 0x5199c29a52c9f059 );
|
||||
DES_TEST ( des_test4_23,
|
||||
0x0101014001010101, 0x0000000000000000, 0xc22f0a294a71f29f );
|
||||
DES_TEST ( des_test4_24,
|
||||
0x0101012001010101, 0x0000000000000000, 0xee371483714c02ea );
|
||||
DES_TEST ( des_test4_25,
|
||||
0x0101011001010101, 0x0000000000000000, 0xa81fbd448f9e522f );
|
||||
DES_TEST ( des_test4_26,
|
||||
0x0101010801010101, 0x0000000000000000, 0x4f644c92e192dfed );
|
||||
DES_TEST ( des_test4_27,
|
||||
0x0101010401010101, 0x0000000000000000, 0x1afa9a66a6df92ae );
|
||||
DES_TEST ( des_test4_28,
|
||||
0x0101010201010101, 0x0000000000000000, 0xb3c1cc715cb879d8 );
|
||||
DES_TEST ( des_test4_29,
|
||||
0x0101010180010101, 0x0000000000000000, 0x19d032e64ab0bd8b );
|
||||
DES_TEST ( des_test4_30,
|
||||
0x0101010140010101, 0x0000000000000000, 0x3cfaa7a7dc8720dc );
|
||||
DES_TEST ( des_test4_31,
|
||||
0x0101010120010101, 0x0000000000000000, 0xb7265f7f447ac6f3 );
|
||||
DES_TEST ( des_test4_32,
|
||||
0x0101010110010101, 0x0000000000000000, 0x9db73b3c0d163f54 );
|
||||
DES_TEST ( des_test4_33,
|
||||
0x0101010108010101, 0x0000000000000000, 0x8181b65babf4a975 );
|
||||
DES_TEST ( des_test4_34,
|
||||
0x0101010104010101, 0x0000000000000000, 0x93c9b64042eaa240 );
|
||||
DES_TEST ( des_test4_35,
|
||||
0x0101010102010101, 0x0000000000000000, 0x5570530829705592 );
|
||||
DES_TEST ( des_test4_36,
|
||||
0x0101010101800101, 0x0000000000000000, 0x8638809e878787a0 );
|
||||
DES_TEST ( des_test4_37,
|
||||
0x0101010101400101, 0x0000000000000000, 0x41b9a79af79ac208 );
|
||||
DES_TEST ( des_test4_38,
|
||||
0x0101010101200101, 0x0000000000000000, 0x7a9be42f2009a892 );
|
||||
DES_TEST ( des_test4_39,
|
||||
0x0101010101100101, 0x0000000000000000, 0x29038d56ba6d2745 );
|
||||
DES_TEST ( des_test4_40,
|
||||
0x0101010101080101, 0x0000000000000000, 0x5495c6abf1e5df51 );
|
||||
DES_TEST ( des_test4_41,
|
||||
0x0101010101040101, 0x0000000000000000, 0xae13dbd561488933 );
|
||||
DES_TEST ( des_test4_42,
|
||||
0x0101010101020101, 0x0000000000000000, 0x024d1ffa8904e389 );
|
||||
DES_TEST ( des_test4_43,
|
||||
0x0101010101018001, 0x0000000000000000, 0xd1399712f99bf02e );
|
||||
DES_TEST ( des_test4_44,
|
||||
0x0101010101014001, 0x0000000000000000, 0x14c1d7c1cffec79e );
|
||||
DES_TEST ( des_test4_45,
|
||||
0x0101010101012001, 0x0000000000000000, 0x1de5279dae3bed6f );
|
||||
DES_TEST ( des_test4_46,
|
||||
0x0101010101011001, 0x0000000000000000, 0xe941a33f85501303 );
|
||||
DES_TEST ( des_test4_47,
|
||||
0x0101010101010801, 0x0000000000000000, 0xda99dbbc9a03f379 );
|
||||
DES_TEST ( des_test4_48,
|
||||
0x0101010101010401, 0x0000000000000000, 0xb7fc92f91d8e92e9 );
|
||||
DES_TEST ( des_test4_49,
|
||||
0x0101010101010201, 0x0000000000000000, 0xae8e5caa3ca04e85 );
|
||||
DES_TEST ( des_test4_50,
|
||||
0x0101010101010180, 0x0000000000000000, 0x9cc62df43b6eed74 );
|
||||
DES_TEST ( des_test4_51,
|
||||
0x0101010101010140, 0x0000000000000000, 0xd863dbb5c59a91a0 );
|
||||
DES_TEST ( des_test4_52,
|
||||
0x0101010101010120, 0x0000000000000000, 0xa1ab2190545b91d7 );
|
||||
DES_TEST ( des_test4_53,
|
||||
0x0101010101010110, 0x0000000000000000, 0x0875041e64c570f7 );
|
||||
DES_TEST ( des_test4_54,
|
||||
0x0101010101010108, 0x0000000000000000, 0x5a594528bebef1cc );
|
||||
DES_TEST ( des_test4_55,
|
||||
0x0101010101010104, 0x0000000000000000, 0xfcdb3291de21f0c0 );
|
||||
DES_TEST ( des_test4_56,
|
||||
0x0101010101010102, 0x0000000000000000, 0x869efd7f9f265a09 );
|
||||
|
||||
/* Test 5: S-box tests
|
||||
*
|
||||
* "Set Data and Key equal to the inputs defined in the Substitution
|
||||
* Table test"
|
||||
*
|
||||
* Appendix B, page 33 ("19 key data pairs which exercise every S-box entry")
|
||||
*/
|
||||
DES_TEST ( des_test5_1,
|
||||
0x7ca110454a1a6e57, 0x01a1d6d039776742, 0x690f5b0d9a26939b );
|
||||
DES_TEST ( des_test5_2,
|
||||
0x0131d9619dc1376e, 0x5cd54ca83def57da, 0x7a389d10354bd271 );
|
||||
DES_TEST ( des_test5_3,
|
||||
0x07a1133e4a0b2686, 0x0248d43806f67172, 0x868ebb51cab4599a );
|
||||
DES_TEST ( des_test5_4,
|
||||
0x3849674c2602319e, 0x51454b582ddf440a, 0x7178876e01f19b2a );
|
||||
DES_TEST ( des_test5_5,
|
||||
0x04b915ba43feb5b6, 0x42fd443059577fa2, 0xaf37fb421f8c4095 );
|
||||
DES_TEST ( des_test5_6,
|
||||
0x0113b970fd34f2ce, 0x059b5e0851cf143a, 0x86a560f10ec6d85b );
|
||||
DES_TEST ( des_test5_7,
|
||||
0x0170f175468fb5e6, 0x0756d8e0774761d2, 0x0cd3da020021dc09 );
|
||||
DES_TEST ( des_test5_8,
|
||||
0x43297fad38e373fe, 0x762514b829bf486a, 0xea676b2cb7db2b7a );
|
||||
DES_TEST ( des_test5_9,
|
||||
0x07a7137045da2a16, 0x3bdd119049372802, 0xdfd64a815caf1a0f );
|
||||
DES_TEST ( des_test5_10,
|
||||
0x04689104c2fd3b2f, 0x26955f6835af609a, 0x5c513c9c4886c088 );
|
||||
DES_TEST ( des_test5_11,
|
||||
0x37d06bb516cb7546, 0x164d5e404f275232, 0x0a2aeeae3ff4ab77 );
|
||||
DES_TEST ( des_test5_12,
|
||||
0x1f08260d1ac2465e, 0x6b056e18759f5cca, 0xef1bf03e5dfa575a );
|
||||
DES_TEST ( des_test5_13,
|
||||
0x584023641aba6176, 0x004bd6ef09176062, 0x88bf0db6d70dee56 );
|
||||
DES_TEST ( des_test5_14,
|
||||
0x025816164629b007, 0x480d39006ee762f2, 0xa1f9915541020b56 );
|
||||
DES_TEST ( des_test5_15,
|
||||
0x49793ebc79b3258f, 0x437540c8698f3cfa, 0x6fbf1cafcffd0556 );
|
||||
DES_TEST ( des_test5_16,
|
||||
0x4fb05e1515ab73a7, 0x072d43a077075292, 0x2f22e49bab7ca1ac );
|
||||
DES_TEST ( des_test5_17,
|
||||
0x49e95d6d4ca229bf, 0x02fe55778117f12a, 0x5a6b612cc26cce4a );
|
||||
DES_TEST ( des_test5_18,
|
||||
0x018310dc409b26d6, 0x1d9d5c5018f728c2, 0x5f4c038ed12b2e41 );
|
||||
DES_TEST ( des_test5_19,
|
||||
0x1c587f1c13924fef, 0x305532286d6f295a, 0x63fac0d034d9f793 );
|
||||
|
||||
/* Unofficial tests
|
||||
*
|
||||
* The official tests are all exactly one block in length. Add some
|
||||
* multi-block tests (generated in Python).
|
||||
*/
|
||||
CIPHER_TEST ( des_unofficial_ecb, &des_ecb_algorithm,
|
||||
KEY ( 0x6e, 0x6f, 0x70, 0x61, 0x72, 0x69, 0x74, 0x79 ),
|
||||
IV(), ADDITIONAL(),
|
||||
PLAINTEXT ( 0x53, 0x6f, 0x20, 0x63, 0x75, 0x74, 0x65, 0x20,
|
||||
0x74, 0x6f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x61,
|
||||
0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,
|
||||
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77,
|
||||
0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x6f,
|
||||
0x6e, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x63, 0x74,
|
||||
0x75, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65,
|
||||
0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x21, 0x21 ),
|
||||
CIPHERTEXT ( 0x1a, 0x02, 0x17, 0xcb, 0x93, 0xa3, 0xd2, 0xf2,
|
||||
0xf9, 0x45, 0x71, 0x1c, 0x33, 0xb1, 0x5c, 0xa4,
|
||||
0x8b, 0x6b, 0x11, 0x7a, 0x7c, 0x86, 0x7c, 0x7f,
|
||||
0x9f, 0x56, 0x61, 0x46, 0x7f, 0xa6, 0xae, 0xf1,
|
||||
0x49, 0xf7, 0x53, 0xe0, 0xbc, 0x15, 0x6a, 0x30,
|
||||
0xe7, 0xf8, 0xf3, 0x29, 0x11, 0xd8, 0x7d, 0x04,
|
||||
0x62, 0x5a, 0xaa, 0xa1, 0x89, 0x61, 0x4c, 0xf6,
|
||||
0x5a, 0x47, 0x3b, 0xc6, 0x04, 0x15, 0xce, 0xf6 ),
|
||||
AUTH() );
|
||||
CIPHER_TEST ( des_unofficial_cbc, &des_cbc_algorithm,
|
||||
KEY ( 0x6e, 0x6f, 0x70, 0x61, 0x72, 0x69, 0x74, 0x79 ),
|
||||
IV ( 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 ),
|
||||
ADDITIONAL(),
|
||||
PLAINTEXT ( 0x53, 0x6f, 0x20, 0x63, 0x75, 0x74, 0x65, 0x20,
|
||||
0x74, 0x6f, 0x20, 0x73, 0x65, 0x65, 0x20, 0x61,
|
||||
0x20, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69,
|
||||
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x77,
|
||||
0x72, 0x69, 0x74, 0x74, 0x65, 0x6e, 0x20, 0x6f,
|
||||
0x6e, 0x20, 0x61, 0x6e, 0x20, 0x61, 0x63, 0x74,
|
||||
0x75, 0x61, 0x6c, 0x20, 0x74, 0x79, 0x70, 0x65,
|
||||
0x77, 0x72, 0x69, 0x74, 0x65, 0x72, 0x21, 0x21 ),
|
||||
CIPHERTEXT ( 0x4c, 0x5f, 0x62, 0xfc, 0xf4, 0x93, 0x09, 0xb5,
|
||||
0x1d, 0x52, 0x25, 0xec, 0xc7, 0x42, 0x3c, 0x29,
|
||||
0x33, 0x67, 0xf5, 0xe9, 0xd6, 0x3c, 0x27, 0x5b,
|
||||
0x49, 0x69, 0xc5, 0xa9, 0x08, 0xa3, 0x14, 0x66,
|
||||
0x3c, 0x95, 0x33, 0x30, 0xcf, 0x3c, 0x7c, 0xaf,
|
||||
0xa3, 0xe4, 0xf8, 0x2e, 0xc3, 0x55, 0x57, 0x81,
|
||||
0x33, 0xd9, 0x90, 0xe2, 0x99, 0xdc, 0x32, 0x10,
|
||||
0x13, 0x21, 0xb6, 0xc1, 0x6b, 0x0f, 0x22, 0xa9 ),
|
||||
AUTH() );
|
||||
|
||||
/**
|
||||
* Perform DES self-test
|
||||
*
|
||||
*/
|
||||
static void des_test_exec ( void ) {
|
||||
|
||||
/* Sample round outputs (page 9) */
|
||||
cipher_ok ( &des_round_sample );
|
||||
|
||||
/* Test 1: Initial permutation and expansion tests */
|
||||
cipher_ok ( &des_test1_1 );
|
||||
cipher_ok ( &des_test1_2 );
|
||||
cipher_ok ( &des_test1_3 );
|
||||
cipher_ok ( &des_test1_4 );
|
||||
cipher_ok ( &des_test1_5 );
|
||||
cipher_ok ( &des_test1_6 );
|
||||
cipher_ok ( &des_test1_7 );
|
||||
cipher_ok ( &des_test1_8 );
|
||||
cipher_ok ( &des_test1_9 );
|
||||
cipher_ok ( &des_test1_10 );
|
||||
cipher_ok ( &des_test1_11 );
|
||||
cipher_ok ( &des_test1_12 );
|
||||
cipher_ok ( &des_test1_13 );
|
||||
cipher_ok ( &des_test1_14 );
|
||||
cipher_ok ( &des_test1_15 );
|
||||
cipher_ok ( &des_test1_16 );
|
||||
cipher_ok ( &des_test1_17 );
|
||||
cipher_ok ( &des_test1_18 );
|
||||
cipher_ok ( &des_test1_19 );
|
||||
cipher_ok ( &des_test1_20 );
|
||||
cipher_ok ( &des_test1_21 );
|
||||
cipher_ok ( &des_test1_22 );
|
||||
cipher_ok ( &des_test1_23 );
|
||||
cipher_ok ( &des_test1_24 );
|
||||
cipher_ok ( &des_test1_25 );
|
||||
cipher_ok ( &des_test1_26 );
|
||||
cipher_ok ( &des_test1_27 );
|
||||
cipher_ok ( &des_test1_28 );
|
||||
cipher_ok ( &des_test1_29 );
|
||||
cipher_ok ( &des_test1_30 );
|
||||
cipher_ok ( &des_test1_31 );
|
||||
cipher_ok ( &des_test1_32 );
|
||||
cipher_ok ( &des_test1_33 );
|
||||
cipher_ok ( &des_test1_34 );
|
||||
cipher_ok ( &des_test1_35 );
|
||||
cipher_ok ( &des_test1_36 );
|
||||
cipher_ok ( &des_test1_37 );
|
||||
cipher_ok ( &des_test1_38 );
|
||||
cipher_ok ( &des_test1_39 );
|
||||
cipher_ok ( &des_test1_40 );
|
||||
cipher_ok ( &des_test1_41 );
|
||||
cipher_ok ( &des_test1_42 );
|
||||
cipher_ok ( &des_test1_43 );
|
||||
cipher_ok ( &des_test1_44 );
|
||||
cipher_ok ( &des_test1_45 );
|
||||
cipher_ok ( &des_test1_46 );
|
||||
cipher_ok ( &des_test1_47 );
|
||||
cipher_ok ( &des_test1_48 );
|
||||
cipher_ok ( &des_test1_49 );
|
||||
cipher_ok ( &des_test1_50 );
|
||||
cipher_ok ( &des_test1_51 );
|
||||
cipher_ok ( &des_test1_52 );
|
||||
cipher_ok ( &des_test1_53 );
|
||||
cipher_ok ( &des_test1_54 );
|
||||
cipher_ok ( &des_test1_55 );
|
||||
cipher_ok ( &des_test1_56 );
|
||||
cipher_ok ( &des_test1_57 );
|
||||
cipher_ok ( &des_test1_58 );
|
||||
cipher_ok ( &des_test1_59 );
|
||||
cipher_ok ( &des_test1_60 );
|
||||
cipher_ok ( &des_test1_61 );
|
||||
cipher_ok ( &des_test1_62 );
|
||||
cipher_ok ( &des_test1_63 );
|
||||
cipher_ok ( &des_test1_64 );
|
||||
|
||||
/* Test 2: Inverse permutation and expansion tests */
|
||||
cipher_ok ( &des_test2_1 );
|
||||
cipher_ok ( &des_test2_2 );
|
||||
cipher_ok ( &des_test2_3 );
|
||||
cipher_ok ( &des_test2_4 );
|
||||
cipher_ok ( &des_test2_5 );
|
||||
cipher_ok ( &des_test2_6 );
|
||||
cipher_ok ( &des_test2_7 );
|
||||
cipher_ok ( &des_test2_8 );
|
||||
cipher_ok ( &des_test2_9 );
|
||||
cipher_ok ( &des_test2_10 );
|
||||
cipher_ok ( &des_test2_11 );
|
||||
cipher_ok ( &des_test2_12 );
|
||||
cipher_ok ( &des_test2_13 );
|
||||
cipher_ok ( &des_test2_14 );
|
||||
cipher_ok ( &des_test2_15 );
|
||||
cipher_ok ( &des_test2_16 );
|
||||
cipher_ok ( &des_test2_17 );
|
||||
cipher_ok ( &des_test2_18 );
|
||||
cipher_ok ( &des_test2_19 );
|
||||
cipher_ok ( &des_test2_20 );
|
||||
cipher_ok ( &des_test2_21 );
|
||||
cipher_ok ( &des_test2_22 );
|
||||
cipher_ok ( &des_test2_23 );
|
||||
cipher_ok ( &des_test2_24 );
|
||||
cipher_ok ( &des_test2_25 );
|
||||
cipher_ok ( &des_test2_26 );
|
||||
cipher_ok ( &des_test2_27 );
|
||||
cipher_ok ( &des_test2_28 );
|
||||
cipher_ok ( &des_test2_29 );
|
||||
cipher_ok ( &des_test2_30 );
|
||||
cipher_ok ( &des_test2_31 );
|
||||
cipher_ok ( &des_test2_32 );
|
||||
cipher_ok ( &des_test2_33 );
|
||||
cipher_ok ( &des_test2_34 );
|
||||
cipher_ok ( &des_test2_35 );
|
||||
cipher_ok ( &des_test2_36 );
|
||||
cipher_ok ( &des_test2_37 );
|
||||
cipher_ok ( &des_test2_38 );
|
||||
cipher_ok ( &des_test2_39 );
|
||||
cipher_ok ( &des_test2_40 );
|
||||
cipher_ok ( &des_test2_41 );
|
||||
cipher_ok ( &des_test2_42 );
|
||||
cipher_ok ( &des_test2_43 );
|
||||
cipher_ok ( &des_test2_44 );
|
||||
cipher_ok ( &des_test2_45 );
|
||||
cipher_ok ( &des_test2_46 );
|
||||
cipher_ok ( &des_test2_47 );
|
||||
cipher_ok ( &des_test2_48 );
|
||||
cipher_ok ( &des_test2_49 );
|
||||
cipher_ok ( &des_test2_50 );
|
||||
cipher_ok ( &des_test2_51 );
|
||||
cipher_ok ( &des_test2_52 );
|
||||
cipher_ok ( &des_test2_53 );
|
||||
cipher_ok ( &des_test2_54 );
|
||||
cipher_ok ( &des_test2_55 );
|
||||
cipher_ok ( &des_test2_56 );
|
||||
cipher_ok ( &des_test2_57 );
|
||||
cipher_ok ( &des_test2_58 );
|
||||
cipher_ok ( &des_test2_59 );
|
||||
cipher_ok ( &des_test2_60 );
|
||||
cipher_ok ( &des_test2_61 );
|
||||
cipher_ok ( &des_test2_62 );
|
||||
cipher_ok ( &des_test2_63 );
|
||||
cipher_ok ( &des_test2_64 );
|
||||
|
||||
/* Test 3: Data permutation tests */
|
||||
cipher_ok ( &des_test3_1 );
|
||||
cipher_ok ( &des_test3_2 );
|
||||
cipher_ok ( &des_test3_3 );
|
||||
cipher_ok ( &des_test3_4 );
|
||||
cipher_ok ( &des_test3_5 );
|
||||
cipher_ok ( &des_test3_6 );
|
||||
cipher_ok ( &des_test3_7 );
|
||||
cipher_ok ( &des_test3_8 );
|
||||
cipher_ok ( &des_test3_9 );
|
||||
cipher_ok ( &des_test3_10 );
|
||||
cipher_ok ( &des_test3_11 );
|
||||
cipher_ok ( &des_test3_12 );
|
||||
cipher_ok ( &des_test3_13 );
|
||||
cipher_ok ( &des_test3_14 );
|
||||
cipher_ok ( &des_test3_15 );
|
||||
cipher_ok ( &des_test3_16 );
|
||||
cipher_ok ( &des_test3_17 );
|
||||
cipher_ok ( &des_test3_18 );
|
||||
cipher_ok ( &des_test3_19 );
|
||||
cipher_ok ( &des_test3_20 );
|
||||
cipher_ok ( &des_test3_21 );
|
||||
cipher_ok ( &des_test3_22 );
|
||||
cipher_ok ( &des_test3_23 );
|
||||
cipher_ok ( &des_test3_24 );
|
||||
cipher_ok ( &des_test3_25 );
|
||||
cipher_ok ( &des_test3_26 );
|
||||
cipher_ok ( &des_test3_27 );
|
||||
cipher_ok ( &des_test3_28 );
|
||||
cipher_ok ( &des_test3_29 );
|
||||
cipher_ok ( &des_test3_30 );
|
||||
cipher_ok ( &des_test3_31 );
|
||||
cipher_ok ( &des_test3_32 );
|
||||
|
||||
/* Test 4: Key permutation tests */
|
||||
cipher_ok ( &des_test4_1 );
|
||||
cipher_ok ( &des_test4_2 );
|
||||
cipher_ok ( &des_test4_3 );
|
||||
cipher_ok ( &des_test4_4 );
|
||||
cipher_ok ( &des_test4_5 );
|
||||
cipher_ok ( &des_test4_6 );
|
||||
cipher_ok ( &des_test4_7 );
|
||||
cipher_ok ( &des_test4_8 );
|
||||
cipher_ok ( &des_test4_9 );
|
||||
cipher_ok ( &des_test4_10 );
|
||||
cipher_ok ( &des_test4_11 );
|
||||
cipher_ok ( &des_test4_12 );
|
||||
cipher_ok ( &des_test4_13 );
|
||||
cipher_ok ( &des_test4_14 );
|
||||
cipher_ok ( &des_test4_15 );
|
||||
cipher_ok ( &des_test4_16 );
|
||||
cipher_ok ( &des_test4_17 );
|
||||
cipher_ok ( &des_test4_18 );
|
||||
cipher_ok ( &des_test4_19 );
|
||||
cipher_ok ( &des_test4_20 );
|
||||
cipher_ok ( &des_test4_21 );
|
||||
cipher_ok ( &des_test4_22 );
|
||||
cipher_ok ( &des_test4_23 );
|
||||
cipher_ok ( &des_test4_24 );
|
||||
cipher_ok ( &des_test4_25 );
|
||||
cipher_ok ( &des_test4_26 );
|
||||
cipher_ok ( &des_test4_27 );
|
||||
cipher_ok ( &des_test4_28 );
|
||||
cipher_ok ( &des_test4_29 );
|
||||
cipher_ok ( &des_test4_30 );
|
||||
cipher_ok ( &des_test4_31 );
|
||||
cipher_ok ( &des_test4_32 );
|
||||
cipher_ok ( &des_test4_33 );
|
||||
cipher_ok ( &des_test4_34 );
|
||||
cipher_ok ( &des_test4_35 );
|
||||
cipher_ok ( &des_test4_36 );
|
||||
cipher_ok ( &des_test4_37 );
|
||||
cipher_ok ( &des_test4_38 );
|
||||
cipher_ok ( &des_test4_39 );
|
||||
cipher_ok ( &des_test4_40 );
|
||||
cipher_ok ( &des_test4_41 );
|
||||
cipher_ok ( &des_test4_42 );
|
||||
cipher_ok ( &des_test4_43 );
|
||||
cipher_ok ( &des_test4_44 );
|
||||
cipher_ok ( &des_test4_45 );
|
||||
cipher_ok ( &des_test4_46 );
|
||||
cipher_ok ( &des_test4_47 );
|
||||
cipher_ok ( &des_test4_48 );
|
||||
cipher_ok ( &des_test4_49 );
|
||||
cipher_ok ( &des_test4_50 );
|
||||
cipher_ok ( &des_test4_51 );
|
||||
cipher_ok ( &des_test4_52 );
|
||||
cipher_ok ( &des_test4_53 );
|
||||
cipher_ok ( &des_test4_54 );
|
||||
cipher_ok ( &des_test4_55 );
|
||||
cipher_ok ( &des_test4_56 );
|
||||
|
||||
/* Test 5: S-box tests */
|
||||
cipher_ok ( &des_test5_1 );
|
||||
cipher_ok ( &des_test5_2 );
|
||||
cipher_ok ( &des_test5_3 );
|
||||
cipher_ok ( &des_test5_4 );
|
||||
cipher_ok ( &des_test5_5 );
|
||||
cipher_ok ( &des_test5_6 );
|
||||
cipher_ok ( &des_test5_7 );
|
||||
cipher_ok ( &des_test5_8 );
|
||||
cipher_ok ( &des_test5_9 );
|
||||
cipher_ok ( &des_test5_10 );
|
||||
cipher_ok ( &des_test5_11 );
|
||||
cipher_ok ( &des_test5_12 );
|
||||
cipher_ok ( &des_test5_13 );
|
||||
cipher_ok ( &des_test5_14 );
|
||||
cipher_ok ( &des_test5_15 );
|
||||
cipher_ok ( &des_test5_16 );
|
||||
cipher_ok ( &des_test5_17 );
|
||||
cipher_ok ( &des_test5_18 );
|
||||
cipher_ok ( &des_test5_19 );
|
||||
|
||||
/* Multi-block tests */
|
||||
cipher_ok ( &des_unofficial_ecb );
|
||||
cipher_ok ( &des_unofficial_cbc );
|
||||
|
||||
/* Speed tests */
|
||||
DBG ( "DES-ECB encryption required %ld cycles per byte\n",
|
||||
cipher_cost_encrypt ( &des_ecb_algorithm, 8 ) );
|
||||
DBG ( "DES-ECB decryption required %ld cycles per byte\n",
|
||||
cipher_cost_decrypt ( &des_ecb_algorithm, 8 ) );
|
||||
DBG ( "DES-CBC encryption required %ld cycles per byte\n",
|
||||
cipher_cost_encrypt ( &des_cbc_algorithm, 8 ) );
|
||||
DBG ( "DES-CBC decryption required %ld cycles per byte\n",
|
||||
cipher_cost_decrypt ( &des_cbc_algorithm, 8 ) );
|
||||
}
|
||||
|
||||
/** DES self-test */
|
||||
struct self_test des_test __self_test = {
|
||||
.name = "des",
|
||||
.exec = des_test_exec,
|
||||
};
|
||||
@ -27,7 +27,8 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
||||
*
|
||||
* X25519 key exchange test
|
||||
*
|
||||
* Full key exchange test vectors are taken from RFC 7748.
|
||||
* Full key exchange test vectors are taken from RFC7748.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Forcibly enable assertions */
|
||||
@ -135,6 +136,8 @@ struct x25519_key_test {
|
||||
struct x25519_value expected;
|
||||
/** Number of iterations */
|
||||
unsigned int count;
|
||||
/** Key exchange is expected to fail (i.e. produce all-zeroes) */
|
||||
int fail;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -142,14 +145,16 @@ struct x25519_key_test {
|
||||
*
|
||||
* @v name Test name
|
||||
* @v COUNT Number of iterations
|
||||
* @v FAIL Expected failure status
|
||||
* @v BASE Base point
|
||||
* @v SCALAR Scalar multiple
|
||||
* @v EXPECTED Expected result
|
||||
* @ret test X25519 key exchange test
|
||||
*/
|
||||
#define X25519_KEY_TEST( name, COUNT, BASE, SCALAR, EXPECTED ) \
|
||||
#define X25519_KEY_TEST( name, COUNT, FAIL, BASE, SCALAR, EXPECTED ) \
|
||||
static struct x25519_key_test name = { \
|
||||
.count = COUNT, \
|
||||
.fail = FAIL, \
|
||||
.base = { .raw = BASE }, \
|
||||
.scalar = { .raw = SCALAR }, \
|
||||
.expected = { .raw = EXPECTED }, \
|
||||
@ -258,6 +263,7 @@ static void x25519_key_okx ( struct x25519_key_test *test,
|
||||
struct x25519_value scalar;
|
||||
struct x25519_value actual;
|
||||
unsigned int i;
|
||||
int rc;
|
||||
|
||||
/* Construct input values */
|
||||
memcpy ( &base, &test->base, sizeof ( test->base ) );
|
||||
@ -271,7 +277,12 @@ static void x25519_key_okx ( struct x25519_key_test *test,
|
||||
|
||||
/* Calculate key */
|
||||
for ( i = 0 ; i < test->count ; i++ ) {
|
||||
x25519_key ( &base, &scalar, &actual );
|
||||
rc = x25519_key ( &base, &scalar, &actual );
|
||||
if ( test->fail ) {
|
||||
okx ( rc != 0, file, line );
|
||||
} else {
|
||||
okx ( rc == 0, file, line );
|
||||
}
|
||||
memcpy ( &base, &scalar, sizeof ( base ) );
|
||||
memcpy ( &scalar, &actual, sizeof ( scalar ) );
|
||||
}
|
||||
@ -460,7 +471,7 @@ X25519_INVERT_TEST ( invert_5,
|
||||
* Scalar: 0xa546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4
|
||||
* Result: 0xc3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552
|
||||
*/
|
||||
X25519_KEY_TEST ( rfc7748_1, 1,
|
||||
X25519_KEY_TEST ( rfc7748_1, 1, 0,
|
||||
BASE ( 0xe6, 0xdb, 0x68, 0x67, 0x58, 0x30, 0x30, 0xdb, 0x35, 0x94,
|
||||
0xc1, 0xa4, 0x24, 0xb1, 0x5f, 0x7c, 0x72, 0x66, 0x24, 0xec,
|
||||
0x26, 0xb3, 0x35, 0x3b, 0x10, 0xa9, 0x03, 0xa6, 0xd0, 0xab,
|
||||
@ -478,7 +489,7 @@ X25519_KEY_TEST ( rfc7748_1, 1,
|
||||
* Scalar: 0x4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d
|
||||
* Result: 0x95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957
|
||||
*/
|
||||
X25519_KEY_TEST ( rfc7748_2, 1,
|
||||
X25519_KEY_TEST ( rfc7748_2, 1, 0,
|
||||
BASE ( 0xe5, 0x21, 0x0f, 0x12, 0x78, 0x68, 0x11, 0xd3, 0xf4, 0xb7,
|
||||
0x95, 0x9d, 0x05, 0x38, 0xae, 0x2c, 0x31, 0xdb, 0xe7, 0x10,
|
||||
0x6f, 0xc0, 0x3c, 0x3e, 0xfc, 0x4c, 0xd5, 0x49, 0xc7, 0x15,
|
||||
@ -496,7 +507,7 @@ X25519_KEY_TEST ( rfc7748_2, 1,
|
||||
* Scalar: 0x0900000000000000000000000000000000000000000000000000000000000000
|
||||
* Result: 0x422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079
|
||||
*/
|
||||
X25519_KEY_TEST ( rfc7748_3, 1,
|
||||
X25519_KEY_TEST ( rfc7748_3, 1, 0,
|
||||
BASE ( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@ -515,12 +526,12 @@ X25519_KEY_TEST ( rfc7748_3, 1,
|
||||
* Result: 0xb1a5a73158904c020866c13939dd7e1aa26852ee1d2609c92e5a8f1debe2150a
|
||||
* (after 100 iterations)
|
||||
*
|
||||
* RFC 7748 gives test vectors for 1000 and 1000000 iterations with
|
||||
* RFC7748 gives test vectors for 1000 and 1000000 iterations with
|
||||
* these starting values. This test case stops after 100 iterations
|
||||
* to avoid a pointlessly slow test cycle in the common case of
|
||||
* running tests under Valgrind.
|
||||
*/
|
||||
X25519_KEY_TEST ( rfc7748_4_100, 100,
|
||||
X25519_KEY_TEST ( rfc7748_4_100, 100, 0,
|
||||
BASE ( 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@ -534,6 +545,24 @@ X25519_KEY_TEST ( rfc7748_4_100, 100,
|
||||
0x1d, 0x26, 0x09, 0xc9, 0x2e, 0x5a, 0x8f, 0x1d, 0xeb, 0xe2,
|
||||
0x15, 0x0a ) );
|
||||
|
||||
/* Base: 2^255 - 19 + 1 (deliberately malicious public key)
|
||||
* Scalar: 0x000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f
|
||||
* Result: Failure (all zeros)
|
||||
*/
|
||||
X25519_KEY_TEST ( malicious, 1, 1,
|
||||
BASE ( 0xee, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x7f ),
|
||||
SCALAR ( 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
|
||||
0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, 0x01, 0x02, 0x03,
|
||||
0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
|
||||
0x0e, 0x0f ),
|
||||
EXPECTED ( 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00 ) );
|
||||
|
||||
/**
|
||||
* Perform X25519 self-tests
|
||||
*
|
||||
@ -561,6 +590,7 @@ static void x25519_test_exec ( void ) {
|
||||
x25519_key_ok ( &rfc7748_2 );
|
||||
x25519_key_ok ( &rfc7748_3 );
|
||||
x25519_key_ok ( &rfc7748_4_100 );
|
||||
x25519_key_ok ( &malicious );
|
||||
}
|
||||
|
||||
/** X25519 self-test */
|
||||
|
||||
Reference in New Issue
Block a user