C language AES algorithm implementation (based on Mbedtls)

Posted by kiosklim on Tue, 21 Jan 2020 15:48:54 +0100

In recent projects, AES algorithm needs to be implemented by C language. Here I implement it by Mbedtls library.

1. Download Mbedtls

First, we put the Mbedtls code into the project, and the related transmission gates are as follows:

Official download address of Mbedtls

The official website is slow download abroad, so the Mbedtls code used in this article is also attached. The portal is as follows:

Mbedtls encryption and decryption tool code

2. Import Mbedtls header file

Here, we introduce the header file of Mbedtls into CMakeLists.txt in the project. The code is as follows:

# for debug
# add_compile_options(-g)

project("device-authentication")

cmake_minimum_required(VERSION 3.5)

INCLUDE_DIRECTORIES(
	../include/
    ../../src/net/mbedtls/include
	../../src/smalgo/sms4/include
)

SET(my_src_crypto
    ../../src/net/mbedtls/library/aes.c
    ../../src/net/mbedtls/library/aesni.c
    ../../src/net/mbedtls/library/base64.c
    ../../src/net/mbedtls/library/rsa.c
    ../../src/net/mbedtls/library/rsa_internal.c
    ../../src/net/mbedtls/library/entropy.c
    ../../src/net/mbedtls/library/entropy_poll.c
    ../../src/net/mbedtls/library/bignum.c
    ../../src/net/mbedtls/library/sha1.c
    ../../src/net/mbedtls/library/sha256.c
    ../../src/net/mbedtls/library/sha512.c
    ../../src/net/mbedtls/library/md.c
    ../../src/net/mbedtls/library/md5.c
    ../../src/net/mbedtls/library/md_wrap.c
    ../../src/net/mbedtls/library/ripemd160.c
    ../../src/net/mbedtls/library/platform_util.c
    ../../src/net/mbedtls/library/oid.c
    ../../src/net/mbedtls/library/timing.c
    ../../src/net/mbedtls/library/net_sockets.c
	../../src/smalgo/sms4/cbc128.c
	../../src/smalgo/sms4/sms4_cbc.c
	../../src/smalgo/sms4/sms4_common.c
	../../src/smalgo/sms4/sms4_enc.c
	../../src/smalgo/sms4/sms4_setkey.c
)
SET(my_src_crypto_dbg
    ../../src/net/mbedtls/library/ctr_drbg.c
)

SET(SRC_LIST_ENCRYPT_BIN
		oem_porting.c
		sdk_porting.c
		authref.c
		test.c
		${my_src_crypto}
		${my_src_crypto_dbg}
		)

SET(SRC_LIST_DECRYPT_LIB 
    oem_porting.c
    sdk_porting.c
    authref.c
    auth.c
    ${my_src_crypto}
    ${my_src_crypto_dbg}
		)

#SET(SRC_LIST_AUTH_DEV
#    oem_porting.c
#    sdk_porting.c
#    authref.c
#    ${my_src_crypto}
#    ${my_src_crypto_dbg}
#)

add_definitions(-fPIC)
#ADD_LIBRARY(authd STATIC ${SRC_LIST_AUTH_DEV})
ADD_LIBRARY(authoal STATIC ${SRC_LIST_DECRYPT_LIB})
ADD_EXECUTABLE(eaidkAuth ${SRC_LIST_ENCRYPT_BIN})

The project structure is as follows:

   

After the introduction, we can start to write AES code.

3. AES coding

The code of authref.h header file is as follows:

#ifndef __AUTHREF_H__
#define __AUTHREF_H__
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#undef DEBUG

#define AES_KEY_SIZE     48
#define AES_IV_LEN       16

#ifdef __cplusplus
extern "C" {
#endif

// aes encryption
// aes_key -- Maximum 48 bytes
// iv -- up to 16 bytes
// plaintext -- text to be encrypted
// ciphertext -- encrypted text
// len -- len should be 16*N bytes
// return – 0 for ok, else for error
int aes_cbc_encryp(uint8_t *aes_key, uint8_t *iv, uint8_t *plaintext, uint8_t *ciphertext, uint32_t len);

// aes decryption
// aes_key -- Maximum 48 bytes
// iv -- up to 16 bytes
// ciphertext -- text to be decrypted
// plaintext -- decrypt good text
// len -- len should be 16*N bytes
// return – 0 for ok, else for error
int aes_cbc_decryp(uint8_t *aes_key, uint8_t *iv, uint8_t *ciphertext, uint8_t *plaintext, uint32_t len);

#ifdef __cplusplus
}
#endif

#endif //__AUTHREF_H__

The authref.c code is as follows:

#include "authref.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/aes.h"

//len should be 16*N bytes
int aes_cbc_encryp(uint8_t *aes_key, uint8_t *iv, uint8_t *plaintext, uint8_t *ciphertext, uint32_t len) {
    int i;
    int blk = (len + 15) >> 4;
    mbedtls_aes_context aes_ctx;
    mbedtls_aes_init(&aes_ctx);
    //setkey_dec
    mbedtls_aes_setkey_enc(&aes_ctx, aes_key, 256);
    for (i = 0; i < blk; ++i) {
        mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_ENCRYPT, 16, iv, plaintext + (i * 16), ciphertext + (i * 16));
    }
    mbedtls_aes_free(&aes_ctx);
    return 0; //OK
}

//len should be 16*N bytes
int aes_cbc_decryp(uint8_t *aes_key, uint8_t *iv, uint8_t *ciphertext, uint8_t *plaintext, uint32_t len) {
    int i;
    int blk = (len + 15) >> 4;
    mbedtls_aes_context aes_ctx;
    mbedtls_aes_init(&aes_ctx);
    //setkey_dec
    mbedtls_aes_setkey_dec(&aes_ctx, aes_key, 256);
    for (i = 0; i < blk; ++i) {
        mbedtls_aes_crypt_cbc(&aes_ctx, MBEDTLS_AES_DECRYPT, 16, iv, ciphertext + (i * 16), plaintext + (i * 16));
    }
    mbedtls_aes_free(&aes_ctx);
    return 0; //OK
}

AES encryption / decryption pseudo code is as follows:

ret = aes_cbc_encryp(&key, &iv, uuid, (uint8_t*)&data, 64); 
ret = aes_cbc_decryp(&key, &iv, uuid, (uint8_t*)&data, 64); 

This is the end of the AES encryption and decryption introduction.

343 original articles published, 376 praised, 360000 visitors+
His message board follow

Topics: SHA1 C