2 * Demo on how to use /dev/crypto device for HMAC.
4 * Placed under public domain.
13 #include <sys/ioctl.h>
14 #include <crypto/cryptodev.h>
18 #define DATA_SIZE 4096
21 #define SHA1_HASH_LEN 20
27 uint8_t in
[DATA_SIZE
],
33 struct session_op sess
;
35 struct session_info_op siop
;
38 uint8_t mac
[AALG_MAX_RESULT_LEN
];
39 uint8_t oldmac
[AALG_MAX_RESULT_LEN
];
40 uint8_t md5_hmac_out
[] = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38";
41 uint8_t sha1_out
[] = "\x8f\x82\x03\x94\xf9\x53\x35\x18\x20\x45\xda\x24\xf3\x4d\xe5\x2b\xf8\xbc\x34\x32";
44 memset(&sess
, 0, sizeof(sess
));
45 memset(&cryp
, 0, sizeof(cryp
));
47 /* Use the garbage that is on the stack :-) */
48 /* memset(&data, 0, sizeof(data)); */
51 memset(mac
, 0, sizeof(mac
));
54 sess
.mac
= CRYPTO_SHA1
;
55 if (ioctl(cfd
, CIOCGSESSION
, &sess
)) {
56 perror("ioctl(CIOCGSESSION)");
62 if (ioctl(cfd
, CIOCGSESSINFO
, &siop
)) {
63 perror("ioctl(CIOCGSESSINFO)");
66 if (debug
) printf("requested mac CRYPTO_SHA1, got %s with driver %s\n",
67 siop
.hash_info
.cra_name
, siop
.hash_info
.cra_driver_name
);
71 cryp
.len
= sizeof("what do ya want for nothing?")-1;
72 cryp
.src
= "what do ya want for nothing?";
74 cryp
.op
= COP_ENCRYPT
;
75 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
76 perror("ioctl(CIOCCRYPT)");
80 if (memcmp(mac
, sha1_out
, 20)!=0) {
82 for (i
=0;i
<SHA1_HASH_LEN
;i
++) {
83 printf("%.2x", (uint8_t)mac
[i
]);
86 fprintf(stderr
, "HASH test 1: failed\n");
88 if (debug
) fprintf(stderr
, "HASH test 1: passed\n");
92 memset(mac
, 0, sizeof(mac
));
95 sess
.mackey
= (uint8_t*)"Jefe";
97 sess
.mac
= CRYPTO_MD5_HMAC
;
98 if (ioctl(cfd
, CIOCGSESSION
, &sess
)) {
99 perror("ioctl(CIOCGSESSION)");
105 if (ioctl(cfd
, CIOCGSESSINFO
, &siop
)) {
106 perror("ioctl(CIOCGSESSINFO)");
110 printf("requested mac CRYPTO_MD5_HMAC, got %s with driver %s\n",
111 siop
.hash_info
.cra_name
, siop
.hash_info
.cra_driver_name
);
115 cryp
.len
= sizeof("what do ya want for nothing?")-1;
116 cryp
.src
= "what do ya want for nothing?";
118 cryp
.op
= COP_ENCRYPT
;
119 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
120 perror("ioctl(CIOCCRYPT)");
124 if (memcmp(mac
, md5_hmac_out
, 16)!=0) {
126 for (i
=0;i
<SHA1_HASH_LEN
;i
++) {
127 printf("%.2x", (uint8_t)mac
[i
]);
130 fprintf(stderr
, "HMAC test 1: failed\n");
132 if (debug
) fprintf(stderr
, "HMAC test 1: passed\n");
135 /* Hash and encryption in one step test */
136 sess
.cipher
= CRYPTO_AES_CBC
;
137 sess
.mac
= CRYPTO_SHA1_HMAC
;
138 sess
.keylen
= KEY_SIZE
;
141 sess
.mackey
= (uint8_t*)"\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
142 if (ioctl(cfd
, CIOCGSESSION
, &sess
)) {
143 perror("ioctl(CIOCGSESSION)");
149 if (ioctl(cfd
, CIOCGSESSINFO
, &siop
)) {
150 perror("ioctl(CIOCGSESSINFO)");
154 printf("requested cipher CRYPTO_AES_CBC and mac CRYPTO_SHA1_HMAC,"
155 " got cipher %s with driver %s and hash %s with driver %s\n",
156 siop
.cipher_info
.cra_name
, siop
.cipher_info
.cra_driver_name
,
157 siop
.hash_info
.cra_name
, siop
.hash_info
.cra_driver_name
);
160 /* Encrypt data.in to data.encrypted */
162 cryp
.len
= sizeof(data
.in
);
164 cryp
.dst
= data
.encrypted
;
167 cryp
.op
= COP_ENCRYPT
;
168 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
169 perror("ioctl(CIOCCRYPT)");
173 memcpy(oldmac
, mac
, sizeof(mac
));
175 /* Decrypt data.encrypted to data.decrypted */
176 cryp
.src
= data
.encrypted
;
177 cryp
.dst
= data
.decrypted
;
178 cryp
.op
= COP_DECRYPT
;
179 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
180 perror("ioctl(CIOCCRYPT)");
184 /* Verify the result */
185 if (memcmp(data
.in
, data
.decrypted
, sizeof(data
.in
)) != 0) {
187 "FAIL: Decrypted data are different from the input data.\n");
189 } else if (debug
) printf("Crypt Test: passed\n");
191 if (memcmp(mac
, oldmac
, 20) != 0) {
193 "FAIL: Hash in decrypted data different than in encrypted.\n");
195 } else if (debug
) printf("HMAC Test 2: passed\n");
197 /* Finish crypto session */
198 if (ioctl(cfd
, CIOCFSESSION
, &sess
.ses
)) {
199 perror("ioctl(CIOCFSESSION)");
209 struct session_op sess
;
211 struct session_info_op siop
;
213 struct crypt_op cryp
;
214 uint8_t mac
[AALG_MAX_RESULT_LEN
];
215 uint8_t oldmac
[AALG_MAX_RESULT_LEN
];
216 uint8_t md5_hmac_out
[] = "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38";
217 uint8_t sha1_out
[] = "\x8f\x82\x03\x94\xf9\x53\x35\x18\x20\x45\xda\x24\xf3\x4d\xe5\x2b\xf8\xbc\x34\x32";
220 memset(&sess
, 0, sizeof(sess
));
221 memset(&cryp
, 0, sizeof(cryp
));
223 /* Use the garbage that is on the stack :-) */
224 /* memset(&data, 0, sizeof(data)); */
226 /* SHA1 plain test */
227 memset(mac
, 0, sizeof(mac
));
230 sess
.mac
= CRYPTO_SHA1
;
231 if (ioctl(cfd
, CIOCGSESSION
, &sess
)) {
232 perror("ioctl(CIOCGSESSION)");
238 if (ioctl(cfd
, CIOCGSESSINFO
, &siop
)) {
239 perror("ioctl(CIOCGSESSINFO)");
243 printf("requested mac CRYPTO_SHA1, got %s with driver %s\n",
244 siop
.hash_info
.cra_name
, siop
.hash_info
.cra_driver_name
);
248 cryp
.len
= sizeof("what do")-1;
249 cryp
.src
= "what do";
251 cryp
.op
= COP_ENCRYPT
;
252 cryp
.flags
= COP_FLAG_UPDATE
;
253 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
254 perror("ioctl(CIOCCRYPT)");
259 cryp
.len
= sizeof(" ya want for nothing?")-1;
260 cryp
.src
= " ya want for nothing?";
262 cryp
.op
= COP_ENCRYPT
;
263 cryp
.flags
= COP_FLAG_FINAL
;
264 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
265 perror("ioctl(CIOCCRYPT)");
269 if (memcmp(mac
, sha1_out
, 20)!=0) {
271 for (i
=0;i
<SHA1_HASH_LEN
;i
++) {
272 printf("%.2x", (uint8_t)mac
[i
]);
275 fprintf(stderr
, "HASH test [update]: failed\n");
277 if (debug
) fprintf(stderr
, "HASH test [update]: passed\n");
280 memset(mac
, 0, sizeof(mac
));
282 /* Finish crypto session */
283 if (ioctl(cfd
, CIOCFSESSION
, &sess
.ses
)) {
284 perror("ioctl(CIOCFSESSION)");
293 main(int argc
, char** argv
)
295 int fd
= -1, cfd
= -1;
297 if (argc
> 1) debug
= 1;
299 /* Open the crypto device */
300 fd
= open("/dev/crypto", O_RDWR
, 0);
302 perror("open(/dev/crypto)");
306 /* Clone file descriptor */
307 if (ioctl(fd
, CRIOGET
, &cfd
)) {
308 perror("ioctl(CRIOGET)");
312 /* Set close-on-exec (not really neede here) */
313 if (fcntl(cfd
, F_SETFD
, 1) == -1) {
314 perror("fcntl(F_SETFD)");
318 /* Run the test itself */
319 if (test_crypto(cfd
))
322 if (test_extras(cfd
))
325 /* Close cloned descriptor */
327 perror("close(cfd)");
331 /* Close the original descriptor */