CryptoDev for Linux
cryptodev-demo1.c source
Project updated · 27 November 2009
Download raw cryptodev-demo1.c ↓
/*
* Demo on how to use OpenBSD /dev/crypto device.
*
* Author: Michal Ludvig <michal@logix.cz>
* /michal
*
* Note: by default OpenBSD doesn't allow using
* /dev/crypto if there is no hardware accelerator
* for a given algorithm. To change this you'll have to
* set cryptodevallowsoft=1 in
* /usr/src/sys/crypto/cryptodev.c and rebuild your kernel.
*/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <crypto/cryptodev.h>
#define DATA_SIZE 4096
#define BLOCK_SIZE 16
#define KEY_SIZE 24
static int
test_crypto(int cfd)
{
struct {
char in[DATA_SIZE],
encrypted[DATA_SIZE],
decrypted[DATA_SIZE],
iv[BLOCK_SIZE],
key[KEY_SIZE];
} data;
struct session_op sess;
struct crypt_op cryp;
memset(&sess, 0, sizeof(sess));
memset(&cryp, 0, sizeof(cryp));
/* Use the garbage that is on the stack :-) */
/* memset(&data, 0, sizeof(data)); */
/* Get crypto session for AES128 */
sess.cipher = CRYPTO_AES_CBC;
sess.keylen = KEY_SIZE;
sess.key = data.key;
if (ioctl(cfd, CIOCGSESSION, &sess)) {
perror("ioctl(CIOCGSESSION)");
return 1;
}
/* Encrypt data.in to data.encrypted */
cryp.ses = sess.ses;
cryp.len = sizeof(data.in);
cryp.src = data.in;
cryp.dst = data.encrypted;
cryp.iv = data.iv;
cryp.op = COP_ENCRYPT;
if (ioctl(cfd, CIOCCRYPT, &cryp)) {
perror("ioctl(CIOCCRYPT)");
return 1;
}
/* Decrypt data.encrypted to data.decrypted */
cryp.src = data.encrypted;
cryp.dst = data.decrypted;
cryp.op = COP_DECRYPT;
if (ioctl(cfd, CIOCCRYPT, &cryp)) {
perror("ioctl(CIOCCRYPT)");
return 1;
}
/* Verify the result */
if (memcmp(data.in, data.decrypted, sizeof(data.in)) != 0) {
fprintf(stderr,
"FAIL: Decrypted data are different from the input data.\n");
return 1;
} else
printf("Test passed\n");
/* Finish crypto session */
if (ioctl(cfd, CIOCFSESSION, &sess.ses)) {
perror("ioctl(CIOCFSESSION)");
return 1;
}
return 0;
}
int
main()
{
int fd = -1, cfd = -1;
/* Open the crypto device */
fd = open("/dev/crypto", O_RDWR, 0);
if (fd < 0) {
perror("open(/dev/crypto)");
return 1;
}
/* Clone file descriptor */
if (ioctl(fd, CRIOGET, &cfd)) {
perror("ioctl(CRIOGET)");
return 1;
}
/* Set close-on-exec (not really neede here */
if (fcntl(cfd, F_SETFD, 1) == -1) {
perror("fcntl(F_SETFD)");
return 1;
}
/* Run the test itself */
if (test_crypto(cfd))
return 1;
/* Close cloned descriptor */
if (close(cfd)) {
perror("close(cfd)");
return 1;
}
/* Close the original descriptor */
if (close(fd)) {
perror("close(fd)");
return 1;
}
return 0;
}