mirror of
https://github.com/SCST-project/scst.git
synced 2026-05-14 01:01:27 +00:00
98 lines
2.0 KiB
C
98 lines
2.0 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* af_alg - wrapper functions to call AF_ALG hash algorithms.
|
|
*
|
|
* Copyright (C) 2025 Brian Meagher <brian.meagher@ixsystems.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation, version 2
|
|
* of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include "af_alg.h"
|
|
|
|
#include <sys/socket.h>
|
|
#include <linux/if_alg.h>
|
|
#include <string.h>
|
|
#include <sys/param.h>
|
|
#include <stdbool.h>
|
|
#include <errno.h>
|
|
|
|
int af_alg_init(const char *algorithm)
|
|
{
|
|
int sockfd, datafd, algo_len;
|
|
struct sockaddr_alg sa = {
|
|
.salg_family = AF_ALG,
|
|
.salg_type = "hash",
|
|
};
|
|
|
|
algo_len = strlen(algorithm);
|
|
if (algo_len >= sizeof(sa.salg_name))
|
|
return -1;
|
|
|
|
sockfd = socket(AF_ALG, SOCK_SEQPACKET, 0);
|
|
if (sockfd == -1)
|
|
return -1;
|
|
|
|
/* +1 for null-terminator */
|
|
memcpy(sa.salg_name, algorithm, algo_len + 1);
|
|
|
|
if (bind(sockfd, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
|
|
close(sockfd);
|
|
return -1;
|
|
}
|
|
|
|
datafd = accept(sockfd, NULL, 0);
|
|
if (datafd < 0) {
|
|
close(sockfd);
|
|
return -1;
|
|
}
|
|
close(sockfd);
|
|
return datafd;
|
|
}
|
|
|
|
int af_alg_update(int datafd, const void *data_in, size_t len)
|
|
{
|
|
ssize_t res;
|
|
|
|
res = send(datafd, data_in, len, MSG_MORE);
|
|
if (res == -1)
|
|
return -errno;
|
|
|
|
return 0;
|
|
}
|
|
|
|
ssize_t af_alg_final(int datafd, void *out, size_t len)
|
|
{
|
|
char buffer[1024];
|
|
ssize_t res;
|
|
|
|
res = send(datafd, NULL, 0, 0);
|
|
if (res == -1)
|
|
return -errno;
|
|
|
|
res = recv(datafd, buffer, sizeof(buffer), 0);
|
|
if (res == -1)
|
|
return -errno;
|
|
|
|
memcpy(out, buffer, MIN(len, res));
|
|
|
|
return res;
|
|
}
|
|
|
|
bool af_alg_supported(char *alg)
|
|
{
|
|
int sock = af_alg_init(alg);
|
|
|
|
if (sock < 0)
|
|
return false;
|
|
close(sock);
|
|
return true;
|
|
}
|