我正在尝试使用内核加密 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 和模式。我阅读了
msghdr
、cmsg
和 sendmsg
的手册页,但没有发现我的错误。
编辑:
你数得不太正确
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}
设置
cmsg_len
的两个位置不应包含对 CMSG_SPACE()
宏的调用,因为该宏会使用 sizeof(struct cmsghdr)
来扩展消息长度。