26f21e80eb6c92fdc2cd3ab3a91ba5736704b31a
[platform/core/security/yaca.git] / examples / encrypt.c
1 /*
2  *  Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *  Contact: Krzysztof Jackiewicz <k.jackiewicz@samsung.com>
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License");
7  *  you may not use this file except in compliance with the License.
8  *  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *  Unless required by applicable law or agreed to in writing, software
13  *  distributed under the License is distributed on an "AS IS" BASIS,
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  *  See the License for the specific language governing permissions and
16  *  limitations under the License
17  */
18
19 /**
20  * @file encrypt.c
21  * @brief
22  */
23
24 #include <stdio.h>
25
26 #include <yaca/crypto.h>
27 #include <yaca/encrypt.h>
28 #include <yaca/simple.h>
29 #include <yaca/key.h>
30 #include "lorem.h"
31 #include "misc.h"
32
33 // Symmetric encryption using simple API
34 void encrypt_simple(void)
35 {
36         int ret;
37         yaca_key_h key = YACA_KEY_NULL;
38         yaca_key_h iv = YACA_KEY_NULL;
39         char *enc_data = NULL;
40         char *dec_data = NULL;
41         size_t enc_len;
42         size_t dec_len;
43
44         printf("Plain data (16 of %zu bytes): %.16s\n", (size_t)1024, lorem1024);
45
46         ret = yaca_key_derive_pbkdf2("foo bar", "123456789", 10,
47                                      1000, YACA_DIGEST_SHA256,
48                                      YACA_KEY_256BIT, &key);
49         if (ret)
50                 return;
51
52         ret = yaca_key_gen(&iv, YACA_KEY_TYPE_IV, YACA_KEY_IV_256BIT);
53         if (ret)
54                 goto exit;
55
56         ret = yaca_encrypt(YACA_ENC_AES, YACA_BCM_CBC,
57                            key, iv, lorem1024, 1024, &enc_data, &enc_len);
58         if (ret)
59                 goto exit;
60
61         dump_hex(enc_data, 16, "Encrypted data (16 of %zu bytes): ", enc_len);
62
63         ret = yaca_decrypt(YACA_ENC_AES, YACA_BCM_CBC,
64                            key, iv,
65                            enc_data, enc_len,
66                            &dec_data, &dec_len);
67         if (ret < 0)
68                 goto exit;
69
70         printf("Decrypted data (16 of %zu bytes): %.16s\n", dec_len, dec_data);
71 exit:
72         if (enc_data)
73                 yaca_free(enc_data);
74         if (dec_data)
75                 yaca_free(dec_data);
76         if (iv != YACA_KEY_NULL)
77                 yaca_key_free(iv);
78         yaca_key_free(key);
79 }
80
81 // Symmetric encryption using advanced API
82 void encrypt_advanced(void)
83 {
84         int ret;
85         yaca_ctx_h ctx;
86         yaca_key_h key = YACA_KEY_NULL;
87         yaca_key_h iv = YACA_KEY_NULL;
88         char *enc = NULL;
89         char *dec = NULL;
90         size_t enc_size;
91         size_t dec_size;
92
93         printf("Plain data (16 of %zu bytes): %.16s\n", (size_t)4096, lorem1024);
94
95         /// Key generation
96
97         ret = yaca_key_derive_pbkdf2("foo bar", "123456789", 10,
98                                      1000, YACA_DIGEST_SHA256,
99                                      YACA_KEY_256BIT, &key);
100         if (ret)
101                 return;
102
103         ret = yaca_key_gen(&iv, YACA_KEY_IV_256BIT, YACA_KEY_TYPE_SYMMETRIC);
104         if (ret)
105                 goto ex_key;
106
107         /// Encryption
108         {
109                 ret = yaca_encrypt_init(&ctx, YACA_ENC_AES, YACA_BCM_CBC,
110                                         key, iv);
111                 if (ret)
112                         goto ex_iv;
113
114                 ret = yaca_encrypt_update(ctx, lorem4096, 4096, NULL, &enc_size);
115                 if (ret != 42)
116                         goto ex_ctx;// TODO: what error code?
117
118                 ret = yaca_get_block_length(ctx);
119                 if (ret < 0)
120                         goto ex_ctx;
121
122                 enc_size += ret ; // Add block size for finalize
123                 enc = yaca_malloc(enc_size);
124                 if (enc == NULL)
125                         goto ex_ctx;
126
127                 size_t out_size = enc_size;
128                 ret = yaca_encrypt_update(ctx, lorem4096, 4096, enc, &out_size);
129                 if (ret < 0)
130                         goto ex_of;
131
132                 size_t rem = enc_size - out_size;
133                 ret = yaca_encrypt_final(ctx, enc + out_size, &rem);
134                 if (ret < 0)
135                         goto ex_of;
136
137                 enc_size = rem + out_size;
138
139                 dump_hex(enc, 16, "Encrypted data (16 of %zu bytes): ", enc_size);
140
141                 yaca_ctx_free(ctx); // TODO: perhaps it should not return value
142         }
143
144         /// Decryption
145         {
146                 ret = yaca_decrypt_init(&ctx, YACA_ENC_AES, YACA_BCM_CBC,
147                                         key, iv);
148                 if (ret < 0) {
149                         yaca_free(enc);
150                         goto ex_iv;
151                 }
152
153                 ret = yaca_decrypt_update(ctx, enc, enc_size, NULL, &dec_size);
154                 if (ret != 42)
155                         goto ex_of; // TODO: what error code?
156
157                 ret = yaca_get_block_length(ctx);
158                 if (ret < 0)
159                         goto ex_of;
160
161                 dec_size += ret; // Add block size for finalize
162                 dec = yaca_malloc(dec_size);
163                 if (dec == NULL)
164                         goto ex_of;
165
166                 size_t out_size = dec_size;
167                 ret = yaca_decrypt_update(ctx, enc, enc_size, dec, &out_size);
168                 if (ret < 0)
169                         goto ex_in;
170
171                 size_t rem = dec_size - out_size;
172                 ret = yaca_encrypt_final(ctx, dec + out_size, &rem);
173                 if (ret < 0)
174                         goto ex_in;
175
176                 dec_size = rem + out_size;
177
178                 printf("Decrypted data (16 of %zu bytes): %.16s\n", dec_size, dec);
179         }
180
181 ex_in:
182         yaca_free(dec);
183 ex_of:
184         yaca_free(enc);
185 ex_ctx:
186         yaca_ctx_free(ctx);
187 ex_iv:
188         yaca_key_free(iv);
189 ex_key:
190         yaca_key_free(key);
191 }
192
193 void encrypt_seal(void)
194 {
195         int ret;
196         yaca_ctx_h ctx = YACA_CTX_NULL;
197         yaca_key_h key_pub = YACA_KEY_NULL;
198         yaca_key_h key_priv = YACA_KEY_NULL;
199         yaca_key_h aes_key = YACA_KEY_NULL;
200         yaca_key_h iv = YACA_KEY_NULL;
201
202         char *enc = NULL;
203         char *dec = NULL;
204         size_t enc_size;
205         size_t dec_size;
206
207         printf("Plain data (16 of %zu bytes): %.16s\n", (size_t)4096, lorem1024);
208
209         /// Generate key pair
210         ret = yaca_key_gen_pair(&key_priv, &key_pub,
211                                 YACA_KEY_2048BIT, YACA_KEY_TYPE_PAIR_RSA);
212         if (ret) return;
213
214         /// Encrypt a.k.a. seal
215         {
216                 ret = yaca_seal_init(&ctx, key_pub,
217                                      YACA_ENC_AES, YACA_BCM_CBC,
218                                      &aes_key, &iv);
219                 if (ret < 0)
220                         goto ex_pk;
221
222                 ret = yaca_seal_update(ctx, lorem4096, 4096, NULL, &enc_size);
223                 if (ret < 0)
224                         goto ex_ak;
225
226                 ret = yaca_get_block_length(ctx);
227                 if (ret < 0)
228                         goto ex_ak;
229
230                 enc_size = enc_size + ret;
231                 enc = yaca_malloc(enc_size);
232                 if (enc == NULL)
233                         goto ex_ak;
234
235                 // Seal and finalize
236                 size_t out_size = enc_size;
237                 ret = yaca_seal_update(ctx, lorem4096, 4096, enc, &out_size);
238                 if (ret < 0)
239                         goto ex_of;
240
241                 size_t rem = enc_size - out_size;
242                 ret = yaca_seal_final(ctx, enc + out_size, &rem);
243                 if (ret < 0)
244                         goto ex_of;
245
246                 enc_size = rem + out_size;
247
248                 dump_hex(enc, 16, "Encrypted data (16 of %zu bytes): ", enc_size);
249
250                 yaca_ctx_free(ctx); // TODO: perhaps it should not return value
251         }
252
253         /// Decrypt a.k.a. open
254         {
255                 ret = yaca_open_init(&ctx, key_priv,
256                                      YACA_ENC_AES, YACA_BCM_CBC,
257                                      aes_key, iv);
258                 if (ret < 0) {
259                         yaca_free(enc);
260                         goto ex_ak;
261                 }
262
263                 ret = yaca_open_update(ctx, enc, enc_size, NULL, &dec_size);
264                 if (ret < 0)
265                         goto ex_of;
266
267                 ret = yaca_get_block_length(ctx);
268                 if (ret < 0)
269                         goto ex_of;
270
271                 dec_size = dec_size + ret;
272                 dec = yaca_malloc(dec_size);
273                 if (dec == NULL)
274                         goto ex_of;
275
276                 // Seal and finalize
277                 size_t out_size = enc_size;
278                 ret = yaca_open_update(ctx, enc, enc_size, dec, &out_size);
279                 if (ret < 0)
280                         goto ex_in;
281
282                 size_t rem = dec_size - out_size;
283                 ret = yaca_open_final(ctx, dec + out_size, &rem);
284                 if (ret < 0)
285                         goto ex_in;
286
287                 dec_size = rem + out_size;
288
289                 printf("Decrypted data (16 of %zu bytes): %.16s\n", (size_t)dec_size, dec);
290
291                 yaca_ctx_free(ctx); // TODO: perhaps it should not return value
292         }
293
294 ex_in:
295         yaca_free(dec);
296 ex_of:
297         yaca_free(enc);
298 ex_ak:
299         yaca_key_free(aes_key);
300         yaca_key_free(iv);
301 ex_pk:
302         yaca_key_free(key_pub);
303         yaca_key_free(key_priv);
304 }
305
306 int main()
307 {
308         int ret = yaca_init();
309         if (ret < 0)
310                 return ret;
311
312         encrypt_simple();
313
314         encrypt_advanced();
315
316         encrypt_seal();
317
318         yaca_exit(); // TODO: what about handing of return value from exit??
319         return ret;
320 }