使用Netlink AF_ALG调用内核态密码模块

目录

检查当前socket是否支持AF_ALG协议

实现自己的内核态密码模块接口

模仿内核源代码linux/crypto/aes_generic.c实现自己的算法

实现Netlink AF_ALG协议调用内核态密码模块里的对称加密

使用libkcapi库完成内核态密码模块的调用

 OpenSSL支持AF_ALG引擎


检查当前socket是否支持AF_ALG协议

af_alg_check.c

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if_alg.h>

int main()
{
    int sockfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
    if(sockfd == -1)
    {
        if(errno == EAFNOSUPPORT)
        {
            printf("#define AF_ALG_UNAVAILABLE\n");
        } else {
            printf("socket api occurs other errors\n");
        }
    } else {
        printf("#define AF_ALG_AVAILABLE\n");
    }

    close(sockfd);
    return 0;
}

 编译并运行

# gcc af_alg_check.c -o af_alg_check
# ./af_alg_check
 #define AF_ALG_AVAILABLE

打印 “#define AF_ALG_AVAILABLE” 说明socket 支持AF_ALG 协议;

打印 “#define AF_ALG_UNAVAILABLE” 说明socket 不支持AF_ALG 协议。

实现自己的内核态密码模块接口

使用github上示例代码完成内核态密码模块

# git clone https://github.com/Ed-Yang/crypto-examples.git
# cd crypto-examples/
# cd aes-example
# make
# sudo dmesg -C
# sudo insmod aes-example.ko
# sudo rmmod aes-example.ko
# sudo dmesg

模仿内核源代码linux/crypto/aes_generic.c实现自己的算法

my_aes_generic.c  (只是替换了算法名称,修改部分如下)

static struct crypto_alg aes_alg = {
	.cra_name		=	"my_aes",
	.cra_driver_name	=	"my_aes-generic",
	.cra_priority		=	100,
	.cra_flags		=	CRYPTO_ALG_TYPE_CIPHER,
	.cra_blocksize		=	AES_BLOCK_SIZE,
	.cra_ctxsize		=	sizeof(struct crypto_aes_ctx),
	.cra_module		=	THIS_MODULE,
	.cra_u			=	{
		.cipher = {
			.cia_min_keysize	=	AES_MIN_KEY_SIZE,
			.cia_max_keysize	=	AES_MAX_KEY_SIZE,
			.cia_setkey		=	crypto_aes_set_key,
			.cia_encrypt		=	crypto_aes_encrypt,
			.cia_decrypt		=	crypto_aes_decrypt
		}
	}
};

static int __init aes_init(void)
{
	return crypto_register_alg(&aes_alg);
}

static void __exit aes_fini(void)
{
	crypto_unregister_alg(&aes_alg);
}

module_init(aes_init);
module_exit(aes_fini);

MODULE_DESCRIPTION("Test my-aes-generic");
MODULE_LICENSE("GPL");

Makefile

obj-m += my_aes_generic.o

KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

all:
	$(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
	$(MAKE) -C $(KDIR) M=$(PWD) clean

 编译并加载驱动

# make
make -C /lib/modules/5.11.0-37-generic/build M=/home/my/Project/my_afalg modules
make[1]: Entering directory '/usr/src/linux-headers-5.11.0-37-generic'
  CC [M]  /home/my/Project/my_afalg/my_aes_generic.o
  MODPOST /home/my/Project/my_afalg/Module.symvers
  CC [M]  /home/my/Project/my_afalg/my_aes_generic.mod.o
  LD [M]  /home/my/Project/my_afalg/my_aes_generic.ko
make[1]: Leaving directory '/usr/src/linux-headers-5.11.0-37-generic'
# ls
Makefile       Module.symvers    my_aes_generic.dwo  my_aes_generic.mod    my_aes_generic.mod.dwo  my_aes_generic.o
modules.order  my_aes_generic.c  my_aes_generic.ko   my_aes_generic.mod.c  my_aes_generic.mod.o
# sudo insmod my_aes_generic.ko 
# lsmod | grep my_aes_generic
my_aes_generic         36864  0

执行# cat /proc/crypto 命令查看内核是否已经支持自定义算法

# cat /proc/crypto

name         : my_aes
driver       : my_aes-generic
module       : my_aes_generic
priority     : 100
refcnt       : 1
selftest     : passed
internal     : no
type         : cipher
blocksize    : 16
min keysize  : 16
max keysize  : 32

实现Netlink AF_ALG协议调用内核态密码模块里的对称加密

 使用github上示例代码完成加密算法的调用

# git clone https://github.com/nibrunie/af_alg-examples.git
# cd af_alg-examples
# make
cc -Wall -Werror  -o basic_cipher examples/basic_cipher.c -lcrypto
# ./basic_cipher
e353779c1079aeb82708942dbe77181a

 修改demo程序examples/basic_cipher.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 = "cbc(my_aes)"
  };
  struct msghdr msg = {};
  struct cmsghdr *cmsg;
  char cbuf[CMSG_SPACE(4) + CMSG_SPACE(20)] = {0};
  char buf[16];
  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;

  cmsg = CMSG_NXTHDR(&msg, cmsg);
  cmsg->cmsg_level = SOL_ALG;
  cmsg->cmsg_type = ALG_SET_IV;
  cmsg->cmsg_len = CMSG_LEN(20);
  iv = (void *)CMSG_DATA(cmsg);
  iv->ivlen = 16;
  memcpy(iv->iv, "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
           "\xb4\x22\xda\x80\x2c\x9f\xac\x41", 16);

  iov.iov_base = "Single block msg";
  iov.iov_len = 16;

  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");

  close(opfd);
  close(tfmfd);

  return 0;
}

 重新编译并运行demo

# make clean
rm -f ./basic_cipher
rm -f ./stream_hash
rm -f ./multi_connections
# make
cc -Wall -Werror  -o basic_cipher examples/basic_cipher.c -lcrypto
# ./basic_cipher 
e353779c1079aeb82708942dbe77181a

使用libkcapi库完成内核态密码模块的调用

libkcapi - Linux Kernel Crypto API User Space Interface Library. The Linux kernel exports a Netlink interface of type AF_ALG to allow user space to utilize the kernel crypto API. libkcapi uses this Netlink interface and exports easy to use APIs so that a developer does not need to consider the low-level Netlink interface handling.

# git clone https://github.com/smuellerDD/libkcapi.git
# cd libkcapi
# ./configure
# make
# make install

 OpenSSL支持AF_ALG引擎

OpenSSL 1.1.0以上版本才支持afalg引擎。

配置并编译安装

# ./config enable-engine enable-dso enable-afalgeng
# make
# make install

在编译安装完成后,可发现afalg.so文件

# pwd
/root/openssl/engines
# ls *.so
afalg.so  capi.so  dasync.so  ossltest.so  padlock.so
# pwd
/usr/lib64/engines-1.1
# ls
afalg.so  capi.so  libpkcs11.so  padlock.so  pkcs11.so

使用openssl speed测试afalg引擎

# openssl speed -evp aes-128-cbc -engine afalg -elapsed

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值