Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions pkg/driver_cryptocell_310/include/cryptocell_310_util.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/*
* Copyright (C) 2021 HAW Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
* SPDX-FileCopyrightText: 2021 HAW Hamburg
* SPDX-License-Identifier: LGPL-2.1-only
*/

#pragma once
Expand All @@ -23,6 +20,10 @@
extern "C" {
#endif

#ifdef CPU_NRF52
#define CHECK_POINTER_DMA_ACCESS(p) ((unsigned int)p >= 0x20000000 ? (unsigned int)p < 0x40000000 : 0)

Check warning on line 24 in pkg/driver_cryptocell_310/include/cryptocell_310_util.h

View workflow job for this annotation

GitHub Actions / static-tests

line is longer than 100 characters
#endif

/**
* @brief Enable CryptoCell module and IRQs.
*
Expand Down
7 changes: 2 additions & 5 deletions pkg/driver_cryptocell_310/include/psa_error.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/*
* Copyright (C) 2021 HAW Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
* SPDX-FileCopyrightText: 2021 HAW Hamburg
* SPDX-License-Identifier: LGPL-2.1-only
*/

#pragma once
Expand Down
53 changes: 53 additions & 0 deletions pkg/driver_cryptocell_310/include/psa_periph_chacha20_ctx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* SPDX-FileCopyrightText: 2024 TU Dresden
* SPDX-License-Identifier: LGPL-2.1-only
*/

#pragma once

/**
* @ingroup pkg_driver_cryptocell_310
* @{
*
* @file
* @brief CryptoCell 310 driver specific ChaCha20 contexts
*
* @author Lennard Melling <[email protected]>
*
*/

#ifdef __cplusplus
extern "C" {
#endif

#include "crys_chacha.h"
#include "kernel_defines.h"

#if IS_USED(MODULE_PERIPH_CIPHER_CHACHA20) || DOXYGEN
/**
* @brief This struct is used to handle the discontinuity between the PSA API
* and the CRYS ChaCha20 API. The PSA API psa_cipher_update() function allows any size
* of input array, but the CRYS implementation only works on multiples of 64B.
* So we store any remainders from the input in the buffer, and if any more data
* is input, we join them with the buffer values. The psa_cipher_finish() function
* will then xcrypt the remaining buffer values.
* The buffer is also used in the setup of the operation. The psa_cipher_~_setup()
* functions only provide the key for the operation, but the CRYS ChaCha20
* implementation also needs the counter and nonce provided by psa_cipher_set_iv().
* So we store the key in the buffer until it is needed in the CRYS ChaCha20 setup.
*/
typedef struct {
uint8_t buffer[CRYS_CHACHA_BLOCK_SIZE_IN_BYTES]; /**< Block buffer */
uint8_t buffer_length; /**< Current length of the data in buffer */
union {
CRYS_CHACHA_EncryptMode_t mode; /**< Mode of the operation */
CRYS_CHACHAUserContext_t post_setup; /**< Context of the CRYS ChaCha20 operation */
} ctx; /**< Context Setup values */
} psa_cipher_chacha20_ctx_t;

#endif

#ifdef __cplusplus
}
#endif
/** @} */
187 changes: 181 additions & 6 deletions pkg/driver_cryptocell_310/psa_cryptocell_310/cipher_chacha20.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/*
* Copyright (C) 2024 TU Dresden
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
* SPDX-FileCopyrightText: 2024 TU Dresden
* SPDX-License-Identifier: LGPL-2.1-only
*/

/**
Expand All @@ -23,14 +20,192 @@
extern "C" {
#endif

#include "psa/crypto.h"
#include "unaligned.h"
#include "crys_chacha.h"
#include "cryptocell_310_util.h"
#include "psa_error.h"
#include "string_utils.h"

#define ENABLE_DEBUG 0
#include "debug.h"

static psa_status_t _setup(psa_cipher_chacha20_ctx_t *ctx,
uint8_t *key_data,
size_t key_length,
CRYS_CHACHA_EncryptMode_t mode)
{
DEBUG("Peripheral ChaCha20 Cipher setup");

if (key_length != CRYS_CHACHA_KEY_MAX_SIZE_IN_BYTES) {
return PSA_ERROR_INVALID_ARGUMENT;
}

ctx->buffer_length = 0;
memset(ctx->buffer, 0, sizeof(ctx->buffer));
/* Copy keydata into buffer for setup in psa_cipher_chacha20_set_iv() */
memcpy(ctx->buffer, key_data, key_length);
ctx->ctx.mode = mode;
return PSA_SUCCESS;
}

psa_status_t psa_cipher_chacha20_encrypt_setup( psa_cipher_chacha20_ctx_t *ctx,
uint8_t *key_data,
size_t key_length)
{
return _setup(ctx, key_data, key_length, CRYS_CHACHA_Encrypt);
}

psa_status_t psa_cipher_chacha20_decrypt_setup( psa_cipher_chacha20_ctx_t *ctx,
uint8_t *key_data,
size_t key_length)
{
return _setup(ctx, key_data, key_length, CRYS_CHACHA_Decrypt);
}

psa_status_t psa_cipher_chacha20_set_iv(psa_cipher_chacha20_ctx_t *ctx,
const uint8_t *iv,
size_t iv_length)
{
DEBUG("Peripheral ChaCha20 Cipher set IV");
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
CRYSError_t periph_status = CRYS_CHACHA_GENERAL_ERROR;

/* See PSA Specification */
switch (iv_length) {
case 8:
/* 8 bytes: the cipher operation uses the original [CHACHA20] definition
of ChaCha20: the provided IV is used as the 64-bit nonce, and the 64-bit
counter value is set to zero. */
status = PSA_ERROR_NOT_SUPPORTED;
break;
case 12:
/* 12 bytes: the provided IV is used as the nonce, and the counter value
is set to zero. */
cryptocell_310_enable();
periph_status = CRYS_CHACHA_Init( &ctx->ctx.post_setup,
(uint8_t*)iv,
CRYS_CHACHA_Nonce96BitSize,
ctx->buffer,
0,
ctx->ctx.mode);
cryptocell_310_disable();
status = CRYS_to_psa_error(periph_status);
break;
case 16:
/* 16 bytes: the first four bytes of the IV are used as the counter value
(encoded as little-endian), and the remaining 12 bytes are used as the nonce. */
periph_status = CRYS_CHACHA_Init( &ctx->ctx.post_setup,
(uint8_t*)&iv[4],
CRYS_CHACHA_Nonce96BitSize,
ctx->buffer,
unaligned_get_u32(iv),
ctx->ctx.mode);
cryptocell_310_disable();
status = CRYS_to_psa_error(periph_status);
break;
default:
/* It is recommended that implementations do not support other sizes of IV. */
status = PSA_ERROR_INVALID_ARGUMENT;
}
/* Clear key from buffer */
explicit_bzero(ctx->buffer, sizeof(ctx->buffer));
return status;
}

/* IoT-ToDo: multipart might be wrong */
psa_status_t psa_cipher_chacha20_update(psa_cipher_chacha20_ctx_t *ctx,
const uint8_t *input,
size_t input_length,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
DEBUG("Peripheral ChaCha20 Cipher update");
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

/* We return full blocks, so we check that we have enough output buffer
to fit all full blocks in the combined context and input buffer */
if (output_size < (((ctx->buffer_length + input_length) / \
CRYS_CHACHA_BLOCK_SIZE_IN_BYTES) * CRYS_CHACHA_BLOCK_SIZE_IN_BYTES)) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}

size_t input_index = 0;
size_t output_index = 0;
CRYSError_t periph_status;
/* check if buffer contains data */
cryptocell_310_enable();
if (ctx->buffer_length > 0) {
/* if yes, fill buffer up and update this block of data */
input_index = sizeof(ctx->buffer) - ctx->buffer_length;
memcpy(&ctx->buffer[ctx->buffer_length], input, input_index);
periph_status = CRYS_CHACHA_Block( &ctx->ctx.post_setup,
ctx->buffer,
64,
output);
status = CRYS_to_psa_error(periph_status);
if (status != PSA_SUCCESS) {
return status;
}
memset(ctx->buffer, 0, sizeof(ctx->buffer));
ctx->buffer_length = 0;
output_index = 64;
}
/* if not, update blocks of input */
const uint32_t blocks_length = ((input_length - input_index) / \
CRYS_CHACHA_BLOCK_SIZE_IN_BYTES) * CRYS_CHACHA_BLOCK_SIZE_IN_BYTES;
/* xcrypt full blocks */

/* IoT-TODO: if blocks_length == 0: CRYS_CHACHA_Block returns PSA_INVALID_ARGUMENT (CRYS_CHACHA_DATA_IN_SIZE_ILLEGAL) */
if(blocks_length > 0) {

Check warning on line 160 in pkg/driver_cryptocell_310/psa_cryptocell_310/cipher_chacha20.c

View workflow job for this annotation

GitHub Actions / static-tests

keyword 'if' not followed by a single space
periph_status = CRYS_CHACHA_Block( &ctx->ctx.post_setup,
(uint8_t *)&input[input_index],
blocks_length,
&output[output_index]);
status = CRYS_to_psa_error(periph_status);
if (status != PSA_SUCCESS) {
cryptocell_310_disable();
return status;
}
}
cryptocell_310_disable();

/* put remaining data into buffer */
ctx->buffer_length = input_length - (input_index + blocks_length);
memcpy(ctx->buffer, &input[input_index + blocks_length], ctx->buffer_length);
*output_length = output_index + blocks_length;

status = PSA_SUCCESS;
return status;
}

psa_status_t psa_cipher_chacha20_finish(psa_cipher_chacha20_ctx_t *ctx,
uint8_t *output,
size_t output_size,
size_t *output_length)
{
DEBUG("Peripheral ChaCha20 Cipher finish.");
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;

if (output_size < ctx->buffer_length) {
return PSA_ERROR_BUFFER_TOO_SMALL;
}

/* xcrypt remaining bytes */
cryptocell_310_enable();
CRYSError_t periph_status = CRYS_CHACHA_Finish( &ctx->ctx.post_setup,
ctx->buffer,
ctx->buffer_length,
output);
cryptocell_310_disable();

status = CRYS_to_psa_error(periph_status);
if (status == PSA_SUCCESS) {
*output_length = ctx->buffer_length;
}
return status;
}

psa_status_t psa_cipher_chacha20_encrypt(uint8_t *key_buffer,
size_t key_buffer_size,
const uint8_t *input,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
/*
* Copyright (C) 2021 HAW Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
* SPDX-FileCopyrightText: 2021 HAW Hamburg
* SPDX-License-Identifier: LGPL-2.1-only
*/

/**
Expand Down Expand Up @@ -221,7 +218,9 @@

const char *cryptocell310_status_to_humanly_readable(uint32_t status)
{
switch(status) {

Check warning on line 221 in pkg/driver_cryptocell_310/psa_cryptocell_310/error_conversion.c

View workflow job for this annotation

GitHub Actions / static-tests

keyword 'switch' not followed by a single space
case CRYS_OK:
return "CRYS_OK";
case CRYS_ECDH_SVDP_DH_NOT_CONCENT_PUBL_AND_PRIV_DOMAIN_ID_ERROR:
return "CRYS_ECDH_SVDP_DH_NOT_CONCENT_PUBL_AND_PRIV_DOMAIN_ID_ERROR";
case CRYS_ECDSA_SIGN_INVALID_IS_EPHEMER_KEY_INTERNAL_ERROR:
Expand Down
Loading
Loading