Python3 bindings for YACA
[platform/core/security/yaca.git] / python / yaca / tests.py
1 # Copyright (c) 2017-2018 Samsung Electronics Co., Ltd All Rights Reserved
2
3 # Contact: Lukasz Pawelczyk <l.pawelczyk@samsung.com>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 #     http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License
16
17
18 """
19 These tests are not to test yaca itself. They are more of a
20 syntax test to see that no stupid mistakes has been made in the
21 python binding. To check whether the code runs properly and
22 returns expected things.
23
24 They can also be used as examples.
25 """
26
27 import yaca
28
29
30 def split_into_parts(data, l):
31     return [data[i:i + l] for i in range(0, len(data), l)]
32
33
34 msg = b'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. \
35 Donec hendrerit tempor tellus.  Donec pretium posuere tellus.  Proin \
36 quam nisl, tincidunt et, mattis eget, convallis nec, purus.  Cum \
37 sociis natoque penatibus et magnis dis parturient montes, nascetur \
38 ridiculus mus.  Nulla posuere.  Donec vitae dolor.  Nullam tristique \
39 diam non turpis.  Cras placerat accumsan nulla.  Nullam rutrum.  Nam \
40 vestibulum accumsan nisl.'
41
42 msg_parts = split_into_parts(msg, 5)
43
44
45 def run_all_tests():
46     """Runs all YACA tests/examples. No exceptions means success."""
47
48     yaca.initialize()
49
50     crypto()
51     key_gen()
52     key_exp_imp()
53     key_derive()
54     simple()
55     digest()
56     encrypt_basic()
57     encrypt_rc2_property()
58     encrypt_gcm_property()
59     encrypt_ccm_property()
60     sign()
61     seal()
62     rsa()
63
64     yaca.cleanup()
65
66
67 def crypto():
68
69     msg_whole = b''
70     for part in msg_parts:
71         msg_whole += part
72
73     assert yaca.memcmp(msg, msg_whole, len(msg))
74
75     rand_bytes = yaca.random_bytes(50)
76     assert len(rand_bytes) == 50
77
78
79 def key_gen():
80
81     key_iv_64 = yaca.key_generate(yaca.KEY_TYPE.IV,
82                                   yaca.KEY_BIT_LENGTH.IV_64BIT)
83     assert key_iv_64.get_type() == yaca.KEY_TYPE.IV
84     assert key_iv_64.get_bit_length() == yaca.KEY_BIT_LENGTH.IV_64BIT
85
86     key_iv_128 = yaca.key_generate(yaca.KEY_TYPE.IV,
87                                    yaca.KEY_BIT_LENGTH.IV_128BIT)
88     assert key_iv_128.get_type() == yaca.KEY_TYPE.IV
89     assert key_iv_128.get_bit_length() == yaca.KEY_BIT_LENGTH.IV_128BIT
90
91     key_sym = yaca.key_generate()
92     assert key_sym.get_type() == yaca.KEY_TYPE.SYMMETRIC
93     assert key_sym.get_bit_length() == yaca.KEY_BIT_LENGTH.L256BIT
94
95     key_rsa_prv = yaca.key_generate(yaca.KEY_TYPE.RSA_PRIV,
96                                     yaca.KEY_BIT_LENGTH.L2048BIT)
97     assert key_rsa_prv.get_type() == yaca.KEY_TYPE.RSA_PRIV
98     assert key_rsa_prv.get_bit_length() == yaca.KEY_BIT_LENGTH.L2048BIT
99
100     key_rsa_pub = yaca.key_extract_public(key_rsa_prv)
101     assert key_rsa_pub.get_type() == yaca.KEY_TYPE.RSA_PUB
102     assert key_rsa_pub.get_bit_length() == yaca.KEY_BIT_LENGTH.L2048BIT
103
104     key_dsa_prv = yaca.key_generate(yaca.KEY_TYPE.DSA_PRIV,
105                                     yaca.KEY_BIT_LENGTH.L2048BIT)
106     assert key_dsa_prv.get_type() == yaca.KEY_TYPE.DSA_PRIV
107     assert key_dsa_prv.get_bit_length() == yaca.KEY_BIT_LENGTH.L2048BIT
108
109     key_dsa_pub = yaca.key_extract_public(key_dsa_prv)
110     assert key_dsa_pub.get_type() == yaca.KEY_TYPE.DSA_PUB
111     assert key_dsa_pub.get_bit_length() == yaca.KEY_BIT_LENGTH.L2048BIT
112
113     key_dh_prv = yaca.key_generate(yaca.KEY_TYPE.DH_PRIV,
114                                    yaca.KEY_BIT_LENGTH_DH_RFC.L2048_256)
115     assert key_dh_prv.get_type() == yaca.KEY_TYPE.DH_PRIV
116     assert key_dh_prv.get_bit_length() == 2048
117
118     key_dh_pub = yaca.key_extract_public(key_dh_prv)
119     assert key_dh_pub.get_type() == yaca.KEY_TYPE.DH_PUB
120     assert key_dh_pub.get_bit_length() == 2048
121
122     key_dh_params = yaca.key_extract_parameters(key_dh_prv)
123     key_dh_prv_2 = yaca.key_generate_from_parameters(key_dh_params)
124     assert key_dh_prv_2.get_type() == key_dh_prv.get_type()
125     assert key_dh_prv_2.get_bit_length() == key_dh_prv.get_bit_length()
126
127     key_dh_prv_3 = yaca.key_generate(yaca.KEY_TYPE.DH_PRIV,
128                                      yaca.KEY_LENGTH_DH_GENERATOR_5 | 256)
129     assert key_dh_prv_3.get_type() == yaca.KEY_TYPE.DH_PRIV
130     assert key_dh_prv_3.get_bit_length() == 256
131
132     key_ec_prv = yaca.key_generate(yaca.KEY_TYPE.EC_PRIV,
133                                    yaca.KEY_BIT_LENGTH_EC.PRIME256V1)
134     assert key_ec_prv.get_type() == yaca.KEY_TYPE.EC_PRIV
135     assert key_ec_prv.get_bit_length() == yaca.KEY_BIT_LENGTH_EC.PRIME256V1
136
137     key_ec_pub = yaca.key_extract_public(key_ec_prv)
138     assert key_ec_pub.get_type() == yaca.KEY_TYPE.EC_PUB
139     assert key_ec_pub.get_bit_length() == yaca.KEY_BIT_LENGTH_EC.PRIME256V1
140
141
142 def key_exp_imp():
143     # prepare:
144     key_sym = yaca.key_generate()
145     key_rsa_prv = yaca.key_generate(yaca.KEY_TYPE.RSA_PRIV,
146                                     yaca.KEY_BIT_LENGTH.L2048BIT)
147     # end prepare
148
149     key_sym_exp = yaca.key_export(key_sym)
150     key_sym_imp = yaca.key_import(key_sym_exp)
151     assert key_sym.get_type() == key_sym_imp.get_type()
152     assert key_sym.get_bit_length() == key_sym_imp.get_bit_length()
153
154     key_rsa_prv_exp = yaca.key_export(key_rsa_prv, yaca.KEY_FILE_FORMAT.PEM)
155     key_rsa_prv_imp = yaca.key_import(key_rsa_prv_exp, yaca.KEY_TYPE.RSA_PRIV)
156     assert key_rsa_prv.get_type() == key_rsa_prv_imp.get_type()
157     assert key_rsa_prv.get_bit_length() == key_rsa_prv_imp.get_bit_length()
158
159     key_rsa_prv_exp = yaca.key_export(key_rsa_prv, yaca.KEY_FILE_FORMAT.PEM,
160                                       yaca.KEY_FORMAT.PKCS8, b"password")
161     key_rsa_prv_imp = yaca.key_import(key_rsa_prv_exp, yaca.KEY_TYPE.RSA_PRIV,
162                                       b"password")
163     assert key_rsa_prv.get_type() == key_rsa_prv_imp.get_type()
164     assert key_rsa_prv.get_bit_length() == key_rsa_prv_imp.get_bit_length()
165
166
167 def key_derive():
168     # prepare:
169     key_dh_prv = yaca.key_generate(yaca.KEY_TYPE.DH_PRIV,
170                                    yaca.KEY_BIT_LENGTH_DH_RFC.L2048_256)
171     key_dh_pub = yaca.key_extract_public(key_dh_prv)
172     key_dh_params = yaca.key_extract_parameters(key_dh_prv)
173     key_dh_prv_2 = yaca.key_generate_from_parameters(key_dh_params)
174     key_dh_pub_2 = yaca.key_extract_public(key_dh_prv_2)
175     # end prepare
176
177     secret = yaca.key_derive_dh(key_dh_prv_2, key_dh_pub)
178     assert len(secret) == 256
179
180     secret_2 = yaca.key_derive_dh(key_dh_prv, key_dh_pub_2)
181     assert secret == secret_2
182
183     key_material = yaca.key_derive_kdf(secret, 128)
184     assert len(key_material) == 128
185
186     key_derived = yaca.key_derive_pbkdf2(b'password')
187     assert key_derived.get_type() == yaca.KEY_TYPE.SYMMETRIC
188     assert key_derived.get_bit_length() == yaca.KEY_BIT_LENGTH.L256BIT
189
190
191 def simple():
192     # prepare:
193     key_sym = yaca.key_generate()
194     key_iv_128 = yaca.key_generate(yaca.KEY_TYPE.IV,
195                                    yaca.KEY_BIT_LENGTH.IV_128BIT)
196     key_rsa_prv = yaca.key_generate(yaca.KEY_TYPE.RSA_PRIV,
197                                     yaca.KEY_BIT_LENGTH.L2048BIT)
198     key_rsa_pub = yaca.key_extract_public(key_rsa_prv)
199     # end prepare
200
201     enc_simple = yaca.simple_encrypt(key_sym, msg,
202                                      yaca.ENCRYPT_ALGORITHM.AES,
203                                      yaca.BLOCK_CIPHER_MODE.CBC, key_iv_128)
204     dec_simple = yaca.simple_decrypt(key_sym, enc_simple,
205                                      yaca.ENCRYPT_ALGORITHM.AES,
206                                      yaca.BLOCK_CIPHER_MODE.CBC, key_iv_128)
207     assert msg == dec_simple
208
209     dgst_simple = yaca.simple_calculate_digest(msg,
210                                                yaca.DIGEST_ALGORITHM.SHA512)
211     assert len(dgst_simple) == 64
212
213     hmac_simple = yaca.simple_calculate_hmac(key_sym, msg,
214                                              yaca.DIGEST_ALGORITHM.SHA512)
215     assert len(hmac_simple) == 64
216
217     cmac_simple = yaca.simple_calculate_cmac(key_sym, msg,
218                                              yaca.ENCRYPT_ALGORITHM.AES)
219     assert len(cmac_simple) == 16
220
221     sig_simple = yaca.simple_calculate_signature(key_rsa_prv, msg,
222                                                  yaca.DIGEST_ALGORITHM.SHA512)
223     assert yaca.simple_verify_signature(key_rsa_pub, msg, sig_simple,
224                                         yaca.DIGEST_ALGORITHM.SHA512)
225
226
227 def digest():
228     # prepare:
229     dgst_simple = yaca.simple_calculate_digest(msg,
230                                                yaca.DIGEST_ALGORITHM.SHA512)
231     # end prepare
232
233     ctx = yaca.digest_initialize(yaca.DIGEST_ALGORITHM.SHA512)
234     for part in msg_parts:
235         yaca.digest_update(ctx, part)
236     dgst = yaca.digest_finalize(ctx)
237
238     assert dgst == dgst_simple
239
240
241 def encrypt_basic():
242     # prepare:
243     key_sym = yaca.key_generate()
244     key_iv_128 = yaca.key_generate(yaca.KEY_TYPE.IV,
245                                    yaca.KEY_BIT_LENGTH.IV_128BIT)
246     enc_simple = yaca.simple_encrypt(key_sym, msg,
247                                      yaca.ENCRYPT_ALGORITHM.AES,
248                                      yaca.BLOCK_CIPHER_MODE.CBC, key_iv_128)
249     # end prepare
250
251     len_iv = yaca.encrypt_get_iv_bit_length(yaca.ENCRYPT_ALGORITHM.AES,
252                                             yaca.BLOCK_CIPHER_MODE.CBC,
253                                             yaca.KEY_BIT_LENGTH.L256BIT)
254     assert len_iv == 128
255
256     ctx = yaca.encrypt_initialize(key_sym, bcm=yaca.BLOCK_CIPHER_MODE.CBC,
257                                   iv=key_iv_128)
258     enc = b''
259     for part in msg_parts:
260         enc += yaca.encrypt_update(ctx, part)
261     enc += yaca.encrypt_finalize(ctx)
262
263     assert enc == enc_simple
264
265     enc_parts = split_into_parts(enc, 5)
266
267     ctx = yaca.decrypt_initialize(key_sym, bcm=yaca.BLOCK_CIPHER_MODE.CBC,
268                                   iv=key_iv_128)
269     dec = b''
270     for part in enc_parts:
271         dec += yaca.decrypt_update(ctx, part)
272     dec += yaca.decrypt_finalize(ctx)
273
274     assert msg == dec
275
276
277 def encrypt_rc2_property():
278     # prepare:
279     key_sym = yaca.key_generate()
280     # end prepare
281
282     len_iv = yaca.encrypt_get_iv_bit_length(yaca.ENCRYPT_ALGORITHM.UNSAFE_RC2,
283                                             yaca.BLOCK_CIPHER_MODE.ECB,
284                                             yaca.KEY_BIT_LENGTH.L256BIT)
285     assert len_iv == 0
286
287     ctx = yaca.encrypt_initialize(key_sym, yaca.ENCRYPT_ALGORITHM.UNSAFE_RC2,
288                                   yaca.BLOCK_CIPHER_MODE.ECB)
289     yaca.context_set_property(ctx, yaca.PROPERTY.RC2_EFFECTIVE_KEY_BITS, 192)
290     enc = b''
291     for part in msg_parts:
292         enc += yaca.encrypt_update(ctx, part)
293     enc += yaca.encrypt_finalize(ctx)
294
295     enc_parts = split_into_parts(enc, 5)
296
297     ctx = yaca.decrypt_initialize(key_sym, yaca.ENCRYPT_ALGORITHM.UNSAFE_RC2,
298                                   yaca.BLOCK_CIPHER_MODE.ECB)
299     yaca.context_set_property(ctx, yaca.PROPERTY.RC2_EFFECTIVE_KEY_BITS, 192)
300     dec = b''
301     for part in enc_parts:
302         dec += yaca.decrypt_update(ctx, part)
303     dec += yaca.decrypt_finalize(ctx)
304
305     assert msg == dec
306
307
308 def encrypt_gcm_property():
309     # prepare:
310     key_sym = yaca.key_generate()
311     key_iv_128 = yaca.key_generate(yaca.KEY_TYPE.IV,
312                                    yaca.KEY_BIT_LENGTH.IV_128BIT)
313     # end prepare
314
315     tag_len = 16
316     aad = yaca.random_bytes(16)
317     ctx = yaca.encrypt_initialize(key_sym, bcm=yaca.BLOCK_CIPHER_MODE.GCM,
318                                   iv=key_iv_128)
319     yaca.context_set_property(ctx, yaca.PROPERTY.GCM_AAD, aad)
320     enc = b''
321     for part in msg_parts:
322         enc += yaca.encrypt_update(ctx, part)
323     enc += yaca.encrypt_finalize(ctx)
324     yaca.context_set_property(ctx, yaca.PROPERTY.GCM_TAG_LEN, tag_len)
325     tag = yaca.context_get_property(ctx, yaca.PROPERTY.GCM_TAG)
326     assert len(tag) == tag_len
327
328     enc_parts = split_into_parts(enc, 5)
329
330     ctx = yaca.decrypt_initialize(key_sym, bcm=yaca.BLOCK_CIPHER_MODE.GCM,
331                                   iv=key_iv_128)
332     yaca.context_set_property(ctx, yaca.PROPERTY.GCM_AAD, aad)
333     dec = b''
334     for part in enc_parts:
335         dec += yaca.decrypt_update(ctx, part)
336     yaca.context_set_property(ctx, yaca.PROPERTY.GCM_TAG, tag)
337     dec += yaca.decrypt_finalize(ctx)
338
339     assert msg == dec
340
341
342 def encrypt_ccm_property():
343     # prepare:
344     key_sym = yaca.key_generate()
345     key_iv_64 = yaca.key_generate(yaca.KEY_TYPE.IV,
346                                   yaca.KEY_BIT_LENGTH.IV_64BIT)
347     # end prepare
348
349     tag_len = 12
350     aad = yaca.random_bytes(16)
351     ctx = yaca.encrypt_initialize(key_sym, bcm=yaca.BLOCK_CIPHER_MODE.CCM,
352                                   iv=key_iv_64)
353     yaca.context_set_property(ctx, yaca.PROPERTY.CCM_TAG_LEN, tag_len)
354     yaca.encrypt_update(ctx, len(msg))  # encrypt_update second type of usage
355     yaca.context_set_property(ctx, yaca.PROPERTY.CCM_AAD, aad)
356     enc = yaca.encrypt_update(ctx, msg)
357     enc += yaca.encrypt_finalize(ctx)
358     tag = yaca.context_get_property(ctx, yaca.PROPERTY.CCM_TAG)
359     assert len(tag) == tag_len
360
361     ctx = yaca.decrypt_initialize(key_sym, bcm=yaca.BLOCK_CIPHER_MODE.CCM,
362                                   iv=key_iv_64)
363     yaca.context_set_property(ctx, yaca.PROPERTY.CCM_TAG, tag)
364     yaca.decrypt_update(ctx, len(enc))  # decrypt_update second type of usage
365     yaca.context_set_property(ctx, yaca.PROPERTY.CCM_AAD, aad)
366     dec = yaca.decrypt_update(ctx, enc)
367     dec += yaca.decrypt_finalize(ctx)
368
369     assert msg == dec
370
371
372 def sign():
373     # prepare:
374     key_sym = yaca.key_generate()
375     key_rsa_prv = yaca.key_generate(yaca.KEY_TYPE.RSA_PRIV,
376                                     yaca.KEY_BIT_LENGTH.L2048BIT)
377     key_rsa_pub = yaca.key_extract_public(key_rsa_prv)
378     hmac_simple = yaca.simple_calculate_hmac(key_sym, msg,
379                                              yaca.DIGEST_ALGORITHM.SHA512)
380     cmac_simple = yaca.simple_calculate_cmac(key_sym, msg,
381                                              yaca.ENCRYPT_ALGORITHM.AES)
382     sign_simple = yaca.simple_calculate_signature(key_rsa_prv, msg,
383                                                   yaca.DIGEST_ALGORITHM.SHA512)
384     # end prepare
385
386     ctx = yaca.sign_initialize_hmac(key_sym, yaca.DIGEST_ALGORITHM.SHA512)
387     for part in msg_parts:
388         yaca.sign_update(ctx, part)
389     hmac = yaca.sign_finalize(ctx)
390
391     assert hmac == hmac_simple
392
393     ctx = yaca.sign_initialize_cmac(key_sym, yaca.ENCRYPT_ALGORITHM.AES)
394     for part in msg_parts:
395         yaca.sign_update(ctx, part)
396     cmac = yaca.sign_finalize(ctx)
397
398     assert cmac == cmac_simple
399
400     ctx = yaca.sign_initialize(key_rsa_prv, yaca.DIGEST_ALGORITHM.SHA512)
401     for part in msg_parts:
402         yaca.sign_update(ctx, part)
403     sig = yaca.sign_finalize(ctx)
404
405     assert sig == sign_simple  # won't work for DSA
406
407     ctx = yaca.verify_initialize(key_rsa_pub, yaca.DIGEST_ALGORITHM.SHA512)
408     for part in msg_parts:
409         yaca.verify_update(ctx, part)
410     assert yaca.verify_finalize(ctx, sig)
411
412     # SIGN + SET PADDING
413
414     ctx = yaca.sign_initialize(key_rsa_prv)
415     for part in msg_parts:
416         yaca.sign_update(ctx, part)
417     yaca.context_set_property(ctx, yaca.PROPERTY.PADDING,
418                               yaca.PADDING.PKCS1_PSS)
419     sig = yaca.sign_finalize(ctx)
420
421     ctx = yaca.verify_initialize(key_rsa_pub)
422     for part in msg_parts:
423         yaca.verify_update(ctx, part)
424     yaca.context_set_property(ctx, yaca.PROPERTY.PADDING,
425                               yaca.PADDING.PKCS1_PSS)
426     assert yaca.verify_finalize(ctx, sig)
427
428
429 def seal():
430     # prepare:
431     key_rsa_prv = yaca.key_generate(yaca.KEY_TYPE.RSA_PRIV,
432                                     yaca.KEY_BIT_LENGTH.L2048BIT)
433     key_rsa_pub = yaca.key_extract_public(key_rsa_prv)
434     # end prepare
435
436     ctx, key_seal, iv = yaca.seal_initialize(key_rsa_pub,
437                                              bcm=yaca.BLOCK_CIPHER_MODE.CBC)
438     sealed = b''
439     for part in msg_parts:
440         sealed += yaca.seal_update(ctx, part)
441     sealed += yaca.seal_finalize(ctx)
442
443     sealed_parts = split_into_parts(sealed, 5)
444
445     ctx = yaca.open_initialize(key_rsa_prv, key_seal, iv,
446                                bcm=yaca.BLOCK_CIPHER_MODE.CBC)
447     opened = b''
448     for part in sealed_parts:
449         opened += yaca.open_update(ctx, part)
450     opened += yaca.open_finalize(ctx)
451
452     assert opened == msg
453
454
455 def rsa():
456     # prepare:
457     key_rsa_prv = yaca.key_generate(yaca.KEY_TYPE.RSA_PRIV,
458                                     yaca.KEY_BIT_LENGTH.L2048BIT)
459     key_rsa_pub = yaca.key_extract_public(key_rsa_prv)
460     # end prepare
461
462     msg_short_max = int(2048 / 8 - 11)
463     msg_short = msg[:msg_short_max]
464
465     enc_rsa = yaca.rsa_public_encrypt(key_rsa_pub, msg_short)
466     dec_rsa = yaca.rsa_private_decrypt(key_rsa_prv, enc_rsa)
467
468     assert dec_rsa == msg_short
469
470     enc_rsa = yaca.rsa_private_encrypt(key_rsa_prv, msg_short)
471     dec_rsa = yaca.rsa_public_decrypt(key_rsa_pub, enc_rsa)
472
473     assert dec_rsa == msg_short