How to Improve the Security of Embedded Bootloader Programs

The field of embedded applications is becoming more and more extensive, and the functional requirements are becoming more and more complicated. Some embedded products require the function of firmware upgrade to remain in use after the product is shipped, so as to ensure that users can use the latest functions and correct products in time. Bug. Supporting firmware upgrade means that there is a “backdoor” left on the software, that is, interaction between the Bootloader and the outside world. If the “backdoor” is improperly protected, it will cause the firmware code to leak. For this security risk, the topic discussed in this article is how to improve the embedded The security of the Bootloader program effectively prevents hacker hacking and cloning. The tool used is the mbed TLS encryption algorithm library of arm.

mbedTLS Overview

MbedTLS, formerly the open source encryption algorithm library PolarSSL, is now acquired by arm and maintained by the arm technical team. It is an algorithm library for TLS and SSL protocols.

mbedTLS's goals are: easy to understand, use, integrate and extend. The mbedTLS core code is written in the C programming language, implements SSL modules and various encryption algorithms, and provides self-test code for various encryption algorithms. Unlike other implementations of the TLS/SSL algorithm library, mbedTLS is primarily intended for small embedded devices. The code is compact, and the smallest and complete TLS stack requires 60 KB of program space and 64 KB of RAM space. This is highly efficient and can be said to be the most compact in the industry. SSL encryption algorithm library.

mbedTLS is a highly modular design: each component, such as an encryption function, can be used independently of the rest of the framework. mbedTLS is written entirely in C language and has no external dependencies. Therefore, mbedTLS is the ideal TLS encryption algorithm library for embedded systems. More importantly, mbedTSL is fully OpenSource and supports dual licensing of Apache 2.0 license or GPL 2.0 license, which can be freely used in commercial projects.

Application and Implementation

Shanghai Runxin Technology is developing a fingerprint module project for smart door locks and other fields. The main control chip used is an ARM Cortex-M4 core MCU, but this MCU does not have code readout protection function in order to avoid illegal products. For cloning, a protection mechanism must be introduced to improve product safety. We use the RSASSA-PSS digital signature algorithm in the mbedTSL algorithm library to sign and verify the UID and fingerprint sensor UID in the MCU chip to ensure that each signed product is unique (unreplicable) and legal. Sex.

Original Sign (Sign) and Signature Verification

Specific implementation steps

Step 1: Store the private key in the key pair generated by mbedTLS with the local server and disable external access to ensure the security of the private key;

Step 2: Generate a digital signature sig file using the UID of the MCU and the UID of the fingerprint sensor through the private key and the signature generation tool on the local server.

Step 3: Save the sig signature file generated in the above second step to a specific area of ​​the Bootloader.

Step 4: Save the public key in the key pair generated by mbedTLS to the APP firmware.

Step 5: When the Bootloader updates the APP firmware, the signature file sig in the Bootloader is verified with the public key in the APP. If the verification passes, it indicates that the Bootloader and the APP firmware are all original legal firmware; otherwise, the Bootloader refuses to boot. Execute the APP firmware to achieve the purpose of protecting the soft and hard copyright of the product.

Used mbedTLS resources and API functions

1. Use the VS2010 or above version of the mbedTSL code package directory to generate the RSA key pair generation tool: rsa_genkey.exe, which is used to generate the key pair in the first step of the above step;

2. Generate the RSASSA signature generation tool rsa_sign_pss.exe using VS2010 or above in the mbedTSL code package directory to generate the sig file in the second step of the above steps;

3. The RSASSA signature verification tool rsa_verify_pss.exe is generated using the VS2010 or above in the mbedTSL code package directory, which ensures the correctness of the code.

4. The mbedTLS API function used in the MCU code:

/*

* Initialize an RSA context to initialize the contents of the RSA algorithm

*/

Void mbedtls_rsa_init( mbedtls_rsa_context *ctx,

Int padding,

Int hash_id )

{

Memset( ctx, 0, sizeof( mbedtls_rsa_context ) );

Mbedtls_rsa_set_padding( ctx, padding, hash_id );

#if defined(MBEDTLS_THREADING_C)

Mbedtls_mutex_init( &ctx->mutex );

#endif

}

#if defined(MBEDTLS_PKCS1_V21)

/*

* Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function

* RSASSA-PSS signature algorithm implementation function

*/

Int mbedtls_rsa_rsassa_pss_sign( mbedtls_rsa_context *ctx,

Int (*f_rng)(void *, unsigned char *, size_t),

Void *p_rng,

Int mode,

Mbedtls_md_type_t md_alg,

Unsigned int hashlen,

Const unsigned char *hash,

Unsigned char *sig )

{

Size_t olen;

Unsigned char *p = sig;

Unsigned char salt[MBEDTLS_MD_MAX_SIZE];

Unsigned int slen, hlen, offset = 0;

Int ret;

Size_t msb;

Const mbedtls_md_info_t *md_info;

Mbedtls_md_context_t md_ctx;

If( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )

Return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );

If( f_rng == NULL )

Return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );

Olen = ctx->len;

If( md_alg != MBEDTLS_MD_NONE )

{

/* Gather length of hash to sign */

Md_info = mbedtls_md_info_from_type( md_alg );

If( md_info == NULL )

Return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );

Hashlen = mbedtls_md_get_size( md_info );

}

Md_info = mbedtls_md_info_from_type( (mbedtls_md_type_t) ctx->hash_id );

If( md_info == NULL )

Return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );

Hlen = mbedtls_md_get_size( md_info );

Slen = hlen;

If( olen < hlen + slen + 2 )

Return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );

Memset( sig, 0, olen );

/* Generate salt of length slen */

If( (ret = f_rng( p_rng, salt, slen ) )= 0 )

Return( MBEDTLS_ERR_RSA_RNG_FAILED + ret );

/* Note: EMSA-PSS encoding is over the length of N - 1 bits */

Msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;

p += olen - hlen * 2 - 2;

*p++ = 0x01;

Memcpy( p, salt, slen );

p += slen;

Mbedtls_md_init( &md_ctx );

If( (ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) )= 0 )

Goto exit;

/* Generate H = Hash( M' ) */

If( (ret = mbedtls_md_starts( &md_ctx )) != 0 )

Goto exit;

If( (ret = mbedtls_md_update( &md_ctx, p, 8 )) != 0 )

Goto exit;

If( (ret = mbedtls_md_update( &md_ctx, hash, hashlen ) != 0 )

Goto exit;

If( (ret = mbedtls_md_update( &md_ctx, salt, slen ) )= 0 )

Goto exit;

If( (ret = mbedtls_md_finish( &md_ctx, p )) != 0 )

Goto exit;

/* Compensate for boundary condition when applying mask */

If( msb % 8 == 0 )

Offset = 1;

/* maskedDB: Apply dbMask to DB */

If( (ret = mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen,

&md_ctx ) )= 0 )

Goto exit;

Msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;

Sig[0] &= 0xFF >> (olen * 8 - msb );

p += hlen;

*p++ = 0xBC;

Mbedtls_zeroize( salt, sizeof( salt ) );

Exit:

Mbedtls_md_free( &md_ctx );

If( ret != 0 )

Return( ret );

Return( ( mode == MBEDTLS_RSA_PUBLIC )

Mbedtls_rsa_public( ctx, sig, sig )

: mbedtls_rsa_private( ctx, f_rng, p_rng, sig, sig );

}

#endif /* MBEDTLS_PKCS1_V21 */

#if defined(MBEDTLS_PKCS1_V21)

/*

* Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function

* RSASSA-PSS signature algorithm check function

*/

Int mbedtls_rsa_rsassa_pss_verify_ext( mbedtls_rsa_context *ctx,

Int (*f_rng)(void *, unsigned char *, size_t),

Void *p_rng,

Int mode,

Mbedtls_md_type_t md_alg,

Unsigned int hashlen,

Const unsigned char *hash,

Mbedtls_md_type_t mgf1_hash_id,

Int expected_salt_len,

Const unsigned char *sig )

{

Int ret;

Size_t siglen;

Unsigned char *p;

Unsigned char *hash_start;

Unsigned char result[MBEDTLS_MD_MAX_SIZE];

Unsigned char zeros[8];

Unsigned int hlen;

Size_t observed_salt_len, msb;

Const mbedtls_md_info_t *md_info;

Mbedtls_md_context_t md_ctx;

Unsigned char buf[MBEDTLS_MPI_MAX_SIZE];

If( mode == MBEDTLS_RSA_PRIVATE && ctx->padding != MBEDTLS_RSA_PKCS_V21 )

Return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );

Siglen = ctx->len;

If( siglen < 16 || siglen > sizeof( buf ) )

Return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );

Ret = ( mode == MBEDTLS_RSA_PUBLIC )

Mbedtls_rsa_public( ctx, sig, buf )

: mbedtls_rsa_private( ctx, f_rng, p_rng, sig, buf );

If( ret != 0 )

Return( ret );

p = buf;

If( buf[siglen - 1] != 0xBC )

Return( MBEDTLS_ERR_RSA_INVALID_PADDING );

If( md_alg != MBEDTLS_MD_NONE )

{

/* Gather length of hash to sign */

Md_info = mbedtls_md_info_from_type( md_alg );

If( md_info == NULL )

Return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );

Hashlen = mbedtls_md_get_size( md_info );

}

Md_info = mbedtls_md_info_from_type( mgf1_hash_id );

If( md_info == NULL )

Return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );

Hlen = mbedtls_md_get_size( md_info );

Memset( zeros, 0, 8 );

/*

* Note: EMSA-PSS verification is over the length of N - 1 bits

*/

Msb = mbedtls_mpi_bitlen( &ctx->N ) - 1;

If( buf[0] >> ( 8 - siglen * 8 + msb )

Return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );

/* Compensate for boundary condition when applying mask */

If( msb % 8 == 0 )

{

p++;

Siglen -= 1;

}

If( siglen < hlen + 2 )

Return( MBEDTLS_ERR_RSA_BAD_INPUT_DATA );

Hash_start = p + siglen - hlen - 1;

Mbedtls_md_init( &md_ctx );

If( (ret = mbedtls_md_setup( &md_ctx, md_info, 0 ) )= 0 )

Goto exit;

Ret = mgf_mask( p, siglen - hlen - 1, hash_start, hlen, &md_ctx );

If( ret != 0 )

Goto exit;

Buf[0] &= 0xFF >> ( siglen * 8 - msb );

While( p < hash_start - 1 && *p == 0 )

p++;

If( *p++ != 0x01 )

{

Ret = MBEDTLS_ERR_RSA_INVALID_PADDING;

Goto exit;

}

Observed_salt_len = hash_start - p;

If( expected_salt_len != MBEDTLS_RSA_SALT_LEN_ANY &&

Observed_salt_len != (size_t) expected_salt_len )

{

Ret = MBEDTLS_ERR_RSA_INVALID_PADDING;

Goto exit;

}

/*

* Generate H = Hash( M' )

*/

Ret = mbedtls_md_starts( &md_ctx );

If ( ret != 0 )

Goto exit;

Ret = mbedtls_md_update( &md_ctx, zeros, 8 );

If ( ret != 0 )

Goto exit;

Ret = mbedtls_md_update( &md_ctx, hash, hashlen );

If ( ret != 0 )

Goto exit;

Ret = mbedtls_md_update( &md_ctx, p, observed_salt_len );

If ( ret != 0 )

Goto exit;

Ret = mbedtls_md_finish( &md_ctx, result );

If ( ret != 0 )

Goto exit;

If( memcmp( hash_start, result, hlen ) != 0 )

{

Ret = MBEDTLS_ERR_RSA_VERIFY_FAILED;

Goto exit;

}

Exit:

Mbedtls_md_free( &md_ctx );

Return( ret );

}

/*

* Simplified PKCS#1 v2.1 RSASSA-PSS-VERIFY function

*/

Int mbedtls_rsa_rsassa_pss_verify( mbedtls_rsa_context *ctx,

Int (*f_rng)(void *, unsigned char *, size_t),

Void *p_rng,

Int mode,

Mbedtls_md_type_t md_alg,

Unsigned int hashlen,

Const unsigned char *hash,

Const unsigned char *sig )

{

Mbedtls_md_type_t mgf1_hash_id = ( ctx->hash_id != MBEDTLS_MD_NONE )

(mbedtls_md_type_t) ctx->hash_id

: md_alg;

Return( mbedtls_rsa_rsassa_pss_verify_ext( ctx, f_rng, p_rng, mode,

Md_alg, hashlen, hash,

Mgf1_hash_id, MBEDTLS_RSA_SALT_LEN_ANY,

Sig ));

}

#endif /* MBEDTLS_PKCS1_V21 */

Hoodie Jacket

Hoodie Jacket,Beige Hoodie,Hooded Shirts And Tops,Hoodies For Women

GUANGZHOU LIWEI ELECTRONICS CO.,LTD , https://www.gdliwei.com