2 * Demo on how to use /dev/crypto device for ciphering.
4 * Placed under public domain.
12 #include <sys/ioctl.h>
13 #include <crypto/cryptodev.h>
15 #define DATA_SIZE 8*1024
22 char plaintext_raw
[DATA_SIZE
+ 63], *plaintext
;
23 char ciphertext_raw
[DATA_SIZE
+ 63], *ciphertext
;
27 struct session_op sess
;
29 struct session_info_op siop
;
33 memset(&sess
, 0, sizeof(sess
));
34 memset(&cryp
, 0, sizeof(cryp
));
36 memset(key
, 0x33, sizeof(key
));
37 memset(iv
, 0x03, sizeof(iv
));
39 /* Get crypto session for AES128 */
40 sess
.cipher
= CRYPTO_AES_CBC
;
41 sess
.keylen
= KEY_SIZE
;
43 if (ioctl(cfd
, CIOCGSESSION
, &sess
)) {
44 perror("ioctl(CIOCGSESSION)");
50 if (ioctl(cfd
, CIOCGSESSINFO
, &siop
)) {
51 perror("ioctl(CIOCGSESSINFO)");
54 printf("requested cipher CRYPTO_AES_CBC, got %s with driver %s\n",
55 siop
.cipher_info
.cra_name
, siop
.cipher_info
.cra_driver_name
);
57 plaintext
= (char *)(((unsigned long)plaintext_raw
+ siop
.alignmask
) & ~siop
.alignmask
);
58 ciphertext
= (char *)(((unsigned long)ciphertext_raw
+ siop
.alignmask
) & ~siop
.alignmask
);
60 plaintext
= plaintext_raw
;
61 ciphertext
= ciphertext_raw
;
63 memset(plaintext
, 0x15, DATA_SIZE
);
65 /* Encrypt data.in to data.encrypted */
69 cryp
.dst
= ciphertext
;
71 cryp
.op
= COP_ENCRYPT
;
72 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
73 perror("ioctl(CIOCCRYPT)");
77 if (ioctl(cfd
, CIOCFSESSION
, &sess
.ses
)) {
78 perror("ioctl(CIOCFSESSION)");
82 if (ioctl(cfd
, CIOCGSESSION
, &sess
)) {
83 perror("ioctl(CIOCGSESSION)");
89 if (ioctl(cfd
, CIOCGSESSINFO
, &siop
)) {
90 perror("ioctl(CIOCGSESSINFO)");
93 printf("requested cipher CRYPTO_AES_CBC, got %s with driver %s\n",
94 siop
.cipher_info
.cra_name
, siop
.cipher_info
.cra_driver_name
);
97 /* Decrypt data.encrypted to data.decrypted */
100 cryp
.src
= ciphertext
;
101 cryp
.dst
= ciphertext
;
103 cryp
.op
= COP_DECRYPT
;
104 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
105 perror("ioctl(CIOCCRYPT)");
109 /* Verify the result */
110 if (memcmp(plaintext
, ciphertext
, DATA_SIZE
) != 0) {
113 "FAIL: Decrypted data are different from the input data.\n");
114 printf("plaintext:");
115 for (i
= 0; i
< DATA_SIZE
; i
++) {
118 printf("%02x ", plaintext
[i
]);
120 printf("ciphertext:");
121 for (i
= 0; i
< DATA_SIZE
; i
++) {
124 printf("%02x ", ciphertext
[i
]);
129 printf("Test passed\n");
131 /* Finish crypto session */
132 if (ioctl(cfd
, CIOCFSESSION
, &sess
.ses
)) {
133 perror("ioctl(CIOCFSESSION)");
140 static int test_aes(int cfd
)
142 char plaintext1_raw
[BLOCK_SIZE
+ 63], *plaintext1
;
143 char ciphertext1
[BLOCK_SIZE
] = { 0xdf, 0x55, 0x6a, 0x33, 0x43, 0x8d, 0xb8, 0x7b, 0xc4, 0x1b, 0x17, 0x52, 0xc5, 0x5e, 0x5e, 0x49 };
144 char iv1
[BLOCK_SIZE
];
145 char key1
[KEY_SIZE
] = { 0xff, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
146 char plaintext2_data
[BLOCK_SIZE
] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00 };
147 char plaintext2_raw
[BLOCK_SIZE
+ 63], *plaintext2
;
148 char ciphertext2
[BLOCK_SIZE
] = { 0xb7, 0x97, 0x2b, 0x39, 0x41, 0xc4, 0x4b, 0x90, 0xaf, 0xa7, 0xb2, 0x64, 0xbf, 0xba, 0x73, 0x87 };
149 char iv2
[BLOCK_SIZE
];
152 struct session_op sess
;
154 struct session_info_op siop
;
156 struct crypt_op cryp
;
158 memset(&sess
, 0, sizeof(sess
));
159 memset(&cryp
, 0, sizeof(cryp
));
161 /* Get crypto session for AES128 */
162 sess
.cipher
= CRYPTO_AES_CBC
;
163 sess
.keylen
= KEY_SIZE
;
165 if (ioctl(cfd
, CIOCGSESSION
, &sess
)) {
166 perror("ioctl(CIOCGSESSION)");
171 if (ioctl(cfd
, CIOCGSESSINFO
, &siop
)) {
172 perror("ioctl(CIOCGSESSINFO)");
175 plaintext1
= (char *)(((unsigned long)plaintext1_raw
+ siop
.alignmask
) & ~siop
.alignmask
);
177 plaintext1
= plaintext1_raw
;
179 memset(plaintext1
, 0x0, BLOCK_SIZE
);
180 memset(iv1
, 0x0, sizeof(iv1
));
182 /* Encrypt data.in to data.encrypted */
184 cryp
.len
= BLOCK_SIZE
;
185 cryp
.src
= plaintext1
;
186 cryp
.dst
= plaintext1
;
188 cryp
.op
= COP_ENCRYPT
;
189 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
190 perror("ioctl(CIOCCRYPT)");
194 /* Verify the result */
195 if (memcmp(plaintext1
, ciphertext1
, BLOCK_SIZE
) != 0) {
197 "FAIL: Decrypted data are different from the input data.\n");
203 memset(key2
, 0x0, sizeof(key2
));
204 memset(iv2
, 0x0, sizeof(iv2
));
206 /* Get crypto session for AES128 */
207 sess
.cipher
= CRYPTO_AES_CBC
;
208 sess
.keylen
= KEY_SIZE
;
210 if (ioctl(cfd
, CIOCGSESSION
, &sess
)) {
211 perror("ioctl(CIOCGSESSION)");
217 if (ioctl(cfd
, CIOCGSESSINFO
, &siop
)) {
218 perror("ioctl(CIOCGSESSINFO)");
221 printf("requested cipher CRYPTO_AES_CBC, got %s with driver %s\n",
222 siop
.cipher_info
.cra_name
, siop
.cipher_info
.cra_driver_name
);
224 plaintext2
= (char *)(((unsigned long)plaintext2_raw
+ siop
.alignmask
) & ~siop
.alignmask
);
226 plaintext2
= plaintext2_raw
;
228 memcpy(plaintext2
, plaintext2_data
, BLOCK_SIZE
);
230 /* Encrypt data.in to data.encrypted */
232 cryp
.len
= BLOCK_SIZE
;
233 cryp
.src
= plaintext2
;
234 cryp
.dst
= plaintext2
;
236 cryp
.op
= COP_ENCRYPT
;
237 if (ioctl(cfd
, CIOCCRYPT
, &cryp
)) {
238 perror("ioctl(CIOCCRYPT)");
242 /* Verify the result */
243 if (memcmp(plaintext2
, ciphertext2
, BLOCK_SIZE
) != 0) {
246 "FAIL: Decrypted data are different from the input data.\n");
247 printf("plaintext:");
248 for (i
= 0; i
< BLOCK_SIZE
; i
++) {
251 printf("%02x ", plaintext2
[i
]);
253 printf("ciphertext:");
254 for (i
= 0; i
< BLOCK_SIZE
; i
++) {
257 printf("%02x ", ciphertext2
[i
]);
263 printf("AES Test passed\n");
265 /* Finish crypto session */
266 if (ioctl(cfd
, CIOCFSESSION
, &sess
.ses
)) {
267 perror("ioctl(CIOCFSESSION)");
277 int fd
= -1, cfd
= -1;
279 /* Open the crypto device */
280 fd
= open("/dev/crypto", O_RDWR
, 0);
282 perror("open(/dev/crypto)");
286 /* Clone file descriptor */
287 if (ioctl(fd
, CRIOGET
, &cfd
)) {
288 perror("ioctl(CRIOGET)");
292 /* Set close-on-exec (not really neede here) */
293 if (fcntl(cfd
, F_SETFD
, 1) == -1) {
294 perror("fcntl(F_SETFD)");
298 /* Run the test itself */
302 if (test_crypto(cfd
))
305 /* Close cloned descriptor */
307 perror("close(cfd)");
311 /* Close the original descriptor */