从用户空间使用内核加密API的AES-GCM

dced5bon  于 2023-02-07  发布在  其他
关注(0)|答案(1)|浏览(174)

我正在尝试使用内核加密API从用户空间与硬件加速器通信。我使用af_alg与内核通信。我可以使用API进行散列或"正常"对称加密,但我无法让它与aead算法一起工作。驱动程序在/proc/crypto下注册。我按照用户空间接口的内核文档准备消息,但每次都得到相同的错误 * Invalig Argument *。

#ifndef AF_ALG
#define AF_ALG 38
#endif
#ifndef SOL_ALG
#define SOL_ALG 279
#endif

int main(void)
{
 int openfd;
 int tfmfd;

 char key [16] = "SecretKeyforAES!";
 char initVector[12] = "123456789012";
 //initiaze vector, in/out vector and buffer
 struct af_alg_iv *iv;
 struct iovec iov;
 char buf[64];
 //size of the aad and the auth tag
 uint32_t aadSize = 8;
 uint32_t taglen = 12;

 //define algorithm used for cryptography
 struct sockaddr_alg sa = {
        .salg_family = AF_ALG,
        .salg_type = "aead",
        .salg_name = "gcm(aes)"
 };
 //create and bind socket
 tfmfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
 printf("open socket\n");
 int bindvalue = bind(tfmfd, (struct sockaddr *) &sa, sizeof(sa));
 if(bindvalue != 0){
        perror("send != 0");
 }
 assert(bindvalue == 0);

 printf("socket bound\n");

//set socket options: key, AEAD Authentication size
 setsockopt(tfmfd, SOL_ALG, ALG_SET_KEY, key, 16);
 int setTag = setsockopt(tfmfd, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, taglen);
 assert(setTag >= 0);
 printf("set socket options\n");
 //accept connection
 openfd = accept(tfmfd, NULL, 0);

//check errors with the connections
 assert(tfmfd > 0);
 assert(openfd > 0);

 //Prepare Message
 struct msghdr msg = { 0 };
 struct cmsghdr *cmsg = NULL;
 char cbuf[128] = {0};

 msg.msg_control = cbuf;
 msg.msg_controllen = sizeof(cbuf);
 msg.msg_iovlen = 0;
 msg.msg_iov = NULL;

 //set the Headervalues for the  Operation
 cmsg = CMSG_FIRSTHDR(&msg);
 assert(cmsg != NULL);
 cmsg->cmsg_level = SOL_ALG;
 cmsg->cmsg_type = ALG_SET_OP;
 cmsg->cmsg_len = CMSG_LEN(CMSG_SPACE(sizeof(uint32_t)));
 *(__u32 *) CMSG_DATA(cmsg) = ALG_OP_ENCRYPT;

 //set headervalues for IV
 cmsg = CMSG_NXTHDR(&msg, cmsg);
 assert(cmsg != NULL);
 cmsg->cmsg_level = SOL_ALG;
 cmsg->cmsg_type = ALG_SET_IV;
 cmsg->cmsg_len = CMSG_LEN(CMSG_SPACE(sizeof(initVector))); //iv_msg_size

 //set value for iv
 iv = (void *)CMSG_DATA(cmsg);
 iv->ivlen = 12;
 memcpy(iv->iv, initVector, 12);

 //set headervalues for aad
 uint32_t *assoclen = NULL;
 cmsg = CMSG_NXTHDR(&msg, cmsg);
 assert(cmsg != NULL);
 cmsg->cmsg_level = SOL_ALG;
 cmsg->cmsg_type = ALG_SET_AEAD_ASSOCLEN;
 cmsg->cmsg_len = CMSG_LEN(sizeof(*assoclen));
 assoclen = (void *) CMSG_DATA(cmsg);
 *assoclen = (uint32_t)aadSize;
 printf("Header values set\n");

 //send initial message
 int send = sendmsg(openfd, &msg, MSG_MORE);
 if(send < 0){
        perror("send < 0");  //This is where the error occures
 }
 assert(send > 0); //This assertion fails following the error above
 printf("Send initial Message...\n");

在内核文档之后,我准备了包含算法、iv和aad长度信息的初始消息。我还用 * setsockopt * 设置了taglen和mode。我阅读了msghdrcmsgsendmsg的手册页,但没有找到我的错误。
编辑:

  • 添加了绑定失败检查,但检查退出时显示0-〉无错误
wbrvyc0a

wbrvyc0a1#

你数cmsg_len不太对。
第一个值是正确的,尽管CMSG_LEN(CMSG_SPACE(sizeof(uint32_t)))反映了ALG_SET_OP
但不是CMSG_LEN(CMSG_SPACE(sizeof(initVector))); //iv_msg_size,因为数据是iv = (void *)CMSG_DATA(cmsg);-〉struct af_alg_iv *iv;,所以应该是CMSG_LEN(sizeof(struct af_alg_iv) + sizeof(initVector))
此外,char cbuf[128] = {0};必须包含辅助数据的总大小,即char cbuf[CMSG_SPACE(sizeof(uint32_t)) + CMSG_SPACE(sizeof(struct af_alg_iv) + sizeof(initVector))] = {0}

相关问题