mirror of
https://github.com/Mbed-TLS/mbedtls.git
synced 2025-03-29 13:20:21 +00:00
Move FFDH layer to separate file
Signed-off-by: Przemek Stekiel <przemyslaw.stekiel@mobica.com>
This commit is contained in:
parent
7cf26dfca3
commit
359f4625a3
@ -35,6 +35,7 @@
|
|||||||
#include "psa_crypto_invasive.h"
|
#include "psa_crypto_invasive.h"
|
||||||
#include "psa_crypto_driver_wrappers.h"
|
#include "psa_crypto_driver_wrappers.h"
|
||||||
#include "psa_crypto_ecp.h"
|
#include "psa_crypto_ecp.h"
|
||||||
|
#include "psa_crypto_ffdh.h"
|
||||||
#include "psa_crypto_hash.h"
|
#include "psa_crypto_hash.h"
|
||||||
#include "psa_crypto_mac.h"
|
#include "psa_crypto_mac.h"
|
||||||
#include "psa_crypto_rsa.h"
|
#include "psa_crypto_rsa.h"
|
||||||
@ -82,7 +83,6 @@
|
|||||||
#include "mbedtls/sha256.h"
|
#include "mbedtls/sha256.h"
|
||||||
#include "mbedtls/sha512.h"
|
#include "mbedtls/sha512.h"
|
||||||
#include "hash_info.h"
|
#include "hash_info.h"
|
||||||
#include "mbedtls/dhm.h"
|
|
||||||
|
|
||||||
#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array)))
|
#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(*(array)))
|
||||||
|
|
||||||
@ -1407,211 +1407,6 @@ psa_status_t psa_export_key(mbedtls_svc_key_id_t key,
|
|||||||
return (status == PSA_SUCCESS) ? unlock_status : status;
|
return (status == PSA_SUCCESS) ? unlock_status : status;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_FFDH_KEY_PAIR) || \
|
|
||||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_FFDH_PUBLIC_KEY)
|
|
||||||
static psa_status_t psa_ffdh_set_prime_generator(size_t key_size,
|
|
||||||
mbedtls_mpi *P,
|
|
||||||
mbedtls_mpi *G)
|
|
||||||
{
|
|
||||||
const unsigned char *dhm_P = NULL;
|
|
||||||
const unsigned char *dhm_G = NULL;
|
|
||||||
size_t dhm_size_P = 0;
|
|
||||||
size_t dhm_size_G = 0;
|
|
||||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
|
||||||
|
|
||||||
if (P == NULL && G == NULL) {
|
|
||||||
return PSA_ERROR_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const unsigned char dhm_P_2048[] =
|
|
||||||
MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN;
|
|
||||||
static const unsigned char dhm_P_3072[] =
|
|
||||||
MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN;
|
|
||||||
static const unsigned char dhm_P_4096[] =
|
|
||||||
MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN;
|
|
||||||
static const unsigned char dhm_P_6144[] =
|
|
||||||
MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN;
|
|
||||||
static const unsigned char dhm_P_8192[] =
|
|
||||||
MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN;
|
|
||||||
static const unsigned char dhm_G_2048[] =
|
|
||||||
MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN;
|
|
||||||
static const unsigned char dhm_G_3072[] =
|
|
||||||
MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN;
|
|
||||||
static const unsigned char dhm_G_4096[] =
|
|
||||||
MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN;
|
|
||||||
static const unsigned char dhm_G_6144[] =
|
|
||||||
MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN;
|
|
||||||
static const unsigned char dhm_G_8192[] =
|
|
||||||
MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN;
|
|
||||||
|
|
||||||
if (key_size <= 256) {
|
|
||||||
dhm_P = dhm_P_2048;
|
|
||||||
dhm_G = dhm_G_2048;
|
|
||||||
dhm_size_P = sizeof(dhm_P_2048);
|
|
||||||
dhm_size_G = sizeof(dhm_G_2048);
|
|
||||||
} else if (key_size <= 384) {
|
|
||||||
dhm_P = dhm_P_3072;
|
|
||||||
dhm_G = dhm_G_3072;
|
|
||||||
dhm_size_P = sizeof(dhm_P_3072);
|
|
||||||
dhm_size_G = sizeof(dhm_G_3072);
|
|
||||||
} else if (key_size <= 512) {
|
|
||||||
dhm_P = dhm_P_4096;
|
|
||||||
dhm_G = dhm_G_4096;
|
|
||||||
dhm_size_P = sizeof(dhm_P_4096);
|
|
||||||
dhm_size_G = sizeof(dhm_G_4096);
|
|
||||||
} else if (key_size <= 768) {
|
|
||||||
dhm_P = dhm_P_6144;
|
|
||||||
dhm_G = dhm_G_6144;
|
|
||||||
dhm_size_P = sizeof(dhm_P_6144);
|
|
||||||
dhm_size_G = sizeof(dhm_G_6144);
|
|
||||||
} else if (key_size <= 1024) {
|
|
||||||
dhm_P = dhm_P_8192;
|
|
||||||
dhm_G = dhm_G_8192;
|
|
||||||
dhm_size_P = sizeof(dhm_P_8192);
|
|
||||||
dhm_size_G = sizeof(dhm_G_8192);
|
|
||||||
} else {
|
|
||||||
return PSA_ERROR_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (P != NULL) {
|
|
||||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(P, dhm_P,
|
|
||||||
dhm_size_P));
|
|
||||||
}
|
|
||||||
if (G != NULL) {
|
|
||||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(G, dhm_G,
|
|
||||||
dhm_size_G));
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
if (ret != 0) {
|
|
||||||
return mbedtls_to_psa_error(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
return PSA_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
|
|
||||||
static psa_status_t psa_key_agreement_ffdh(const uint8_t *peer_key,
|
|
||||||
size_t peer_key_length,
|
|
||||||
const uint8_t *our_key,
|
|
||||||
size_t our_key_length,
|
|
||||||
uint8_t *shared_secret,
|
|
||||||
size_t shared_secret_size,
|
|
||||||
size_t *shared_secret_length)
|
|
||||||
{
|
|
||||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
|
||||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
|
||||||
mbedtls_mpi P, G, X, GY, K;
|
|
||||||
const size_t calculated_shared_secret_size = peer_key_length;
|
|
||||||
|
|
||||||
if (peer_key_length != our_key_length ||
|
|
||||||
calculated_shared_secret_size > shared_secret_size) {
|
|
||||||
return PSA_ERROR_INVALID_ARGUMENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
mbedtls_mpi_init(&P); mbedtls_mpi_init(&G);
|
|
||||||
mbedtls_mpi_init(&X); mbedtls_mpi_init(&GY);
|
|
||||||
mbedtls_mpi_init(&K);
|
|
||||||
|
|
||||||
status = psa_ffdh_set_prime_generator(peer_key_length, &P, &G);
|
|
||||||
|
|
||||||
if (status == PSA_SUCCESS) {
|
|
||||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, our_key,
|
|
||||||
our_key_length));
|
|
||||||
|
|
||||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&GY, peer_key,
|
|
||||||
peer_key_length));
|
|
||||||
|
|
||||||
/* Calculate shared secret public key: K = G^(XY) mod P */
|
|
||||||
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&K, &GY, &X, &P, NULL));
|
|
||||||
|
|
||||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&K, shared_secret,
|
|
||||||
calculated_shared_secret_size));
|
|
||||||
|
|
||||||
*shared_secret_length = calculated_shared_secret_size;
|
|
||||||
}
|
|
||||||
cleanup:
|
|
||||||
mbedtls_mpi_free(&P); mbedtls_mpi_free(&G);
|
|
||||||
mbedtls_mpi_free(&X); mbedtls_mpi_free(&GY);
|
|
||||||
mbedtls_mpi_free(&K);
|
|
||||||
|
|
||||||
if (status == PSA_SUCCESS && ret != 0) {
|
|
||||||
return mbedtls_to_psa_error(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
return PSA_SUCCESS;
|
|
||||||
}
|
|
||||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */
|
|
||||||
|
|
||||||
static psa_status_t psa_export_ffdh_public_key_internal(
|
|
||||||
const uint8_t *key_buffer,
|
|
||||||
size_t key_buffer_size,
|
|
||||||
uint8_t *data,
|
|
||||||
size_t data_size,
|
|
||||||
size_t *data_length)
|
|
||||||
{
|
|
||||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
|
||||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
|
||||||
mbedtls_mpi GX, G, X, P;
|
|
||||||
|
|
||||||
mbedtls_mpi_init(&GX); mbedtls_mpi_init(&G);
|
|
||||||
mbedtls_mpi_init(&X); mbedtls_mpi_init(&P);
|
|
||||||
|
|
||||||
status = psa_ffdh_set_prime_generator(key_buffer_size, &P, &G);
|
|
||||||
|
|
||||||
if (status == PSA_SUCCESS) {
|
|
||||||
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer,
|
|
||||||
key_buffer_size));
|
|
||||||
|
|
||||||
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&GX, &G, &X, &P, NULL));
|
|
||||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&GX, data, data_size));
|
|
||||||
|
|
||||||
*data_length = mbedtls_mpi_size(&GX);
|
|
||||||
}
|
|
||||||
cleanup:
|
|
||||||
mbedtls_mpi_free(&P); mbedtls_mpi_free(&G);
|
|
||||||
mbedtls_mpi_free(&X); mbedtls_mpi_free(&GX);
|
|
||||||
|
|
||||||
if (status == PSA_SUCCESS && ret != 0) {
|
|
||||||
return mbedtls_to_psa_error(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static psa_status_t mbedtls_psa_ffdh_generate_key(
|
|
||||||
const psa_key_attributes_t *attributes,
|
|
||||||
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
|
|
||||||
{
|
|
||||||
mbedtls_mpi X, P;
|
|
||||||
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
|
||||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
|
||||||
mbedtls_mpi_init(&P); mbedtls_mpi_init(&X);
|
|
||||||
|
|
||||||
status = psa_ffdh_set_prime_generator(PSA_BITS_TO_BYTES(attributes->core.bits), &P, NULL);
|
|
||||||
|
|
||||||
if (status == PSA_SUCCESS) {
|
|
||||||
MBEDTLS_MPI_CHK(mbedtls_mpi_random(&X, 4, &P, mbedtls_psa_get_random,
|
|
||||||
MBEDTLS_PSA_RANDOM_STATE));
|
|
||||||
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&X, &X, 2));
|
|
||||||
|
|
||||||
*key_buffer_length = mbedtls_mpi_size(&X);
|
|
||||||
|
|
||||||
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&X, key_buffer,
|
|
||||||
key_buffer_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
mbedtls_mpi_free(&P); mbedtls_mpi_free(&X);
|
|
||||||
if (status == PSA_SUCCESS && ret != 0) {
|
|
||||||
return mbedtls_to_psa_error(ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_FFDH_KEY_PAIR ||
|
|
||||||
MBEDTLS_PSA_BUILTIN_KEY_TYPE_FFDH_PUBLIC_KEY */
|
|
||||||
|
|
||||||
psa_status_t psa_export_public_key_internal(
|
psa_status_t psa_export_public_key_internal(
|
||||||
const psa_key_attributes_t *attributes,
|
const psa_key_attributes_t *attributes,
|
||||||
const uint8_t *key_buffer,
|
const uint8_t *key_buffer,
|
||||||
@ -1663,10 +1458,11 @@ psa_status_t psa_export_public_key_internal(
|
|||||||
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_FFDH_KEY_PAIR) || \
|
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_FFDH_KEY_PAIR) || \
|
||||||
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_FFDH_PUBLIC_KEY)
|
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_FFDH_PUBLIC_KEY)
|
||||||
else {
|
else {
|
||||||
return psa_export_ffdh_public_key_internal(key_buffer,
|
return mbedtls_psa_export_ffdh_public_key(attributes,
|
||||||
key_buffer_size,
|
key_buffer,
|
||||||
data, data_size,
|
key_buffer_size,
|
||||||
data_length);
|
data, data_size,
|
||||||
|
data_length);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* We don't know how to convert a private FFDH key to public */
|
/* We don't know how to convert a private FFDH key to public */
|
||||||
@ -6802,13 +6598,14 @@ psa_status_t psa_key_agreement_raw_builtin(const psa_key_attributes_t *attribute
|
|||||||
return PSA_ERROR_INVALID_ARGUMENT;
|
return PSA_ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return psa_key_agreement_ffdh(peer_key,
|
return mbedtls_psa_key_agreement_ffdh(attributes,
|
||||||
peer_key_length,
|
peer_key,
|
||||||
key_buffer,
|
peer_key_length,
|
||||||
key_buffer_size,
|
key_buffer,
|
||||||
shared_secret,
|
key_buffer_size,
|
||||||
shared_secret_size,
|
shared_secret,
|
||||||
shared_secret_length);
|
shared_secret_size,
|
||||||
|
shared_secret_length);
|
||||||
#endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */
|
#endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
241
library/psa_crypto_ffdh.c
Normal file
241
library/psa_crypto_ffdh.c
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
/*
|
||||||
|
* PSA FFDH layer on top of Mbed TLS crypto
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_CRYPTO_C)
|
||||||
|
|
||||||
|
#include <psa/crypto.h>
|
||||||
|
#include "psa_crypto_core.h"
|
||||||
|
#include "psa_crypto_ffdh.h"
|
||||||
|
#include "psa_crypto_random_impl.h"
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_FFDH_KEY_PAIR) || \
|
||||||
|
defined(MBEDTLS_PSA_BUILTIN_KEY_TYPE_FFDH_PUBLIC_KEY)
|
||||||
|
static psa_status_t mbedtls_psa_ffdh_set_prime_generator(size_t key_size,
|
||||||
|
mbedtls_mpi *P,
|
||||||
|
mbedtls_mpi *G)
|
||||||
|
{
|
||||||
|
const unsigned char *dhm_P = NULL;
|
||||||
|
const unsigned char *dhm_G = NULL;
|
||||||
|
size_t dhm_size_P = 0;
|
||||||
|
size_t dhm_size_G = 0;
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
|
||||||
|
if (P == NULL && G == NULL) {
|
||||||
|
return PSA_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const unsigned char dhm_P_2048[] =
|
||||||
|
MBEDTLS_DHM_RFC7919_FFDHE2048_P_BIN;
|
||||||
|
static const unsigned char dhm_P_3072[] =
|
||||||
|
MBEDTLS_DHM_RFC7919_FFDHE3072_P_BIN;
|
||||||
|
static const unsigned char dhm_P_4096[] =
|
||||||
|
MBEDTLS_DHM_RFC7919_FFDHE4096_P_BIN;
|
||||||
|
static const unsigned char dhm_P_6144[] =
|
||||||
|
MBEDTLS_DHM_RFC7919_FFDHE6144_P_BIN;
|
||||||
|
static const unsigned char dhm_P_8192[] =
|
||||||
|
MBEDTLS_DHM_RFC7919_FFDHE8192_P_BIN;
|
||||||
|
static const unsigned char dhm_G_2048[] =
|
||||||
|
MBEDTLS_DHM_RFC7919_FFDHE2048_G_BIN;
|
||||||
|
static const unsigned char dhm_G_3072[] =
|
||||||
|
MBEDTLS_DHM_RFC7919_FFDHE3072_G_BIN;
|
||||||
|
static const unsigned char dhm_G_4096[] =
|
||||||
|
MBEDTLS_DHM_RFC7919_FFDHE4096_G_BIN;
|
||||||
|
static const unsigned char dhm_G_6144[] =
|
||||||
|
MBEDTLS_DHM_RFC7919_FFDHE6144_G_BIN;
|
||||||
|
static const unsigned char dhm_G_8192[] =
|
||||||
|
MBEDTLS_DHM_RFC7919_FFDHE8192_G_BIN;
|
||||||
|
|
||||||
|
if (key_size <= 256) {
|
||||||
|
dhm_P = dhm_P_2048;
|
||||||
|
dhm_G = dhm_G_2048;
|
||||||
|
dhm_size_P = sizeof(dhm_P_2048);
|
||||||
|
dhm_size_G = sizeof(dhm_G_2048);
|
||||||
|
} else if (key_size <= 384) {
|
||||||
|
dhm_P = dhm_P_3072;
|
||||||
|
dhm_G = dhm_G_3072;
|
||||||
|
dhm_size_P = sizeof(dhm_P_3072);
|
||||||
|
dhm_size_G = sizeof(dhm_G_3072);
|
||||||
|
} else if (key_size <= 512) {
|
||||||
|
dhm_P = dhm_P_4096;
|
||||||
|
dhm_G = dhm_G_4096;
|
||||||
|
dhm_size_P = sizeof(dhm_P_4096);
|
||||||
|
dhm_size_G = sizeof(dhm_G_4096);
|
||||||
|
} else if (key_size <= 768) {
|
||||||
|
dhm_P = dhm_P_6144;
|
||||||
|
dhm_G = dhm_G_6144;
|
||||||
|
dhm_size_P = sizeof(dhm_P_6144);
|
||||||
|
dhm_size_G = sizeof(dhm_G_6144);
|
||||||
|
} else if (key_size <= 1024) {
|
||||||
|
dhm_P = dhm_P_8192;
|
||||||
|
dhm_G = dhm_G_8192;
|
||||||
|
dhm_size_P = sizeof(dhm_P_8192);
|
||||||
|
dhm_size_G = sizeof(dhm_G_8192);
|
||||||
|
} else {
|
||||||
|
return PSA_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (P != NULL) {
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(P, dhm_P,
|
||||||
|
dhm_size_P));
|
||||||
|
}
|
||||||
|
if (G != NULL) {
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(G, dhm_G,
|
||||||
|
dhm_size_G));
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (ret != 0) {
|
||||||
|
return mbedtls_to_psa_error(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PSA_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(MBEDTLS_PSA_BUILTIN_ALG_FFDH)
|
||||||
|
psa_status_t mbedtls_psa_key_agreement_ffdh(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *peer_key,
|
||||||
|
size_t peer_key_length,
|
||||||
|
const uint8_t *key_buffer,
|
||||||
|
size_t key_buffer_size,
|
||||||
|
uint8_t *shared_secret,
|
||||||
|
size_t shared_secret_size,
|
||||||
|
size_t *shared_secret_length)
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||||
|
mbedtls_mpi P, G, X, GY, K;
|
||||||
|
const size_t calculated_shared_secret_size = peer_key_length;
|
||||||
|
|
||||||
|
if (peer_key_length != key_buffer_size ||
|
||||||
|
calculated_shared_secret_size > shared_secret_size) {
|
||||||
|
return PSA_ERROR_INVALID_ARGUMENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
mbedtls_mpi_init(&P); mbedtls_mpi_init(&G);
|
||||||
|
mbedtls_mpi_init(&X); mbedtls_mpi_init(&GY);
|
||||||
|
mbedtls_mpi_init(&K);
|
||||||
|
|
||||||
|
status = mbedtls_psa_ffdh_set_prime_generator(
|
||||||
|
PSA_BITS_TO_BYTES(attributes->core.bits), &P, &G);
|
||||||
|
|
||||||
|
if (status == PSA_SUCCESS) {
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer,
|
||||||
|
key_buffer_size));
|
||||||
|
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&GY, peer_key,
|
||||||
|
peer_key_length));
|
||||||
|
|
||||||
|
/* Calculate shared secret public key: K = G^(XY) mod P */
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&K, &GY, &X, &P, NULL));
|
||||||
|
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&K, shared_secret,
|
||||||
|
calculated_shared_secret_size));
|
||||||
|
|
||||||
|
*shared_secret_length = calculated_shared_secret_size;
|
||||||
|
}
|
||||||
|
cleanup:
|
||||||
|
mbedtls_mpi_free(&P); mbedtls_mpi_free(&G);
|
||||||
|
mbedtls_mpi_free(&X); mbedtls_mpi_free(&GY);
|
||||||
|
mbedtls_mpi_free(&K);
|
||||||
|
|
||||||
|
if (status == PSA_SUCCESS && ret != 0) {
|
||||||
|
return mbedtls_to_psa_error(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PSA_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_PSA_BUILTIN_ALG_FFDH */
|
||||||
|
|
||||||
|
psa_status_t mbedtls_psa_export_ffdh_public_key(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *key_buffer,
|
||||||
|
size_t key_buffer_size,
|
||||||
|
uint8_t *data,
|
||||||
|
size_t data_size,
|
||||||
|
size_t *data_length)
|
||||||
|
{
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||||
|
mbedtls_mpi GX, G, X, P;
|
||||||
|
|
||||||
|
mbedtls_mpi_init(&GX); mbedtls_mpi_init(&G);
|
||||||
|
mbedtls_mpi_init(&X); mbedtls_mpi_init(&P);
|
||||||
|
|
||||||
|
status = mbedtls_psa_ffdh_set_prime_generator(
|
||||||
|
PSA_BITS_TO_BYTES(attributes->core.bits), &P, &G);
|
||||||
|
|
||||||
|
if (status == PSA_SUCCESS) {
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_read_binary(&X, key_buffer,
|
||||||
|
key_buffer_size));
|
||||||
|
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&GX, &G, &X, &P, NULL));
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&GX, data, data_size));
|
||||||
|
|
||||||
|
*data_length = mbedtls_mpi_size(&GX);
|
||||||
|
}
|
||||||
|
cleanup:
|
||||||
|
mbedtls_mpi_free(&P); mbedtls_mpi_free(&G);
|
||||||
|
mbedtls_mpi_free(&X); mbedtls_mpi_free(&GX);
|
||||||
|
|
||||||
|
if (status == PSA_SUCCESS && ret != 0) {
|
||||||
|
return mbedtls_to_psa_error(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
psa_status_t mbedtls_psa_ffdh_generate_key(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
uint8_t *key_buffer, size_t key_buffer_size, size_t *key_buffer_length)
|
||||||
|
{
|
||||||
|
mbedtls_mpi X, P;
|
||||||
|
int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
|
||||||
|
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||||
|
mbedtls_mpi_init(&P); mbedtls_mpi_init(&X);
|
||||||
|
|
||||||
|
status = mbedtls_psa_ffdh_set_prime_generator(
|
||||||
|
PSA_BITS_TO_BYTES(attributes->core.bits), &P, NULL);
|
||||||
|
|
||||||
|
if (status == PSA_SUCCESS) {
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_random(&X, 4, &P, mbedtls_psa_get_random,
|
||||||
|
MBEDTLS_PSA_RANDOM_STATE));
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&X, &X, 2));
|
||||||
|
|
||||||
|
*key_buffer_length = mbedtls_mpi_size(&X);
|
||||||
|
|
||||||
|
MBEDTLS_MPI_CHK(mbedtls_mpi_write_binary(&X, key_buffer,
|
||||||
|
key_buffer_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
mbedtls_mpi_free(&P); mbedtls_mpi_free(&X);
|
||||||
|
if (status == PSA_SUCCESS && ret != 0) {
|
||||||
|
return mbedtls_to_psa_error(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
#endif /* MBEDTLS_PSA_BUILTIN_KEY_TYPE_FFDH_KEY_PAIR ||
|
||||||
|
MBEDTLS_PSA_BUILTIN_KEY_TYPE_FFDH_PUBLIC_KEY */
|
||||||
|
|
||||||
|
#endif /* MBEDTLS_PSA_CRYPTO_C */
|
115
library/psa_crypto_ffdh.h
Normal file
115
library/psa_crypto_ffdh.h
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* PSA FFDH layer on top of Mbed TLS crypto
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Copyright The Mbed TLS Contributors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PSA_CRYPTO_FFDH_H
|
||||||
|
#define PSA_CRYPTO_FFDH_H
|
||||||
|
|
||||||
|
#include <psa/crypto.h>
|
||||||
|
#include <mbedtls/dhm.h>
|
||||||
|
|
||||||
|
/** Perform a key agreement and return the FFDH shared secret.
|
||||||
|
*
|
||||||
|
* \param[in] attributes The attributes of the key to use for the
|
||||||
|
* operation.
|
||||||
|
* \param[in] peer_key The buffer containing the key context
|
||||||
|
* of the peer's public key.
|
||||||
|
* \param[in] peer_key_length Size of the \p peer_key buffer in
|
||||||
|
* bytes.
|
||||||
|
* \param[in] key_buffer The buffer containing the private key
|
||||||
|
* context.
|
||||||
|
* \param[in] key_buffer_size Size of the \p key_buffer buffer in
|
||||||
|
* bytes.
|
||||||
|
* \param[out] shared_secret The buffer to which the shared secret
|
||||||
|
* is to be written.
|
||||||
|
* \param[in] shared_secret_size Size of the \p shared_secret buffer in
|
||||||
|
* bytes.
|
||||||
|
* \param[out] shared_secret_length On success, the number of bytes that make
|
||||||
|
* up the returned shared secret.
|
||||||
|
* \retval #PSA_SUCCESS
|
||||||
|
* Success. Shared secret successfully calculated.
|
||||||
|
* \retval #PSA_ERROR_INVALID_ARGUMENT
|
||||||
|
* \p key_buffer_size, \p peer_key_length, \p shared_secret_size
|
||||||
|
* do not match
|
||||||
|
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||||
|
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||||
|
*/
|
||||||
|
psa_status_t mbedtls_psa_key_agreement_ffdh(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *peer_key,
|
||||||
|
size_t peer_key_length,
|
||||||
|
const uint8_t *key_buffer,
|
||||||
|
size_t key_buffer_size,
|
||||||
|
uint8_t *shared_secret,
|
||||||
|
size_t shared_secret_size,
|
||||||
|
size_t *shared_secret_length);
|
||||||
|
|
||||||
|
/** Export a public key or the public part of a FFDH key pair in binary format.
|
||||||
|
*
|
||||||
|
* \param[in] attributes The attributes for the key to export.
|
||||||
|
* \param[in] key_buffer Material or context of the key to export.
|
||||||
|
* \param[in] key_buffer_size Size of the \p key_buffer buffer in bytes.
|
||||||
|
* \param[out] data Buffer where the key data is to be written.
|
||||||
|
* \param[in] data_size Size of the \p data buffer in bytes.
|
||||||
|
* \param[out] data_length On success, the number of bytes written in
|
||||||
|
* \p data
|
||||||
|
*
|
||||||
|
* \retval #PSA_SUCCESS The public key was exported successfully.
|
||||||
|
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||||
|
* The size of \p key_buffer is too small.
|
||||||
|
* \retval #PSA_ERROR_NOT_PERMITTED
|
||||||
|
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||||
|
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||||
|
*/
|
||||||
|
psa_status_t mbedtls_psa_export_ffdh_public_key(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
const uint8_t *key_buffer,
|
||||||
|
size_t key_buffer_size,
|
||||||
|
uint8_t *data,
|
||||||
|
size_t data_size,
|
||||||
|
size_t *data_length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Generate FFDH key.
|
||||||
|
*
|
||||||
|
* \note The signature of the function is that of a PSA driver generate_key
|
||||||
|
* entry point.
|
||||||
|
*
|
||||||
|
* \param[in] attributes The attributes for the key to generate.
|
||||||
|
* \param[out] key_buffer Buffer where the key data is to be written.
|
||||||
|
* \param[in] key_buffer_size Size of \p key_buffer in bytes.
|
||||||
|
* \param[out] key_buffer_length On success, the number of bytes written in
|
||||||
|
* \p key_buffer.
|
||||||
|
*
|
||||||
|
* \retval #PSA_SUCCESS
|
||||||
|
* The key was generated successfully.
|
||||||
|
* \retval #PSA_ERROR_NOT_SUPPORTED
|
||||||
|
* Key size in bits is invalid.
|
||||||
|
* \retval #PSA_ERROR_BUFFER_TOO_SMALL
|
||||||
|
* The size of \p key_buffer is too small.
|
||||||
|
* \retval #PSA_ERROR_INSUFFICIENT_MEMORY
|
||||||
|
* \retval #PSA_ERROR_CORRUPTION_DETECTED
|
||||||
|
*/
|
||||||
|
psa_status_t mbedtls_psa_ffdh_generate_key(
|
||||||
|
const psa_key_attributes_t *attributes,
|
||||||
|
uint8_t *key_buffer,
|
||||||
|
size_t key_buffer_size,
|
||||||
|
size_t *key_buffer_length);
|
||||||
|
|
||||||
|
#endif /* PSA_CRYPTO_FFDH_H */
|
Loading…
x
Reference in New Issue
Block a user