1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 #include <fcntl.h>
22
23 #include <CommonCrypto/CommonCrypto.h>
24 #include <CommonCrypto/CommonDigest.h>
25
26 typedef struct {
27 void *iv;
28 void *data;
29 size_t len;
30 } crypt_msg;
31
32 typedef struct {
33 void *buf;
34 size_t len;
35 } plain_msg;
36
37 int aes_encrypt(
void *msg,
size_t len,
void *key,
size_t keylen, crypt_msg *ret) {
38 char iv[
16];
39
40
41 int devr = open(
"/dev/urandom",
O_RDONLY);
42 if(devr == -
1) {
43 return -
1;
44 }
45 ssize_t rr = read(devr, iv,
16);
46 close(devr);
47 if(rr !=
16) {
48 return -
1;
49 }
50
51
52 CCCryptorRef cryptor;
53 if(CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding, key,
32, iv, &cryptor) != kCCSuccess) {
54 return -
1;
55 }
56
57 size_t outlen = len - (len %
16) +
32;
58 char *outbuf = malloc(outlen);
59
60 memcpy(outbuf, iv,
16);
61 char *data = outbuf +
16;
62 size_t datalen = outlen -
16;
63
64 crypt_msg c;
65 c.iv = outbuf;
66 c.data = data;
67 c.len =
0;
68
69
70 size_t moved;
71 CCCryptorStatus status;
72 status = CCCryptorUpdate(cryptor, msg,
73 len, data, datalen,
74 &moved);
75 if(status != kCCSuccess) {
76 free(outbuf);
77 return -
1;
78 }
79
80 data += moved;
81 datalen -= moved;
82 c.len += moved;
83
84 status = CCCryptorFinal(cryptor, data, datalen, &moved);
85 if(status != kCCSuccess) {
86 free(outbuf);
87 return -
1;
88 }
89
90 c.len += moved;
91 *ret = c;
92
93 return 0;
94 }
95
96 int aes_decrypt(crypt_msg cmsg,
void *key,
size_t keylen, plain_msg *ret) {
97 CCCryptorRef cryptor;
98 if(CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding, key,
32, cmsg.iv, &cryptor) != kCCSuccess) {
99 return -
1;
100 }
101
102 char *outbuf = malloc(cmsg.len);
103 size_t outavail = cmsg.len;
104 char *buf = outbuf;
105
106 size_t len =
0;
107 size_t moved;
108 CCCryptorStatus status;
109
110 char *data = cmsg.data;
111 size_t datalen = cmsg.len;
112
113 status = CCCryptorUpdate(cryptor, cmsg.data, cmsg.len, outbuf, outavail, &moved);
114 if(status != kCCSuccess) {
115 free(outbuf);
116 return -
1;
117 }
118
119 outavail -= moved;
120 buf += moved;
121 len += moved;
122
123 status = CCCryptorFinal(cryptor, buf, outavail, &moved);
124 if(status != kCCSuccess) {
125 free(outbuf);
126 return -
1;
127 }
128
129 len += moved;
130
131 plain_msg msg;
132 msg.buf = outbuf;
133 msg.len = len;
134
135 *ret = msg;
136
137 return 0;
138 }
139
140 int main(
int argc,
char** argv) {
141 char *text =
"Hello World!";
142 size_t textlen = strlen(text);
143
144 char key[
32];
145
146 int devr = open(
"/dev/urandom",
O_RDONLY);
147 if(devr == -
1) {
148 return -
1;
149 }
150 ssize_t rr = read(devr, key,
32);
151 close(devr);
152 if(rr !=
32) {
153 return -
1;
154 }
155
156
157 crypt_msg cmsg;
158 if(aes_encrypt(text, textlen, key,
32, &cmsg)) {
159 fprintf(stderr,
"aes_encrypt failed\n");
160 }
161
162
163 plain_msg pmsg;
164 if(aes_decrypt(cmsg, key,
32, &pmsg)) {
165 fprintf(stderr,
"aes_decrypt failed\n");
166 }
167
168 printf(
"decrypted text: %.*s\n", (
int)pmsg.len, pmsg.buf);
169
170 return (
EXIT_SUCCESS);
171 }
172
173