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