mirror of
https://github.com/ipxe/ipxe
synced 2026-06-29 00:07:28 +03:00
[crypto] Allocate FFDHE temporary space on demand
Now that key exchange algorithms are allowed to fail to construct a shared public key, we can allocate the temporary working space for FFDHE calculations on demand rather than using a static buffer. Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
+41
-35
@@ -47,6 +47,7 @@ FILE_SECBOOT ( PERMITTED );
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ipxe/ffdhe.h>
|
#include <ipxe/ffdhe.h>
|
||||||
@@ -165,27 +166,6 @@ static const uint8_t pi[] = {
|
|||||||
0x90, 0xa6, 0xc0, 0x8f, 0x4d, 0xf4, 0x35, 0xc9
|
0x90, 0xa6, 0xc0, 0x8f, 0x4d, 0xf4, 0x35, 0xc9
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Maximum number of elements in big integer values */
|
|
||||||
#define FFDHE_SIZE bigint_required_size ( FFDHE_LEN )
|
|
||||||
|
|
||||||
/** Maximally sized big integer */
|
|
||||||
typedef bigint_t ( FFDHE_SIZE ) ffdhe_t;
|
|
||||||
|
|
||||||
/** Temporary storage */
|
|
||||||
static struct {
|
|
||||||
/** Prime modulus */
|
|
||||||
ffdhe_t modulus;
|
|
||||||
/** Base */
|
|
||||||
ffdhe_t base;
|
|
||||||
/** Result */
|
|
||||||
ffdhe_t result;
|
|
||||||
/** Temporary working space */
|
|
||||||
union {
|
|
||||||
uint8_t mod_exp[ bigint_mod_exp_tmp_len ( (ffdhe_t *) NULL ) ];
|
|
||||||
uint8_t raw[FFDHE_LEN];
|
|
||||||
} tmp;
|
|
||||||
} ffdhe_temp;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculate FFDHE result
|
* Calculate FFDHE result
|
||||||
*
|
*
|
||||||
@@ -201,23 +181,41 @@ static int ffdhe ( struct ffdhe_group *group, const void *public,
|
|||||||
unsigned int size = group->size;
|
unsigned int size = group->size;
|
||||||
size_t explen = group->explen;
|
size_t explen = group->explen;
|
||||||
size_t len = group->len;
|
size_t len = group->len;
|
||||||
ffdhe_modulus_t ( len ) *tmp = ( ( void * ) &ffdhe_temp.tmp );
|
|
||||||
bigint_t ( size ) *modulus = ( ( void * ) &ffdhe_temp.modulus );
|
|
||||||
bigint_t ( size ) *base = ( ( void * ) &ffdhe_temp.base );
|
|
||||||
bigint_t ( size ) *result = ( ( void * ) &ffdhe_temp.result );
|
|
||||||
bigint_t ( expsize ) exponent;
|
bigint_t ( expsize ) exponent;
|
||||||
|
bigint_t ( size ) *modulus;
|
||||||
|
bigint_t ( size ) *base;
|
||||||
|
bigint_t ( size ) *result;
|
||||||
|
ffdhe_modulus_t ( len ) *raw;
|
||||||
|
struct {
|
||||||
|
typeof ( *modulus ) modulus;
|
||||||
|
typeof ( *base ) base;
|
||||||
|
typeof ( *result ) result;
|
||||||
|
uint8_t mod_exp[ bigint_mod_exp_tmp_len ( modulus ) ];
|
||||||
|
} *tmp;
|
||||||
static const uint8_t two[1] = { 2 };
|
static const uint8_t two[1] = { 2 };
|
||||||
|
int rc;
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
static_assert ( sizeof ( euler ) == FFDHE_CONSTANT_LEN );
|
static_assert ( sizeof ( euler ) == FFDHE_CONSTANT_LEN );
|
||||||
static_assert ( sizeof ( pi ) == FFDHE_CONSTANT_LEN );
|
static_assert ( sizeof ( pi ) == FFDHE_CONSTANT_LEN );
|
||||||
|
|
||||||
/* Construct modulus */
|
/* Allocate temporary space */
|
||||||
assert ( sizeof ( *tmp ) == len );
|
tmp = malloc ( sizeof ( *tmp ) );
|
||||||
memset ( tmp, 0xff, sizeof ( *tmp ) );
|
if ( ! tmp ) {
|
||||||
memcpy ( tmp->constant, group->constant, sizeof ( tmp->constant ) );
|
rc = -ENOMEM;
|
||||||
tmp->lsb32 = group->lsb32;
|
goto err_alloc;
|
||||||
bigint_init ( modulus, tmp, len );
|
}
|
||||||
|
modulus = &tmp->modulus;
|
||||||
|
base = &tmp->base;
|
||||||
|
result = &tmp->result;
|
||||||
|
|
||||||
|
/* Construct modulus (using base as temporary buffer) */
|
||||||
|
assert ( sizeof ( *raw ) <= sizeof ( *base ) );
|
||||||
|
raw = ( ( void * ) base );
|
||||||
|
memset ( raw, 0xff, sizeof ( *raw ) );
|
||||||
|
memcpy ( raw->constant, group->constant, sizeof ( raw->constant ) );
|
||||||
|
raw->lsb32 = group->lsb32;
|
||||||
|
bigint_init ( modulus, raw, len );
|
||||||
DBGC ( group, "FFDHE %s mod: %s\n",
|
DBGC ( group, "FFDHE %s mod: %s\n",
|
||||||
group->name, bigint_ntoa ( modulus ) );
|
group->name, bigint_ntoa ( modulus ) );
|
||||||
|
|
||||||
@@ -236,7 +234,7 @@ static int ffdhe ( struct ffdhe_group *group, const void *public,
|
|||||||
group->name, bigint_ntoa ( &exponent ) );
|
group->name, bigint_ntoa ( &exponent ) );
|
||||||
|
|
||||||
/* Calculate result */
|
/* Calculate result */
|
||||||
bigint_mod_exp ( base, modulus, &exponent, result, &ffdhe_temp.tmp );
|
bigint_mod_exp ( base, modulus, &exponent, result, tmp->mod_exp );
|
||||||
DBGC ( group, "FFDHE %s %s: %s\n", group->name,
|
DBGC ( group, "FFDHE %s %s: %s\n", group->name,
|
||||||
( public ? "shr" : "pub" ), bigint_ntoa ( result ) );
|
( public ? "shr" : "pub" ), bigint_ntoa ( result ) );
|
||||||
bigint_done ( result, shared, len );
|
bigint_done ( result, shared, len );
|
||||||
@@ -246,16 +244,24 @@ static int ffdhe ( struct ffdhe_group *group, const void *public,
|
|||||||
if ( ! bigint_is_geq ( result, base ) ) {
|
if ( ! bigint_is_geq ( result, base ) ) {
|
||||||
/* Result is 0 or 1 */
|
/* Result is 0 or 1 */
|
||||||
DBGC ( group, "FFDHE %s invalid result\n", group->name );
|
DBGC ( group, "FFDHE %s invalid result\n", group->name );
|
||||||
return -EPERM;
|
rc = -EPERM;
|
||||||
|
goto err_result;
|
||||||
}
|
}
|
||||||
bigint_add ( base, result );
|
bigint_add ( base, result );
|
||||||
if ( ! bigint_is_geq ( modulus, result ) ) {
|
if ( ! bigint_is_geq ( modulus, result ) ) {
|
||||||
/* Result is p-1 */
|
/* Result is p-1 */
|
||||||
DBGC ( group, "FFDHE %s invalid result\n", group->name );
|
DBGC ( group, "FFDHE %s invalid result\n", group->name );
|
||||||
return -EPERM;
|
rc = -EPERM;
|
||||||
|
goto err_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
/* Success */
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
|
err_result:
|
||||||
|
free ( tmp );
|
||||||
|
err_alloc:
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user