MC3302_SDK_V1.1.9_202507281.../bsp/test/crypto/cipher.c
2025-11-11 12:08:31 +08:00

419 lines
11 KiB
C
Executable File

/*
* Demo on how to use /dev/crypto device for ciphering.
*
* Placed under public domain.
*
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "crypto/cryptodev.h"
#include "tcrypt.h"
#include "aes.h"
unsigned char * ckey = "\x96\x15\xa0\x41\x7c\xb7\x9d\xcc"
"\x04\x6d\xd0\x3a\x82\x38\x00\xa4";
static const struct cipher_testvec cipher_key = {
.key = "\xc2\x86\x69\x6d\x88\x7c\x9a\xa0"
"\x61\x1b\xbb\x3e\x20\x25\xa4\x5a",
.klen = 16,
.iv = "\x56\x2e\x17\x99\x6d\x09\x3d\x28"
"\xdd\xb3\xba\x69\x5a\x2e\x6f\x58",
.ptext = "\x00\x01\x02\x03\x04\x05\x06\x07"
"\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
"\x10\x11\x12\x13\x14\x15\x16\x17"
"\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
.ctext = "\xd2\x96\xcd\x94\xc2\xcc\xcf\x8a"
"\x3a\x86\x30\x28\xb5\xe1\xdc\x0a"
"\x75\x86\x60\x2d\x25\x3c\xff\xf9"
"\x1b\x82\x66\xbe\xa6\xd6\x1a\xb1",
.len = 32,
};
int aes_ctx_init(struct cryptodev_ctx* ctx, int cfd, const char *key, unsigned int key_size,enum cryptodev_crypto_op_t alg)
{
#ifdef CIOCGSESSINFO
struct session_info_op siop;
#endif
memset(ctx, 0, sizeof(*ctx));
ctx->cfd = cfd;
ctx->sess.cipher = alg;
ctx->sess.keylen = key_size;
ctx->sess.key = (void*)key;
if (ioctl(ctx->cfd, CIOCGSESSION, &ctx->sess)) {
perror("11ioctl(CIOCGSESSION)");
return -1;
}
#ifdef CIOCGSESSINFO
memset(&siop, 0, sizeof(siop));
siop.ses = ctx->sess.ses;
if (ioctl(ctx->cfd, CIOCGSESSINFO, &siop)) {
perror("22ioctl(CIOCGSESSINFO)");
return -1;
}
printf("Got %s with driver %s\n",
siop.cipher_info.cra_name, siop.cipher_info.cra_driver_name);
/*printf("Alignmask is %x\n", (unsigned int)siop.alignmask); */
ctx->alignmask = siop.alignmask;
#endif
return 0;
}
void aes_ctx_deinit(struct cryptodev_ctx* ctx)
{
if (ioctl(ctx->cfd, CIOCFSESSION, &ctx->sess.ses)) {
perror("ioctl(CIOCFSESSION)");
}
}
int
aes_encrypt(struct cryptodev_ctx* ctx, const void* iv, const void* plaintext, void* ciphertext, size_t size)
{
struct crypt_op cryp;
void* p;
/* check plaintext and ciphertext alignment */
if (ctx->alignmask) {
p = (void*)(((unsigned long)plaintext + ctx->alignmask) & ~ctx->alignmask);
if (plaintext != p) {
fprintf(stderr, "plaintext is not aligned\n");
return -1;
}
p = (void*)(((unsigned long)ciphertext + ctx->alignmask) & ~ctx->alignmask);
if (ciphertext != p) {
fprintf(stderr, "ciphertext is not aligned\n");
return -1;
}
}
memset(&cryp, 0, sizeof(cryp));
/* Encrypt data.in to data.encrypted */
cryp.ses = ctx->sess.ses;
cryp.len = size;
cryp.src = (void*)plaintext;
cryp.dst = ciphertext;
cryp.iv = (void*)iv;
cryp.op = COP_ENCRYPT;
//printf("before encrypto cryp.len is %d \r\n",cryp.len);
if (ioctl(ctx->cfd, CIOCCRYPT, &cryp)) {
perror("ioctl(CIOCCRYPT)");
return -1;
}
return 0;
}
int
aes_decrypt(struct cryptodev_ctx* ctx, const void* iv, const void* ciphertext, void* plaintext, size_t size)
{
struct crypt_op cryp;
void* p;
/* check plaintext and ciphertext alignment */
if (ctx->alignmask) {
p = (void*)(((unsigned long)plaintext + ctx->alignmask) & ~ctx->alignmask);
if (plaintext != p) {
fprintf(stderr, "plaintext is not aligned\n");
return -1;
}
p = (void*)(((unsigned long)ciphertext + ctx->alignmask) & ~ctx->alignmask);
if (ciphertext != p) {
fprintf(stderr, "ciphertext is not aligned\n");
return -1;
}
}
memset(&cryp, 0, sizeof(cryp));
/* Encrypt data.in to data.encrypted */
cryp.ses = ctx->sess.ses;
cryp.len = size;
cryp.src = (void*)ciphertext;
cryp.dst = plaintext;
cryp.iv = (void*)iv;
cryp.op = COP_DECRYPT;
if (ioctl(ctx->cfd, CIOCCRYPT, &cryp)) {
perror("ioctl(CIOCCRYPT)");
return -1;
}
return 0;
}
char plaintext_raw[1024] __attribute__((aligned(16)));
char ciphertext_raw[1024] __attribute__((aligned(16)));
static int test_aes_efuse_key(int cfd)
{
struct cryptodev_ctx ctx;
struct cipher_test_info *cipher_test;
const struct cipher_testvec *testvec;
char *plaintext, *ciphertext;
unsigned int cipher_len, block_size,j;
unsigned int test_key[64];
printf("++++++AES EFUSE KEY Test++++++\n");
memset(test_key, 0, sizeof(test_key));
cipher_test = &cipher_efuse_key_test_list[2];
testvec = cipher_test->vecs;
memcpy(test_key, KEY_IN_EFUSE, KEY_IN_EFUSE_LEN);
test_key[KEY_IN_EFUSE_LEN] = 0x0;
for(j = 0; j < 1; j++){
aes_ctx_init(&ctx, cfd, test_key, testvec[j].klen, cipher_test->crypt);
if (ctx.alignmask) {
plaintext = (char *)(((unsigned long)plaintext_raw + ctx.alignmask) & ~ctx.alignmask);
ciphertext = (char *)(((unsigned long)ciphertext_raw + ctx.alignmask) & ~ctx.alignmask);
} else {
plaintext = plaintext_raw;
ciphertext = ciphertext_raw;
}
memset(plaintext, 0 , testvec[j].len);
memset(ciphertext, 0 , testvec[j].len);
memcpy(plaintext, testvec[j].ptext, testvec[j].len);
block_size = ctx.alignmask + 1;
cipher_len = (testvec[j].len + ctx.alignmask) / block_size * block_size ;
aes_encrypt(&ctx, testvec[j].iv, plaintext, ciphertext, cipher_len);
if (memcmp(ciphertext, testvec[j].ctext, testvec[j].len) != 0) {
int k;
fprintf(stderr,
"FAIL: Encrypted data are different from the expect cipher data.\n");
printf("expect ciphertext:");
for (k = 0; k < testvec[j].len; k++) {
printf("%02x ", testvec[j].ctext[k]);
}
printf("encode ciphertext:");
for (k = 0; k < testvec[j].len; k++) {
printf("%02x ", ciphertext[k]);
}
printf("\n");
return 1;
}
aes_ctx_deinit(&ctx);
}
printf("AES EFUSE KEY Test passed\n");
return 0;
}
char test_key[32] = {0};
static int aes_test_key(int cfd)
{
struct cryptodev_ctx ctx;
struct cipher_test_info *cipher_test;
const struct cipher_testvec *testvec;
char *plaintext, *ciphertext;
unsigned int cipher_len, block_size;
char kkey[32];
printf("++++++AES KEY Test++++++\n");
memcpy(test_key, CIPHER_KEY, CIPHER_KEY_LEN);
memcpy(test_key + CIPHER_KEY_LEN, cipher_key.key, cipher_key.klen);
aes_ctx_init(&ctx, cfd, (const char *)test_key, CIPHER_KEY_LEN + cipher_key.klen, CRYPTO_AES_CBC);
printf("ctx.alignmask is %d \r\n",ctx.alignmask);
if (ctx.alignmask) {
plaintext = (char *)(((unsigned long)plaintext_raw + ctx.alignmask) & ~ctx.alignmask);
ciphertext = (char *)(((unsigned long)ciphertext_raw + ctx.alignmask) & ~ctx.alignmask);
} else {
plaintext = plaintext_raw;
ciphertext = ciphertext_raw;
}
memset(plaintext, 0 , cipher_key.len);
memset(ciphertext, 0 , cipher_key.len);
block_size = ctx.alignmask + 1;
cipher_len = (cipher_key.len + ctx.alignmask) / block_size * block_size ;
memcpy(ciphertext, ckey, cipher_key.klen);
/* Encrypt data.in to data.encrypted */
aes_decrypt(&ctx, cipher_key.iv, ciphertext, plaintext, cipher_key.klen);
printf("encode/decode use cipher key\n");
memset(test_key, 0, sizeof(test_key));
memcpy(test_key, USE_CIPHER_KEY, USE_CIPHER_KEY_LEN);
aes_ctx_init(&ctx, cfd, test_key, cipher_key.klen, CRYPTO_AES_CBC);
memset(plaintext, 0 , cipher_key.len);
memset(ciphertext, 0 , cipher_key.len);
memcpy(plaintext, cipher_key.ptext, cipher_key.len);
memcpy(ciphertext, cipher_key.ctext, cipher_key.len);
/* Encrypt data.in to data.encrypted */
aes_decrypt(&ctx, cipher_key.iv, ciphertext, plaintext, cipher_len);
/* Verify the result */
if (memcmp(plaintext, cipher_key.ptext, cipher_key.len) != 0) {
int k;
fprintf(stderr,
"FAIL: Decrypted data are different from the expect plain data.\n");
printf("expect plaintext:");
for (k = 0; k < cipher_key.len; k++) {
printf("%02x ", cipher_key.ptext[k]);
}
printf("decode plaintext:");
for (k = 0; k < cipher_key.len; k++) {
printf("%02x ", plaintext[k]);
}
printf("\n");
return 1;
}
aes_ctx_deinit(&ctx);
printf("AES KEY Test passed\n");
return 0;
}
static int test_aes(int cfd)
{
struct cryptodev_ctx ctx;
struct cipher_test_info *cipher_test;
const struct cipher_testvec *testvec;
char *plaintext, *ciphertext;
unsigned int cipher_len, block_size;
unsigned int i , j;
for(i = 0; i < ARRAY_SIZE(cipher_test_list); i++) {
cipher_test = &cipher_test_list[i];
testvec = cipher_test->vecs;
for(j = 0; j < cipher_test->count; j++) {
aes_ctx_init(&ctx, cfd, testvec[j].key, testvec[j].klen, cipher_test->crypt);
if (ctx.alignmask) {
plaintext = (char *)(((unsigned long)plaintext_raw + ctx.alignmask) & ~ctx.alignmask);
ciphertext = (char *)(((unsigned long)ciphertext_raw + ctx.alignmask) & ~ctx.alignmask);
} else {
plaintext = plaintext_raw;
ciphertext = ciphertext_raw;
}
memset(plaintext, 0 , testvec[j].len);
memset(ciphertext, 0 , testvec[j].len);
memcpy(plaintext, testvec[j].ptext, testvec[j].len);
block_size = ctx.alignmask + 1;
cipher_len = (testvec[j].len + ctx.alignmask) / block_size * block_size ;
/* Encrypt data.in to data.encrypted */
aes_encrypt(&ctx, testvec[j].iv, plaintext, ciphertext, cipher_len);
/* Verify the result */
if (memcmp(ciphertext, testvec[j].ctext, testvec[j].len) != 0) {
int k;
fprintf(stderr,
"FAIL: Encrypted data are different from the expect cipher data.\n");
// printf("expect ciphertext:");
for (k = 0; k < testvec[j].len; k++) {
printf("%02x ", testvec[j].ctext[k]);
}
printf("encode ciphertext:");
for (k = 0; k < testvec[j].len; k++) {
//printf("%02x ", ciphertext[k]);
}
printf("\n");
return 1;
}
memset(plaintext, 0 , testvec[j].len);
memset(ciphertext, 0 , testvec[j].len);
memcpy(ciphertext, testvec[j].ctext, testvec[j].len);
/* Encrypt data.in to data.encrypted */
aes_decrypt(&ctx, testvec[j].iv, ciphertext, plaintext, cipher_len);
/* Verify the result */
if (memcmp(plaintext, testvec[j].ptext, testvec[j].len) != 0) {
int k;
fprintf(stderr,
"FAIL: Decrypted data are different from the expect plain data.\n");
printf("expect plaintext:");
for (k = 0; k < testvec[j].len; k++) {
// printf("%02x ", testvec[j].ptext[k]);
}
//printf("decode plaintext:");
for (k = 0; k < testvec[j].len; k++) {
// printf("%02x ", plaintext[k]);
}
//printf("\n");
return 1;
}
aes_ctx_deinit(&ctx);
}
}
printf("AES Test passed\n");
return 0;
}
int
main()
{
int cfd = -1;
//printf("crypto.................................\r\n");
/* Open the crypto device */
cfd = open("/dev/crypto", O_RDWR, 0);
if (cfd < 0) {
perror("open(/dev/crypto)");
return 1;
}
/* Set close-on-exec (not really neede here) */
if (fcntl(cfd, F_SETFD, 1) == -1) {
perror("fcntl(F_SETFD)");
return 1;
}
/* Run the test itself */
if (test_aes(cfd))
return 1;
#if 0
if (test_aes_efuse_key(cfd)) {
printf("test aes efuse key failed");
}
#endif
//cipher key
if (aes_test_key(cfd)) {
printf("test aes cipher key failed");
return 1;
}
/* Close the original descriptor */
if (close(cfd)) {
perror("close(cfd)");
return 1;
}
return 0;
}