Reputation: 1
Thank you very much for any help in advance. I am a beginner so excuse me if this is a dumb question.
I am trying to make a simple random number generator. I am using the MCUxpresso IDE and created a new project with Semihost as the debug option. I also checked 'middleware/security/MbedTLS' to include the library in my code. I attached a picture of the file structure. I also attached below the code I am using.
IMG: File structure. Default project from MCUXpresso with added Mbedtls
I have followed the steps from the official documentation, found here: https://mbed-tls.readthedocs.io/en/latest/kb/how-to/add-a-random-generator/
/*
* Copyright 2016-2024 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
/**
* @file crypto_test.c
* @brief Application entry point.
*/
#include <stdio.h>
#include "board.h"
#include "peripherals.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "fsl_debug_console.h"
/* TODO: insert other include files here. */
#include "mbedtls/entropy.h" //entropy source
#include "mbedtls/ctr_drbg.h" //random number generation
/* TODO: insert other definitions and declarations here. */
/*
* @brief Application entry point.
*/
int main(void) {
/* Init board hardware. */
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitBootPeripherals();
#ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL
/* Init FSL debug console. */
BOARD_InitDebugConsole();
#endif
//initialize random number generator
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_ctr_drbg_init( &ctr_drbg );
//prepare the entropy initialization
mbedtls_entropy_context entropy;
mbedtls_entropy_init( &entropy );
char *personalization = "test"; //helps add random initial seeding ?
int ret = mbedtls_ctr_drbg_seed( &ctr_drbg , mbedtls_entropy_func, &entropy, (const unsigned char *) personalization, strlen( personalization ) );
// ret = mbedtls_ctr_drbg_seed( &ctr_drbg , mbedtls_entropy_func, NULL, NULL, 0 );
PRINTF("%d", ret);
if (ret != 0) {
PRINTF("eror in seeding the random number generator");
return -1;
}
PRINTF("RNG ready");
// /* Force the counter to be placed into memory. */
// volatile static int i = 0 ;
// /* Enter an infinite loop, just incrementing a counter. */
// while(1) {
// i++ ;
// /* 'Dummy' NOP to allow source level single stepping of
// tight while() loop */
// __asm volatile ("nop");
// }
// return 0 ;
}
The problamatic line is here:
int ret = mbedtls_ctr_drbg_seed( &ctr_drbg , mbedtls_entropy_func, &entropy, (const unsigned char *) personalization, strlen( personalization ) );
I recieve this error: Forced and Stack overflow errors
Semihost Hardfault:
// ****************************************************************************
// semihost_hardfault.c
// - Provides hard fault handler to allow semihosting code not
// to hang application when debugger not connected.
//
// ****************************************************************************
// Copyright 2017-2024 NXP
// All rights reserved.
//
// SPDX-License-Identifier: BSD-3-Clause
// ****************************************************************************
//
// ===== DESCRIPTION =====
//
// One of the issues with applications that make use of semihosting operations
// (such as printf calls) is that the code will not execute correctly when the
// debugger is not connected. Generally this will show up with the application
// appearing to just hang. This may include the application running from reset
// or powering up the board (with the application already in FLASH), and also
// as the application failing to continue to execute after a debug session is
// terminated.
//
// The problem here is that the "bottom layer" of the semihosted variants of
// the C library, semihosting is implemented by a "BKPT 0xAB" instruction.
// When the debug tools are not connected, this instruction triggers a hard
// fault - and the default hard fault handler within an application will
// typically just contains an infinite loop - causing the application to
// appear to have hang when no debugger is connected.
//
// The below code provides an example hard fault handler which instead looks
// to see what the instruction that caused the hard fault was - and if it
// was a "BKPT 0xAB", then it instead returns back to the user application.
//
// In most cases this will allow applications containing semihosting
// operations to execute (to some degree) when the debugger is not connected.
//
// == NOTE ==
//
// Correct execution of the application containing semihosted operations
// which are vectored onto this hard fault handler cannot be guaranteed. This
// is because the handler may not return data or return codes that the higher
// level C library code or application code expects. This hard fault handler
// is meant as a development aid, and it is not recommended to leave
// semihosted code in a production build of your application!
//
// ****************************************************************************
// Allow handler to be removed by setting a define (via command line)
#if !defined (__SEMIHOST_HARDFAULT_DISABLE)
__attribute__((naked))
void HardFault_Handler(void){
__asm( ".syntax unified\n"
// Check which stack is in use
"MOVS R0, #4 \n"
"MOV R1, LR \n"
"TST R0, R1 \n"
"BEQ _MSP \n"
"MRS R0, PSP \n"
"B _process \n"
"_MSP: \n"
"MRS R0, MSP \n"
// Load the instruction that triggered hard fault
"_process: \n"
"LDR R1,[R0,#24] \n"
"LDRH R2,[r1] \n"
// Semihosting instruction is "BKPT 0xAB" (0xBEAB)
"LDR R3,=0xBEAB \n"
"CMP R2,R3 \n"
"BEQ _semihost_return \n"
// Wasn't semihosting instruction so enter infinite loop
"B . \n"
// Was semihosting instruction, so adjust location to
// return to by 1 instruction (2 bytes), then exit function
"_semihost_return: \n"
"ADDS R1,#2 \n"
"STR R1,[R0,#24] \n"
// Set a return value from semihosting operation.
// 0 is slightly arbitrary, but appears to allow most
// C Library IO functions sitting on top of semihosting to
// continue to operate to some degree
// Return a positive value (32) for SYS_OPEN only
"LDR R1,[ R0,#0 ] \n" // R0 is at location 0 on stack
"CMP R1, #1 \n" // 0x01=SYS_OPEN
"BEQ _non_zero_ret \n"
"MOVS R1,#0 \n"
"B _sys_ret \n"
"_non_zero_ret: \n"
"MOVS R1,#32 \n"
"_sys_ret: \n"
"STR R1,[ R0,#0 ] \n" // R0 is at location 0 on stack
// Return from hard fault handler to application
"BX LR \n"
".syntax divided\n") ;
}
#endif
The error in sha512 points to: /mbedtls/library/sha512.c
while (ilen >= 128) {
if ((ret = mbedtls_internal_sha512_process(ctx, input)) != 0) {
return ret;
}
input += 128;
ilen -= 128;
}
What have I tried?
unsigned char buf[16];
int entropy_ret = mbedtls_entropy_func(&entropy, buf, sizeof(buf));
if (entropy_ret != 0) {
PRINTF("Entropy source failed: %d\r\n", entropy_ret);
return -1;
} else {
PRINTF("%d", entropy_ret);
}
This seemed to work as it returned '0'. This tells me it is not a entropy issue (the common issue online)
Checking the stack: Here it shows in the explorer that the stack is not over 100%... IMG: Stack is only 45% utilized
Exploring the stack trace:
IMG: Stack Trace
Here can you see it was this: mbedtls_internal_sha512_process() at sha512.c:184 0x678
Following mbedtls_sha512_update_ret() at sha512.c:327 0x5cca
That caused the fault (I think)
Replacing the problamatic line: This was the line causing error:
int ret = mbedtls_ctr_drbg_seed( &ctr_drbg , mbedtls_entropy_func, &entropy, (const unsigned char *) personalization, strlen( personalization ) );
Replaced with:
ret = mbedtls_ctr_drbg_seed( &ctr_drbg , mbedtls_entropy_func, NULL, NULL, 0 );
I replaced because looking through the example files (/lpcxpresso55s69_mbedtls_benchmark on line 1073) used mbedtls_ctr_drbg_seed like this:
if (mbedtls_ctr_drbg_seed(&ctr_drbg, myrand, NULL, NULL, 0) != 0) {
mbedtls_exit(1);
}
This caused the program to NOT have the semihost hard fault. Instead, it caused the program to hang and not continue.
Any guidance on how to solve this would be greatly appreciated!!!
Upvotes: 0
Views: 37