嵌入式安全实验—密码算法
- 创建一个新密码算法的内核模块,生成该模块的 .ko文件。
- 将新 .ko文件插入内核
- 通过算法接口使用新密码算法,如加密,解密文件,验证其有效性。
- 将新算法用在加密存储和加密通信中
内核模块新密码算法
embcipher.c
#include <linux/types.h>
#include <linux/crypto.h>
#include <linux/module.h>
#include <linux/init.h>
#define EMB_MIN_KEY_SIZE 16
#define EMB_MAX_KEY_SIZE 16
#define EMB_BLOCK_SIZE 16
struct emb_ctx {
u8 key[256];
u8 klen;
};
int crypto_emb_setkey(struct crypto_tfm* tfm, const u8* in_key, unsigned int key_len)
{
struct emb_ctx* ctx = crypto_tfm_ctx(tfm);
return 0;
}
static void crypto_emb_encrypt(struct crypto_tfm* tfm, u8* out, const u8* in)
{
// const struct emb_ctx *ctx = crypto_tfm_ctx(tfm);
u32 i;
const int len = tfm->__crt_alg->cra_blocksize;
for (i = 0; i < len; i++)
out[i] = in[len - 1 - i];
}
static void crypto_emb_decrypt(struct crypto_tfm* tfm, u8* out, const u8* in)
{
}
static struct crypto_alg emb_alg = {
.cra_name = "emb",
.cra_driver_name = "emb-generic",
.cra_priority = 100,
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
.cra_blocksize = EMB_BLOCK_SIZE,
.cra_ctxsize = sizeof(struct emb_ctx),
.cra_module = THIS_MODULE,
.cra_u = {
.cipher = {
.cia_min_keysize = EMB_MIN_KEY_SIZE,
.cia_max_keysize = EMB_MAX_KEY_SIZE,
.cia_setkey = crypto_emb_setkey,
.cia_encrypt = crypto_emb_encrypt,
.cia_decrypt = crypto_emb_decrypt
}
}
};
static int __init emb_init(void)
{
return crypto_register_alg(&emb_alg);
}
static void __exit emb_fini(void)
{
crypto_unregister_alg(&emb_alg);
}
subsys_initcall(emb_init);
module_exit(emb_fini);
MODULE_DESCRIPTION("Embedded Test Cipher Algorithm");
MODULE_LICENSE("Dual BSD/GPL");
MODULE_ALIAS_CRYPTO("emb");
MODULE_ALIAS_CRYPTO("emb-generic");
对应的Makefile
文件
#Makefile for embcipher
obj-m += embcipher.o
KERNELDIR :=/lib/modules/$(shell uname -r)/build
all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean
编译
编译后文件夹内如下
将加密模块插入内核
用户空间应用程序
ecbemb.c
#include <stdio.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/if_alg.h>
#include <linux/socket.h>
#include <string.h>
#ifndef SOL_ALG
#define SOL_ALG 279
#endif
int main(void) {
int opfd;
int tfmfd;
struct sockaddr_alg sa = {
.salg_family = AF_ALG,
.salg_type = "skcipher",
.salg_name = "ecb(emb)"
};
struct msghdr msg = {};
struct cmsghdr *cmsg;
char cbuf[CMSG_SPACE(4) + CMSG_SPACE(20)] = {0};
char buf[17];
struct af_alg_iv *iv;
struct iovec iov;
int i;
tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
bind(tfmfd, (struct sockaddr *)&sa, sizeof(sa));
setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY,
"\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
"\x51\x2e\x03\xd5\x34\x12\x00\x06", 16);
opfd = accept(tfmfd, NULL, 0);
msg.msg_control = cbuf;
msg.msg_controllen = sizeof(cbuf);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_level = SOL_ALG;
cmsg->cmsg_type = ALG_SET_OP;
cmsg->cmsg_len = CMSG_LEN(4);
*(__u32 *)CMSG_DATA(cmsg) = ALG_OP_ENCRYPT; //ALG_OP_DECRYPT;
cmsg = CMSG_NXTHDR(&msg, cmsg);
cmsg->cmsg_level = SOL_ALG;
cmsg->cmsg_type = ALG_SET_IV;
cmsg->cmsg_len = CMSG_LEN(20);
iov.iov_base = "Single block msg, Hello World!!!";
iov.iov_len = 32;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
sendmsg(opfd, &msg, 0);
read(opfd, buf, 16);
for (i = 0; i < 16; i++) {
printf("%02x", (unsigned char)buf[i]);
}
printf("\n");
buf[16]=0;
printf("%s\n",buf);
read(opfd, buf, 16);
for (i = 0; i < 16; i++) {
printf("%02x", (unsigned char)buf[i]);
}
printf("\n");
buf[16]=0;
printf("%s\n",buf);
close(opfd);
close(tfmfd);
return 0;
}
编译运行