Linux内核通过一个新的套接字系列AF_ALG
在2.6的加密函数中添加了一个用户空间API。另见LWN上的crypto: af_alg - User-space interface for Crypto API。
我正在使用Gentoo,它需要一个配置和构建内核。看来默认设置省略了AF_ALG
,所以我[目前]正在使用缺乏支持的内核。 OpenSSL 1.1.0在加密API中有一个Engine接口。由于缺乏对AF_ALG
的支持,它未能通过自检。
我想知道如何在编译时和运行时检测AF_ALG
的可用性。我还没有找到一种在编译时检测可用性的方法。我想我们可以使用alg_get_type
来检测运行时可用性,但我不确定。
如何在编译时和运行时确定AF_ALG
的可用性?
socket(2)
手册页有这样的说法:“所有协议系列都可能无法实现某些套接字类型。”但它没有讨论如何检测可用性。
内核文档涵盖了Chapter 4. User Space Interface中的API,但它似乎没有讨论如何检测可用性。
为了完整性,看起来需要为Gentoo设置以下内核配置参数(来自MarekVašut的Utilizing the crypto accelerators):
CONFIG_CRYPTO_USER_API=m
CONFIG_CRYPTO_USER_API_HASH=m
CONFIG_CRYPTO_USER_API_SKCIPHER=m
我想说在编译时检测的唯一方法是编写一个单独的程序,它将对AF_ALG套接字进行运行时检查,并创建一个带有#define AF_ALG_AVAILABLE
等定义的头文件。
扩展你对第二个问题的答案,你可能想确保errno持有EAFNOSUPPORT
。否则,另一个错误(例如超出文件描述符)将使您的程序错误地认为不支持AF_ALG,如果您在编译时使用我的方法检查AF_ALG,这可能会很糟糕。
在编译时检查:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <linux/if_alg.h>
int main(){
//Alternatively you can set the path to argv[1]
FILE *f = fopen("/path/to/output/file", "w");
if(f == NULL){
//Handle error
}
int sockfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
if(sockfd == -1){
if(errno == EAFNOSUPPORT){
//Unavailable, put whatever you want here
fprintf(f, "#define AF_ALG_UNAVAILABLE\n");
} else {
//Unable to detect for some other error
}
} else { //AF_ALG is available
fprintf(f, "#define AF_ALG_AVAILABLE\n");
}
close(sockfd);
fclose(f);
return 0;
}
然后只需在您的makefile中编译并运行它,您就会找到放置它的头文件。然后,您只需使用#ifdef AF_ALG_AVAILABLE
选择要使用的代码。
我想我可以回答第二个问题,即运行时可用性,具体如下:
int ret = socket(AF_ALG, SOCK_SEQPACKET, 0);
if (ret != -1)
close(ret);
int supported = ret != -1;