Skip to content

Commit

Permalink
Add CRACEN CTR DRBG random driver
Browse files Browse the repository at this point in the history
Add a new random CTR DRBG driver using the CRACEN HW TRNG and AES-ECB
acceleration.

Signed-off-by: Alberto Escolar Piedras <[email protected]>
  • Loading branch information
aescolar committed Jan 14, 2025
1 parent 30757c8 commit 18fb543
Show file tree
Hide file tree
Showing 6 changed files with 788 additions and 0 deletions.
99 changes: 99 additions & 0 deletions nrfx/drivers/include/nrfx_cracen_ctr_drbg.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright (c) 2025, Nordic Semiconductor ASA
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef NRFX_CRACEN_CTR_DRBG_H
#define NRFX_CRACEN_CTR_DRBG_H

#include <stddef.h>
#include <stdint.h>
#include <nrfx.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* @defgroup nrfx_cracen_ctr_drbg CRACEN CTR DRBG
* @{
* @ingroup nrfx_cracen_ctr_drbg
* @brief CRACEN CTR DRBG random generator driver
*
*/

/**
* @brief Initialize the CRACEN CTR DRBG pseudo random generator
*
* @retval NRFX_SUCCESS Initialization was successful.
* @retval NRFX_ERROR_INTERNAL Unexpected error.
*
* @note This function is only meant to be called once.
*
* @note It is not required to call this function before @nrfx_cracen_ctr_drbg_get_random.
* If @ref nrfx_cracen_ctr_drbg_get_random() were to be called without ever calling this,
* the same initialization would be done with its first call.
* But this initialization is relatively slow and power consuming. So this function
* allows initializing in it what may be a less constrained moment.
*
* @note This function assumes exclusive access to the CRACEN TRNG and CryptoMaster, and may
* not be used while any other component is using those peripherals. I.e. this driver
* may not be used together with the nRF security solution.
*
* @note This function is not reentrant.
*/
nrfx_err_t nrfx_cracen_ctr_drbg_init(void);

/**
* @brief Fill the /p p_buf buffer with /p size bytes of random data
*
* @param[out] p_buf Buffer into which to copy \p size bytes of entropy
* @param[in] size Number of bytes to copy
*
* @retval NRFX_SUCCESS Success
* @retval NRFX_ERROR_INVALID_PARAM Invalid inputs
* @retval NRFX_ERROR_INTERNAL Unexpected error.
*
* @note This function assumes exclusive access to the CRACEN TRNG and CryptoMaster, and may
* not be used while any other component is using those peripherals. I.e. this driver
* may not be used together with the nRF security solution.
*
* @note This function is not reentrant.
*/
nrfx_err_t nrfx_cracen_ctr_drbg_get_random(uint8_t *p_buf, size_t size);

/** @} */

#ifdef __cplusplus
}
#endif

#endif /* NRFX_CRACEN_CTR_DRBG_H */
131 changes: 131 additions & 0 deletions nrfx/drivers/src/cracen/nrfx_cracen_cm_aes_ecb.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
/*
* Copyright (c) 2025, Nordic Semiconductor ASA
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#include <stdint.h>
#include <stddef.h>
#include "hal/nrf_cracen.h"
#include "hal/nrf_cracen_cm.h"
#include "helpers/nrf_cracen_cm_dma.h"
#include "soc/nrfx_coredep.h"

/*
* Check if the CryptoMaster is done
*
* returns 0 if done, -1 if busy, and -2 on error
*/
static int cracen_cm_check_done(void)
{
uint32_t ret;
uint32_t busy;

ret = nrf_cracen_cm_int_pending_get(NRF_CRACENCORE);

if (ret & (NRF_CRACEN_CM_INT_FETCH_ERROR_MASK | NRF_CRACEN_CM_INT_PUSH_ERROR_MASK)) {
return -2;
}

busy = nrf_cracen_cm_status_get(NRF_CRACENCORE,
(NRF_CRACEN_CM_STATUS_BUSY_FETCH_MASK
| NRF_CRACEN_CM_STATUS_BUSY_PUSH_MASK
| NRF_CRACEN_CM_STATUS_PUSH_WAITING_MASK));

if (busy) {
return -1;
}

return 0;
}

int nrfx_cracen_cm_aes_ecb(uint8_t *key_p, size_t key_size, uint8_t *input_p, uint8_t *output_p)
{
#define ECB_BLK_SZ (16U)

int ret;

const uint32_t aes_config_value = NRF_CRACEN_CM_AES_CONFIG(
NRF_CRACEN_CM_AES_CONFIG_MODE_ECB,
NRF_CRACEN_CM_AES_CONFIG_KEY_SW_PROGRAMMED,
false, false, false);

struct nrf_cracen_cm_dma_desc in_descs[3];

in_descs[0].p_addr = (uint8_t *)&aes_config_value;
in_descs[0].length = sizeof(aes_config_value) | NRF_CRACEN_CM_DMA_DESC_LENGTH_REALIGN;
in_descs[0].dmatag = NRF_CRACEN_CM_DMA_TAG_AES_CONFIG(NRF_CRACEN_CM_AES_REG_OFFSET_CONFIG);
in_descs[0].p_next = &in_descs[1];

in_descs[1].p_addr = key_p;
in_descs[1].length = key_size | NRF_CRACEN_CM_DMA_DESC_LENGTH_REALIGN;
in_descs[1].dmatag = NRF_CRACEN_CM_DMA_TAG_AES_CONFIG(NRF_CRACEN_CM_AES_REG_OFFSET_KEY);
in_descs[1].p_next = &in_descs[2];

in_descs[2].p_addr = input_p;
in_descs[2].length = ECB_BLK_SZ | NRF_CRACEN_CM_DMA_DESC_LENGTH_REALIGN;
in_descs[2].dmatag = NRF_CRACEN_CM_DMA_TAG_LAST | NRF_CRACEN_CM_DMA_TAG_ENGINE_AES
| NRF_CRACEN_CM_DMA_TAG_DATATYPE_AES_PAYLOAD;
in_descs[2].p_next = NRF_CRACEN_CM_DMA_DESC_STOP;

struct nrf_cracen_cm_dma_desc out_desc;

out_desc.p_addr = output_p;
out_desc.length = ECB_BLK_SZ | NRF_CRACEN_CM_DMA_DESC_LENGTH_REALIGN;
out_desc.p_next = NRF_CRACEN_CM_DMA_DESC_STOP;
out_desc.dmatag = NRF_CRACEN_CM_DMA_TAG_LAST;

nrf_cracen_module_enable(NRF_CRACEN, CRACEN_ENABLE_CRYPTOMASTER_Msk);

nrf_cracen_cm_fetch_addr_set(NRF_CRACENCORE, (void *)in_descs);
nrf_cracen_cm_push_addr_set(NRF_CRACENCORE, (void *)&out_desc);

nrf_cracen_cm_config_indirect_set(NRF_CRACENCORE, NRF_CRACEN_CM_CONFIG_INDIRECT_FETCH_MASK
| NRF_CRACEN_CM_CONFIG_INDIRECT_PUSH_MASK);

__DMB();

nrf_cracen_cm_start(NRF_CRACENCORE);

do {
/* The HW is so fast that it is better to "busy wait" here than program an
* interrupt. This will normally already succeed in the first try
*/
#if defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
nrfx_coredep_delay_us(1);
#endif
ret = cracen_cm_check_done();
} while (ret == -1);

nrf_cracen_cm_softreset(NRF_CRACENCORE);
nrf_cracen_module_disable(NRF_CRACEN, CRACEN_ENABLE_CRYPTOMASTER_Msk);

return ret;
}
79 changes: 79 additions & 0 deletions nrfx/drivers/src/cracen/nrfx_cracen_cm_aes_ecb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright (c) 2025, Nordic Semiconductor ASA
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef NRFX_CRACEN_CM_AES_ECB_H
#define NRFX_CRACEN_CM_AES_ECB_H

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

/**
* @file
*
* Minimal driver for the CRACEN CryptoMaster AES ECB for the cracen_ctr_drbg driver
*/

/**
* Encrypt with AES-ECB the input data using the CRACEN CryptoMaster module
*
* @param[in] key_p Pointer to the key
* @param[in] key_size Size of the key in bytes (valid sizes 16, 24 or 32 => 128, 192 or 256 bits)
* @param[in] input_p Pointer to the input data (16 bytes/128 bits)
* @param[in] output_p Pointer to the output data (16 bytes/128 bits)
*
* @return 0 on success, a negative number on failure
*
* @note The key, input and output data are in big endian/cryptographic order. That is, input[0]
* corresponds to the highest byte of the 128bit input.
*
* @note The only failure one can normally expect are bus failures due to incorrect pointers.
*
* @note This function is meant to be used by the nrfx_random_ctr_drbg driver.
* If using it outside of this driver it must be used with care specially if any other
* component is using CRACEN.
* It may not be used if any other component is using the CRACEN CM at the same time.
*
* @note This function is not reentrant.
*
* @note The key size needs to be supported by the CRACEN CryptoMaster AES engine.
*/
int nrfx_cracen_cm_aes_ecb(uint8_t *key_p, size_t key_size, uint8_t *input_p, uint8_t *output_p);

#ifdef __cplusplus
}
#endif

#endif /* NRFX_CRACEN_CM_AES_ECB_H */
Loading

0 comments on commit 18fb543

Please sign in to comment.