2 * Demo on how to use /dev/crypto device for HMAC.
4 * Placed under public domain.
12 #include <sys/ioctl.h>
13 #include <crypto/cryptodev.h>
15 #define DATA_SIZE 4096
18 #define SHA1_HASH_LEN 20
24 uint8_t in
[DATA_SIZE
],
30 struct session_op sess
;
32 uint8_t mac
[AALG_MAX_RESULT_LEN
];
33 uint8_t oldmac
[AALG_MAX_RESULT_LEN
];
34 uint8_t md5_hmac_out
[] = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38";
35 uint8_t sha1_out
[] = "\x8f\x82\x03\x94\xf9\x53\x35\x18\x20\x45\xda\x24\xf3\x4d\xe5\x2b\xf8\xbc\x34\x32";
38 memset(&sess
, 0, sizeof(sess
));
39 memset(&cryp
, 0, sizeof(cryp
));
41 /* Use the garbage that is on the stack :-) */
42 /* memset(&data, 0, sizeof(data)); */
45 memset(mac
, 0, sizeof(mac
));
48 sess
.mac
= CRYPTO_SHA1
;
49 if (ioctl(cfd
, CIOCGSESSION
, &sess
)) {
50 perror("ioctl(CIOCGSESSION)");
55 cryp
.len
= sizeof("what do ya want for nothing?")-1;
56 cryp
.src
= "what do ya want for nothing?";
58 cryp
.op
= COP_ENCRYPT
;
59 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
60 perror("ioctl(CIOCCRYPT)");
64 if (memcmp(mac
, sha1_out
, 20)!=0) {
66 for (i
=0;i
<SHA1_HASH_LEN
;i
++) {
67 printf("%.2x", (uint8_t)mac
[i
]);
70 fprintf(stderr
, "HASH test 1: failed\n");
72 fprintf(stderr
, "HASH test 1: passed\n");
76 memset(mac
, 0, sizeof(mac
));
79 sess
.mackey
= (uint8_t*)"Jefe";
81 sess
.mac
= CRYPTO_MD5_HMAC
;
82 if (ioctl(cfd
, CIOCGSESSION
, &sess
)) {
83 perror("ioctl(CIOCGSESSION)");
88 cryp
.len
= sizeof("what do ya want for nothing?")-1;
89 cryp
.src
= "what do ya want for nothing?";
91 cryp
.op
= COP_ENCRYPT
;
92 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
93 perror("ioctl(CIOCCRYPT)");
97 if (memcmp(mac
, md5_hmac_out
, 16)!=0) {
99 for (i
=0;i
<SHA1_HASH_LEN
;i
++) {
100 printf("%.2x", (uint8_t)mac
[i
]);
103 fprintf(stderr
, "HMAC test 1: failed\n");
105 fprintf(stderr
, "HMAC test 1: passed\n");
108 /* Hash and encryption in one step test */
109 sess
.cipher
= CRYPTO_AES_CBC
;
110 sess
.mac
= CRYPTO_SHA1_HMAC
;
111 sess
.keylen
= KEY_SIZE
;
114 sess
.mackey
= (uint8_t*)"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
115 if (ioctl(cfd
, CIOCGSESSION
, &sess
)) {
116 perror("ioctl(CIOCGSESSION)");
120 /* Encrypt data.in to data.encrypted */
122 cryp
.len
= sizeof(data
.in
);
124 cryp
.dst
= data
.encrypted
;
127 cryp
.op
= COP_ENCRYPT
;
128 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
129 perror("ioctl(CIOCCRYPT)");
133 memcpy(oldmac
, mac
, sizeof(mac
));
135 /* Decrypt data.encrypted to data.decrypted */
136 cryp
.src
= data
.encrypted
;
137 cryp
.dst
= data
.decrypted
;
138 cryp
.op
= COP_DECRYPT
;
139 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
140 perror("ioctl(CIOCCRYPT)");
144 /* Verify the result */
145 if (memcmp(data
.in
, data
.decrypted
, sizeof(data
.in
)) != 0) {
147 "FAIL: Decrypted data are different from the input data.\n");
150 printf("Crypt Test: passed\n");
152 if (memcmp(mac
, oldmac
, 20) != 0) {
154 "FAIL: Hash in decrypted data different than in encrypted.\n");
157 printf("HMAC Test 2: passed\n");
159 /* Finish crypto session */
160 if (ioctl(cfd
, CIOCFSESSION
, &sess
.ses
)) {
161 perror("ioctl(CIOCFSESSION)");
171 int fd
= -1, cfd
= -1;
173 /* Open the crypto device */
174 fd
= open("/dev/crypto", O_RDWR
, 0);
176 perror("open(/dev/crypto)");
180 /* Clone file descriptor */
181 if (ioctl(fd
, CRIOGET
, &cfd
)) {
182 perror("ioctl(CRIOGET)");
186 /* Set close-on-exec (not really neede here) */
187 if (fcntl(cfd
, F_SETFD
, 1) == -1) {
188 perror("fcntl(F_SETFD)");
192 /* Run the test itself */
193 if (test_crypto(cfd
))
196 /* Close cloned descriptor */
198 perror("close(cfd)");
202 /* Close the original descriptor */