我正在尝试使用内核加密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。我阅读了msghdr
、cmsg
和sendmsg
的手册页,但没有找到我的错误。
编辑:
- 添加了绑定失败检查,但检查退出时显示0-〉无错误
1条答案
按热度按时间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}