303bcd7d5be5d7c8b07094bbcec6dd8ce10fa9e6
[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         const yaca_enc_algo_e algo = YACA_ENC_AES;
37         const yaca_block_cipher_mode_e bcm = YACA_BCM_CBC;
38         const size_t key_bits = YACA_KEY_256BIT;
39         int ret;
40         yaca_key_h key = YACA_KEY_NULL;
41         yaca_key_h iv = YACA_KEY_NULL;
42         char *enc_data = NULL;
43         char *dec_data = NULL;
44         size_t enc_len;
45         size_t dec_len;
46         int iv_bits;
47
48         printf("Simple Encrypt\nPlain data (16 of %zu bytes): %.16s\n",
49                LOREM1024_SIZE, lorem1024);
50
51         ret = yaca_key_derive_pbkdf2("foo bar", "123456789", 10, 1000,
52                                      YACA_DIGEST_SHA256, key_bits, &key);
53         if (ret)
54                 return;
55
56         iv_bits = yaca_get_iv_bits(algo, bcm, key_bits);
57         if (iv_bits < 0)
58                 return;
59
60         if (iv_bits > 0) {
61                 ret = yaca_key_gen(&iv, YACA_KEY_TYPE_IV, iv_bits);
62                 if (ret)
63                         goto exit;
64         }
65
66         ret = yaca_encrypt(algo, bcm, key, iv, lorem1024, LOREM1024_SIZE,
67                            &enc_data, &enc_len);
68         if (ret)
69                 goto exit;
70
71         dump_hex(enc_data, 16, "Encrypted data (16 of %zu bytes): ", enc_len);
72
73         ret = yaca_decrypt(algo, bcm, key, iv, enc_data, enc_len, &dec_data,
74                            &dec_len);
75         if (ret < 0)
76                 goto exit;
77
78         printf("Decrypted data (16 of %zu bytes): %.16s\n", dec_len, dec_data);
79 exit:
80         if (enc_data)
81                 yaca_free(enc_data);
82         if (dec_data)
83                 yaca_free(dec_data);
84         if (iv != YACA_KEY_NULL)
85                 yaca_key_free(iv);
86         yaca_key_free(key);
87 }
88
89 // Symmetric encryption using advanced API
90 void encrypt_advanced(void)
91 {
92         const yaca_enc_algo_e algo = YACA_ENC_AES;
93         const yaca_block_cipher_mode_e bcm = YACA_BCM_CBC;
94         const size_t key_bits = YACA_KEY_256BIT;
95         int ret;
96         yaca_ctx_h ctx;
97         yaca_key_h key = YACA_KEY_NULL;
98         yaca_key_h iv = YACA_KEY_NULL;
99         char *enc = NULL;
100         char *dec = NULL;
101         size_t enc_size;
102         size_t dec_size;
103         int iv_bits;
104
105         printf("Advanced Encrypt\nPlain data (16 of %zu bytes): %.16s\n",
106                LOREM4096_SIZE, lorem4096);
107
108         /// Key generation
109
110         ret = yaca_key_derive_pbkdf2("foo bar", "123456789", 10, 1000,
111                                      YACA_DIGEST_SHA256, key_bits, &key);
112         if (ret)
113                 return;
114
115         iv_bits = yaca_get_iv_bits(algo, bcm, key_bits);
116         if (iv_bits < 0)
117                 goto ex_key;
118
119         if (iv_bits > 0) {
120                 ret = yaca_key_gen(&iv, YACA_KEY_TYPE_IV, iv_bits);
121                 if (ret)
122                         goto ex_key;
123         }
124
125         /// Encryption
126         {
127                 size_t block_len;
128                 size_t output_len;
129                 size_t out_size;
130                 size_t rem;
131
132                 ret = yaca_encrypt_init(&ctx, algo, bcm, key, iv);
133                 if (ret)
134                         goto ex_iv;
135
136                 ret = yaca_get_block_length(ctx);
137                 if (ret < 0)
138                         goto ex_ctx;
139
140                 block_len = ret;
141
142                 ret = yaca_get_output_length(ctx, LOREM4096_SIZE);
143                 if (ret < 0)
144                         goto ex_ctx;
145
146                 output_len = ret;
147
148                 /* Calculate max output: size of update + final chunks */
149                 enc_size = output_len + block_len;
150                 enc = yaca_malloc(enc_size);
151                 if (enc == NULL)
152                         goto ex_ctx;
153
154                 out_size = enc_size;
155                 ret = yaca_encrypt_update(ctx, lorem4096, LOREM4096_SIZE, enc,
156                                           &out_size);
157                 if (ret < 0)
158                         goto ex_of;
159
160                 rem = enc_size - out_size;
161                 ret = yaca_encrypt_final(ctx, enc + out_size, &rem);
162                 if (ret < 0)
163                         goto ex_of;
164
165                 enc_size = rem + out_size;
166
167                 dump_hex(enc, 16, "Encrypted data (16 of %zu bytes): ",
168                          enc_size);
169
170                 yaca_ctx_free(ctx); // TODO: perhaps it should not return value
171         }
172
173         /// Decryption
174         {
175                 size_t block_len;
176                 size_t output_len;
177                 size_t out_size;
178                 size_t rem;
179
180                 ret = yaca_decrypt_init(&ctx, algo, bcm, key, iv);
181                 if (ret < 0) {
182                         ctx = YACA_CTX_NULL;
183                         goto ex_of;
184                 }
185
186                 ret = yaca_get_block_length(ctx);
187                 if (ret < 0)
188                         goto ex_of;
189
190                 block_len = ret;
191
192                 ret = yaca_get_output_length(ctx, LOREM4096_SIZE);
193                 if (ret < 0)
194                         goto ex_ctx;
195
196                 output_len = ret;
197
198                 /* Calculate max output: size of update + final chunks */
199                 dec_size = output_len + block_len;
200                 dec = yaca_malloc(dec_size);
201                 if (dec == NULL)
202                         goto ex_of;
203
204                 out_size = dec_size;
205                 ret = yaca_decrypt_update(ctx, enc, enc_size, dec, &out_size);
206                 if (ret < 0)
207                         goto ex_in;
208
209                 rem = dec_size - out_size;
210                 ret = yaca_decrypt_final(ctx, dec + out_size, &rem);
211                 if (ret < 0)
212                         goto ex_in;
213
214                 dec_size = rem + out_size;
215
216                 printf("Decrypted data (16 of %zu bytes): %.16s\n", dec_size, dec);
217         }
218
219 ex_in:
220         yaca_free(dec);
221 ex_of:
222         yaca_free(enc);
223 ex_ctx:
224         yaca_ctx_free(ctx);
225 ex_iv:
226         yaca_key_free(iv);
227 ex_key:
228         yaca_key_free(key);
229 }
230
231 int main()
232 {
233         int ret = yaca_init();
234         if (ret < 0)
235                 return ret;
236
237         encrypt_simple();
238
239         encrypt_advanced();
240
241         yaca_exit(); // TODO: what about handing of return value from exit??
242         return ret;
243 }