1%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1999-2020. All Rights Reserved.
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
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%% %CopyrightEnd%
19%%
20-module(crypto_SUITE).
21
22-include_lib("common_test/include/ct.hrl").
23
24
25-export([
26         %% CT callbacks:
27         suite/0,
28         all/0,
29         groups/0,
30         init_per_suite/1,
31         end_per_suite/1,
32         init_per_group/2,
33         end_per_group/2,
34         init_per_testcase/2,
35         end_per_testcase/2,
36
37         %% Test cases:
38         aead_bad_tag/1,
39         aead_ng/1,
40         all_ciphers/1,
41         api_errors_ecdh/1,
42         api_ng/0,
43         api_ng/1,
44         api_ng_one_shot/0,
45         api_ng_one_shot/1,
46         api_ng_tls/0,
47         api_ng_tls/1,
48         app/0,
49         app/1,
50         appup/0,
51         appup/1,
52         bad_combo/1,
53         bad_key_length/1,
54         bad_cipher_name/1,
55         bad_generate_key_name/1,
56         bad_hash_name/1,
57         bad_mac_name/1,
58         bad_sign_name/1,
59         bad_verify_name/1,
60         cipher_info/0,
61         cipher_info/1,
62         cipher_info_prop_aead_attr/0,
63         cipher_info_prop_aead_attr/1,
64         cipher_padding/1,
65         compute/0,
66         compute/1,
67         compute_bug/0,
68         compute_bug/1,
69         crypto_load/1,
70         crypto_load_and_call/1,
71         exor/0,
72         exor/1,
73         generate/0,
74         generate/1,
75         generate_compute/0,
76         generate_compute/1,
77         hash/0,
78         hash/1,
79         hash_info/0,
80         hash_info/1,
81         info/1,
82         mod_pow/0,
83         mod_pow/1,
84         no_aead_ng/0,
85         no_aead_ng/1,
86         no_generate_compute/0,
87         no_generate_compute/1,
88         no_hash/0,
89         no_hash/1,
90         no_sign_verify/0,
91         no_sign_verify/1,
92         no_support/0,
93         no_support/1,
94         node_supports_cache/1,
95         private_encrypt/0,
96         private_encrypt/1,
97         public_encrypt/0,
98         public_encrypt/1,
99         rand_plugin/0,
100         rand_plugin/1,
101         rand_plugin_s/0,
102         rand_plugin_s/1,
103         rand_threads/0,
104         rand_threads/1,
105         rand_uniform/0,
106         rand_uniform/1,
107         sign_verify/0,
108         sign_verify/1,
109         ec_key_padding/1,
110         use_all_ec_sign_verify/1,
111         use_all_ecdh_generate_compute/1,
112         use_all_eddh_generate_compute/1,
113
114         %% Others:
115         aes_128_cbc/1,
116         aes_128_ccm/1,
117         aes_128_cfb128/1,
118         aes_128_cfb8/1,
119         aes_128_ctr/1,
120         aes_128_ecb/1,
121         aes_128_gcm/1,
122         aes_192_cbc/1,
123         aes_192_ccm/1,
124         aes_192_cfb128/1,
125         aes_192_cfb8/1,
126         aes_192_ctr/1,
127         aes_192_ecb/1,
128         aes_192_gcm/1,
129         aes_256_cbc/1,
130         aes_256_ccm/1,
131         aes_256_cfb128/1,
132         aes_256_cfb8/1,
133         aes_256_ctr/1,
134         aes_256_ecb/1,
135         aes_256_gcm/1,
136         aes_cbc/1,
137         aes_cbc128/1,
138         aes_cbc256/1,
139         aes_ccm/1,
140         aes_cfb128/1,
141         aes_cfb8/1,
142         aes_ecb/1,
143         aes_gcm/1,
144         blowfish_cbc/1,
145         blowfish_cfb64/1,
146         blowfish_ecb/1,
147         blowfish_ofb64/1,
148         chacha20/1,
149         chacha20_poly1305/1,
150         des3_cbc/1,
151         des3_cbf/1,
152         des3_cfb/1,
153         des_cbc/1,
154         des_cfb/1,
155         des_ede3/1,
156         des_ede3_cbc/1,
157         des_ede3_cfb/1,
158         mac_check/1,
159         rc2_cbc/1,
160         rc4/1,
161         ripemd160_incr_digest/0,
162         ripemd160_incr_msgs/0,
163         rsa_oaep/0,
164         rsa_oaep256/0,
165         rsa_oaep_label/0
166        ]).
167
168%%--------------------------------------------------------------------
169%% Common Test interface functions -----------------------------------
170%%--------------------------------------------------------------------
171
172suite() -> [{ct_hooks,[ts_install_cth]}].
173
174all() ->
175    [%%crypto_load,
176     %%crypto_load_and_call,
177     app,
178     {group, api_errors},
179     appup,
180     all_ciphers,
181     {group, fips},
182     {group, non_fips},
183     cipher_padding,
184     ec_key_padding,
185     node_supports_cache,
186     mod_pow,
187     exor,
188     rand_uniform,
189     rand_threads,
190     rand_plugin,
191     rand_plugin_s,
192     info,
193     cipher_info,
194     hash_info
195    ].
196
197-define(NEW_CIPHER_TYPE_SCHEMA,
198       ).
199
200groups() ->
201    [{non_fips, [], [
202                     {group, blake2b},
203                     {group, blake2s},
204                     {group, dss},
205                     {group, ecdsa},
206                     {group, ed25519},
207                     {group, ed448},
208                     {group, rsa},
209
210                     {group, md4},
211                     {group, md5},
212                     {group, ripemd160},
213                     {group, sha224},
214                     {group, sha256},
215                     {group, sha384},
216                     {group, sha3_224},
217                     {group, sha3_256},
218                     {group, sha3_384},
219                     {group, sha3_512},
220                     {group, sha512},
221                     {group, sha},
222
223                     {group, dh},
224                     {group, ecdh},
225                     {group, eddh},
226                     {group, srp},
227
228		     {group, chacha20_poly1305},
229		     {group, chacha20},
230                     {group, blowfish_cbc},
231                     {group, blowfish_cfb64},
232                     {group, blowfish_ecb},
233                     {group, blowfish_ofb64},
234
235                     {group, des_cbc},
236                     {group, des_cfb},
237                     {group, rc2_cbc},
238                     {group, rc4},
239
240                     {group, des_ede3_cbc},
241                     {group, des_ede3_cfb},
242                     {group, aes_128_cbc},
243                     {group, aes_192_cbc},
244                     {group, aes_256_cbc},
245                     {group, aes_128_ctr},
246                     {group, aes_192_ctr},
247                     {group, aes_256_ctr},
248                     {group, aes_128_ccm},
249                     {group, aes_192_ccm},
250                     {group, aes_256_ccm},
251                     {group, aes_128_ecb},
252                     {group, aes_192_ecb},
253                     {group, aes_256_ecb},
254                     {group, aes_128_gcm},
255                     {group, aes_192_gcm},
256                     {group, aes_256_gcm},
257                     {group, des_ede3_cbc},
258                     {group, des_ede3_cfb},
259                     {group, aes_128_cfb128},
260                     {group, aes_192_cfb128},
261                     {group, aes_256_cfb128},
262                     {group, aes_128_cfb8},
263                     {group, aes_192_cfb8},
264                     {group, aes_256_cfb8}
265                    ]},
266     {fips, [], [
267                 {group, no_blake2b},
268                 {group, no_blake2s},
269                 {group, dss},
270                 {group, ecdsa},
271                 {group, no_ed25519},
272                 {group, no_ed448},
273                 {group, rsa},
274
275                 {group, no_md4},
276                 {group, no_md5},
277                 {group, no_ripemd160},
278                 {group, sha},
279                 {group, sha224},
280                 {group, sha256},
281                 {group, sha384},
282                 {group, sha512},
283
284                 {group, dh},
285                 {group, ecdh},
286                 {group, no_srp},
287
288		 {group, no_chacha20_poly1305},
289		 {group, no_chacha20},
290                 {group, no_blowfish_cbc},
291                 {group, no_blowfish_cfb64},
292                 {group, no_blowfish_ecb},
293                 {group, no_blowfish_ofb64},
294
295                 {group, no_des_cbc},
296                 {group, no_des_cfb},
297                 {group, no_rc2_cbc},
298                 {group, no_rc4},
299
300                 {group, des_ede3_cbc},
301                 {group, des_ede3_cfb},
302                 {group, aes_128_cbc},
303                 {group, aes_192_cbc},
304                 {group, aes_256_cbc},
305                 {group, aes_128_ctr},
306                 {group, aes_192_ctr},
307                 {group, aes_256_ctr},
308                 {group, aes_128_ccm},
309                 {group, aes_192_ccm},
310                 {group, aes_256_ccm},
311                 {group, aes_128_ecb},
312                 {group, aes_192_ecb},
313                 {group, aes_256_ecb},
314                 {group, aes_128_gcm},
315                 {group, aes_192_gcm},
316                 {group, aes_256_gcm},
317                 {group, des_ede3_cbc},
318                 {group, des_ede3_cfb},
319                 {group, aes_128_cfb128},
320                 {group, aes_192_cfb128},
321                 {group, aes_256_cfb128},
322                 {group, aes_128_cfb8},
323                 {group, aes_192_cfb8},
324                 {group, aes_256_cfb8}
325                ]},
326
327     {md4,                  [], [hash]},
328     {md5,                  [], [hash]},
329     {ripemd160,            [], [hash]},
330     {sha,                  [], [hash]},
331     {sha224,               [], [hash]},
332     {sha256,               [], [hash]},
333     {sha384,               [], [hash]},
334     {sha512,               [], [hash]},
335     {sha3_224,             [], [hash]},
336     {sha3_256,             [], [hash]},
337     {sha3_384,             [], [hash]},
338     {sha3_512,             [], [hash]},
339     {blake2b,              [], [hash]},
340     {blake2s,              [], [hash]},
341     {no_blake2b,           [], [no_hash]},
342     {no_blake2s,           [], [no_hash]},
343     {rsa,                  [], [sign_verify,
344                                 public_encrypt,
345                                 private_encrypt,
346                                 generate
347                                ]},
348     {dss,                  [], [sign_verify
349                                 %% Does not work yet:  ,public_encrypt, private_encrypt
350                                ]},
351     {ecdsa,                [], [sign_verify, use_all_ec_sign_verify
352                                 %% Does not work yet:  ,public_encrypt, private_encrypt
353                                ]},
354     {ed25519,              [], [sign_verify,
355                                 %% Does not work yet:  ,public_encrypt, private_encrypt
356                                 generate
357                              ]},
358     {ed448,                [], [sign_verify,
359                                 %% Does not work yet:  ,public_encrypt, private_encrypt
360                                 generate
361                                ]},
362     {dh,                   [], [generate_compute, compute_bug]},
363     {ecdh,                 [], [compute, generate, use_all_ecdh_generate_compute]},
364     {eddh,                 [], [compute, generate, use_all_eddh_generate_compute]},
365     {srp,                  [], [generate_compute]},
366     {des_cbc,              [], [api_ng, api_ng_one_shot, api_ng_tls]},
367     {des_cfb,              [], [api_ng, api_ng_one_shot, api_ng_tls]},
368     {des_ede3_cbc,         [], [api_ng, api_ng_one_shot, api_ng_tls]},
369     {des_ede3_cfb,         [], [api_ng, api_ng_one_shot, api_ng_tls]},
370     {rc2_cbc,              [], [api_ng, api_ng_one_shot, api_ng_tls]},
371     {aes_cfb8,             [], []},
372     {aes_128_cfb8,         [], [api_ng, api_ng_one_shot, api_ng_tls]},
373     {aes_192_cfb8,         [], [api_ng, api_ng_one_shot, api_ng_tls]},
374     {aes_256_cfb8,         [], [api_ng, api_ng_one_shot, api_ng_tls]},
375     {no_aes_cfb8,          [], [no_support]},
376     {aes_cfb128,           [], []},
377     {aes_128_cfb128,       [], [api_ng, api_ng_one_shot, api_ng_tls]},
378     {aes_192_cfb128,       [], [api_ng, api_ng_one_shot, api_ng_tls]},
379     {aes_256_cfb128,       [], [api_ng, api_ng_one_shot, api_ng_tls]},
380     {no_aes_cfb128,        [], [no_support]},
381     {blowfish_cbc,         [], [api_ng, api_ng_one_shot, api_ng_tls]},
382     {blowfish_ecb,         [], [api_ng, api_ng_one_shot]},
383     {blowfish_cfb64,       [], [api_ng, api_ng_one_shot, api_ng_tls]},
384     {blowfish_ofb64,       [], [api_ng, api_ng_one_shot, api_ng_tls]},
385     {rc4,                  [], [api_ng, api_ng_one_shot, api_ng_tls]},
386     {chacha20_poly1305,    [], [aead_ng, aead_bad_tag]},
387     {chacha20,             [], [api_ng, api_ng_one_shot, api_ng_tls]},
388     {no_aes_cfb128,        [], [no_support]},
389     {no_md4,               [], [no_support, no_hash]},
390     {no_md5,               [], [no_support, no_hash]},
391     {no_ed25519,           [], [no_support, no_sign_verify
392                                 %% Does not work yet:  ,public_encrypt, private_encrypt
393                                ]},
394     {no_ed448,             [], [no_support, no_sign_verify
395                                 %% Does not work yet:  ,public_encrypt, private_encrypt
396                                ]},
397     {no_ripemd160,         [], [no_support, no_hash]},
398     {no_srp,               [], [no_support, no_generate_compute]},
399     {no_des_cbc,           [], [no_support]},
400     {no_des_cfb,           [], [no_support]},
401     {no_blowfish_cbc,      [], [no_support]},
402     {no_blowfish_ecb,      [], [no_support]},
403     {no_blowfish_cfb64,    [], [no_support]},
404     {no_blowfish_ofb64,    [], [no_support]},
405     {no_chacha20_poly1305, [], [no_support, no_aead_ng]},
406     {no_chacha20,          [], [no_support]},
407     {no_rc2_cbc,           [], [no_support]},
408     {no_rc4,               [], [no_support]},
409     {api_errors,           [], [api_errors_ecdh,
410                                 bad_combo,
411                                 bad_key_length,
412                                 bad_cipher_name,
413                                 bad_generate_key_name,
414                                 bad_hash_name,
415                                 bad_mac_name,
416                                 bad_sign_name,
417                                 bad_verify_name
418                                ]},
419
420     %% New cipher nameing schema
421     {des_ede3_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls]},
422     {des_ede3_cfb, [], [api_ng, api_ng_one_shot, api_ng_tls]},
423     {aes_128_cbc,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
424     {aes_192_cbc,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
425     {aes_256_cbc,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
426     {aes_128_ctr,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
427     {aes_192_ctr,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
428     {aes_256_ctr,  [], [api_ng, api_ng_one_shot, api_ng_tls]},
429     {aes_128_ccm,  [], [aead_ng, aead_bad_tag]},
430     {aes_192_ccm,  [], [aead_ng, aead_bad_tag]},
431     {aes_256_ccm,  [], [aead_ng, aead_bad_tag]},
432     {aes_128_ecb,  [], [api_ng, api_ng_one_shot]},
433     {aes_192_ecb,  [], [api_ng, api_ng_one_shot]},
434     {aes_256_ecb,  [], [api_ng, api_ng_one_shot]},
435     {aes_128_gcm,  [], [aead_ng, aead_bad_tag]},
436     {aes_192_gcm,  [], [aead_ng, aead_bad_tag]},
437     {aes_256_gcm,  [], [aead_ng, aead_bad_tag]}
438    ].
439
440%%-------------------------------------------------------------------
441init_per_suite(Config) ->
442    file:set_cwd(datadir(Config)),
443    {ok, _} = zip:unzip("KAT_AES.zip"),
444    {ok, _} = zip:unzip("aesmmt.zip"),
445    {ok, _} = zip:unzip("cmactestvectors.zip"),
446    {ok, _} = zip:unzip("gcmtestvectors.zip"),
447
448    try is_ok(crypto:start()) of
449	ok ->
450            catch ct:comment("~s",[element(3,hd(crypto:info_lib()))]),
451            catch ct:log("crypto:info_lib() -> ~p~n"
452                         "crypto:supports() -> ~p~n"
453                         "crypto:version()  -> ~p~n"
454                        ,[crypto:info_lib(), crypto:supports(), crypto:version()]),
455
456	    try crypto:strong_rand_bytes(1) of
457		_ ->
458		    Config
459	    catch error:low_entropy ->
460                    %% We are testing on an OS with low entropy in its random
461                    %% seed. So we have to seed it with a binary to get started.
462
463		    %% This is NOT how you want to do seeding, it is just here
464		    %% to make the tests pass. Check your OS manual for how you
465		    %% really want to seed.
466		    {H,M,L} = erlang:timestamp(),
467		    Bin = <<H:24,M:20,L:20>>,
468		    crypto:rand_seed(<< <<Bin/binary>> || _ <- lists:seq(1,16) >>),
469		    Config
470	    end
471
472    catch C:E:S ->
473            ct:log("~p ~p~n~p", [C,E,S]),
474	    {fail, "Crypto did not start"}
475    end.
476
477is_ok(ok) -> ok;
478is_ok({error, already_started}) -> ok;
479is_ok({error,{already_started,crypto}}) -> ok.
480
481
482
483end_per_suite(_Config) ->
484    application:stop(crypto).
485
486%%-------------------------------------------------------------------
487init_per_group(fips, Config) ->
488    try_enable_fips_mode(Config);
489init_per_group(non_fips, Config) ->
490    NonFIPSConfig = [{fips, false} | Config],
491    case crypto:info_fips() of
492        enabled ->
493            true = crypto:enable_fips_mode(false),
494            not_enabled = crypto:info_fips(),
495            NonFIPSConfig;
496        _NotEnabled ->
497            NonFIPSConfig
498    end;
499init_per_group(api_errors, Config) ->
500    Config;
501init_per_group(GroupName, Config) ->
502    case atom_to_list(GroupName) of
503        "no_" ++ TypeStr ->
504            %% Negated test case: check the algorithm is not supported
505            %% (e.g. due to FIPS mode limitations)
506            TypeAtom = list_to_atom(TypeStr),
507            [{type, TypeAtom} | group_config(TypeAtom, Config)];
508        _Other ->
509            %% Regular test case: skip if the algorithm is not supported
510            case is_supported(GroupName) of
511                true ->
512                    [{type, GroupName} | group_config(GroupName, Config)];
513                false ->
514                    {skip, "Group not supported"}
515            end
516    end.
517
518end_per_group(_GroupName, Config) ->
519    Config.
520
521init_per_testcase(info, Config) ->
522    Config;
523init_per_testcase(cmac, Config) ->
524    case is_supported(cmac) of
525        true ->
526            configure_mac(cmac, proplists:get_value(type,Config), Config);
527        false ->
528            {skip, "CMAC is not supported"}
529    end;
530init_per_testcase(generate, Config) ->
531    case proplists:get_value(type, Config) of
532	rsa ->
533	    % RSA key generation is a lengthy process, and is only available
534	    % if dirty CPU scheduler support was enabled for this runtime.
535	    case try erlang:system_info(dirty_cpu_schedulers) of
536		     N -> N > 0
537		 catch
538		     error:badarg -> false
539		 end of
540		true -> Config;
541		false -> {skip, "RSA key generation requires dirty scheduler support."}
542	    end;
543	_ -> Config
544    end;
545init_per_testcase(hmac, Config) ->
546    configure_mac(hmac, proplists:get_value(type,Config), Config);
547init_per_testcase(_Name,Config) ->
548    Config.
549
550end_per_testcase(info, Config) ->
551    Config;
552end_per_testcase(_Name,Config) ->
553    Config.
554
555%%--------------------------------------------------------------------
556%% Test Cases --------------------------------------------------------
557%%--------------------------------------------------------------------
558app() ->
559    [{doc, "Test that the crypto app file is ok"}].
560app(Config) when is_list(Config) ->
561    ok = test_server:app_test(crypto).
562%%--------------------------------------------------------------------
563appup() ->
564    [{doc, "Test that the crypto appup file is ok"}].
565appup(Config) when is_list(Config) ->
566    ok = test_server:appup_test(crypto).
567
568%%--------------------------------------------------------------------
569%% Simple encode/decode for all ciphers in crypto:supports(ciphers). No
570%% checking of the encrypted text, just check that it is decrypted back
571%% to the plain text.
572all_ciphers(_Config) ->
573    case [C || C <- crypto:supports(ciphers),
574               ok =/= simple_cipher_test(C)] of
575        [] ->
576            ok;
577        BadCiphers ->
578            ct:log("Bad ciphers: ~p", [BadCiphers]),
579            {fail, "Cipher(s) failed"}
580    end.
581
582simple_cipher_test(Cipher) ->
583    try
584        #{key_length := KeyLength,
585          iv_length := IvLength,
586          block_size := BlockSize,
587          mode := CipherMode
588         } = crypto:cipher_info(Cipher),
589        Key = <<1:KeyLength/unit:8>>,
590        IV = <<0:IvLength/unit:8>>,
591        Plain0 = <<"Hello world! Let's do some cipher tests">>,
592        Plain = case BlockSize of
593                    1 -> Plain0;
594                    _ -> <<Plain0:BlockSize/binary>>
595                end,
596        enc_dec(Cipher, Key, IV, CipherMode, Plain)
597    catch
598        Class:Error:Stack ->
599            ct:log("Error for cipher ~p:~nClass = ~p~nError = ~p~nStack = ~p",
600                   [Cipher, Class, Error, Stack]),
601            error
602    end.
603
604
605
606enc_dec(Cipher, Key, 0, _Mode, Plain) ->
607    case crypto:crypto_one_time(Cipher, Key, Plain, true) of
608        Encrypted when is_binary(Encrypted) ->
609             case crypto:crypto_one_time(Cipher, Key, Encrypted, false) of
610                 Plain ->
611                     ok;
612                 Other ->
613                     ct:log("~p:~p Error for cipher ~p:~n~p", [?MODULE,?LINE,Cipher, Other]),
614                     error
615             end;
616        Other ->
617            ct:log("~p:~p Error for cipher ~p:~n~p", [?MODULE,?LINE,Cipher, Other]),
618            error
619    end;
620
621enc_dec(Cipher, Key, IV, Mode, Plain) when Mode == ccm_mode ;
622                                           Mode == gcm_mode ;
623                                           Cipher == chacha20_poly1305 ->
624    AAD = aad(Cipher, Mode),
625    case crypto:crypto_one_time_aead(Cipher, Key, IV, Plain, AAD, true) of
626        {Encrypted,Tag} when is_binary(Encrypted) ->
627            case crypto:crypto_one_time_aead(Cipher, Key, IV, Encrypted, AAD, Tag, false) of
628                 Plain ->
629                     ok;
630                 Other ->
631                     ct:log("~p:~p Error for cipher ~p:~n~p", [?MODULE,?LINE,Cipher, Other]),
632                     error
633             end;
634        Other ->
635            ct:log("~p:~p Error for cipher ~p:~n~p", [?MODULE,?LINE,Cipher, Other]),
636            error
637    end;
638
639enc_dec(Cipher, Key, IV, _Mode, Plain) ->
640    case crypto:crypto_one_time(Cipher, Key, IV, Plain, true) of
641        Encrypted when is_binary(Encrypted) ->
642             case crypto:crypto_one_time(Cipher, Key, IV, Encrypted, false) of
643                 Plain ->
644                     ok;
645                 Other ->
646                     ct:log("~p:~p Error for cipher ~p:~n~p", [?MODULE,?LINE,Cipher, Other]),
647                     error
648             end;
649        Other ->
650            ct:log("~p:~p Error for cipher ~p:~n~p", [?MODULE,?LINE,Cipher, Other]),
651            error
652    end.
653
654aad(_Cipher, _Mode) ->
655    %% Any size will do
656    <<"Some text">>.
657
658%%--------------------------------------------------------------------
659no_support() ->
660    [{doc, "Test an algorithm is not reported in the supported list"}].
661no_support(Config) when is_list(Config) ->
662    Type  = ?config(type, Config),
663    false = is_supported(Type).
664%%--------------------------------------------------------------------
665crypto_load(_Config) ->
666    (catch crypto:stop()),
667    code:delete(crypto),
668    code:purge(crypto),
669    crypto:start().
670%%--------------------------------------------------------------------
671crypto_load_and_call(_Config) ->
672    (catch crypto:stop()),
673    code:delete(crypto),
674    code:purge(crypto),
675    Key0 = "ablurf123BX#$;3",
676    Bin0 = erlang:md5(<<"whatever">>),
677    {Key,IVec,_BlockSize} = make_crypto_key(Key0),
678    crypto:crypto_one_time(des_ede3_cbc, Key, IVec, Bin0, true).
679
680make_crypto_key(String) ->
681    <<K1:8/binary,K2:8/binary>> = First = erlang:md5(String),
682    <<K3:8/binary,IVec:8/binary>> = erlang:md5([First|lists:reverse(String)]),
683    {[K1,K2,K3],IVec,8}.
684%%--------------------------------------------------------------------
685%% Test that a spawned node has initialized the cache
686-define(at_node,
687        (fun(N, M, F, As) ->
688                 R = rpc:call(N, M, F, As),
689                 ct:log("~p ~p ~p:~p(~s) = ~p", [?LINE,N,M,F,args2list(As), R]),
690                 R
691         end) ).
692args2list(As) -> lists:join(", ", [io_lib:format("~p",[A]) || A <- As]).
693
694node_supports_cache(_Config) ->
695    ECs = crypto:supports(curves),
696    {ok,Node} = start_slave_node(random_node_name(?MODULE)),
697    case ?at_node(Node, crypto, supports, [curves]) of
698        ECs ->
699            test_server:stop_node(Node);
700        OtherECs ->
701            ct:log("At master:~p~nAt slave:~p~n"
702                   "Missing at slave: ~p~nmissing at master: ~p",
703                   [ECs, OtherECs, ECs--OtherECs, OtherECs--ECs]),
704            {fail, "different support at slave"}
705    end.
706
707
708start_slave_node(Name) ->
709    Pa = filename:dirname(code:which(?MODULE)),
710    test_server:start_node(Name, slave, [{args, " -pa " ++ Pa}]).
711
712random_node_name(BaseName) ->
713    L = integer_to_list(erlang:unique_integer([positive])),
714    lists:concat([BaseName,"___",L]).
715
716%%--------------------------------------------------------------------
717hash() ->
718    [{doc, "Test all different hash functions"}].
719hash(Config) when is_list(Config) ->
720    {Type, MsgsLE, Digests} = proplists:get_value(hash, Config),
721    Msgs = lazy_eval(MsgsLE),
722    [LongMsg | _] = lists:reverse(Msgs),
723    Inc = iolistify(LongMsg),
724    [IncrDigest | _] = lists:reverse(Digests),
725    hash(Type, Msgs, Digests),
726    hash(Type, lists:map(fun iolistify/1, Msgs), Digests),
727    hash_increment(Type, Inc, IncrDigest).
728%%--------------------------------------------------------------------
729no_hash() ->
730    [{doc, "Test all disabled hash functions"}].
731no_hash(Config) when is_list(Config) ->
732    Type = ?config(type, Config),
733    notsup(fun crypto:hash/2, [Type, <<"Hi There">>]),
734    notsup(fun crypto:hash_init/1, [Type]).
735
736%%--------------------------------------------------------------------
737api_ng() ->
738     [{doc, "Test new api"}].
739
740api_ng(Config) when is_list(Config) ->
741    [_|_] = Ciphers = lazy_eval(proplists:get_value(cipher, Config, [])),
742    lists:foreach(fun api_ng_cipher_increment/1, Ciphers ++ spec_0_bytes(Config)).
743
744api_ng_cipher_increment({Type, Key, PlainTexts}=_X) ->
745    ct:log("~p",[_X]),
746    api_ng_cipher_increment({Type, Key, <<>>, PlainTexts});
747
748api_ng_cipher_increment({Type, Key, IV, PlainTexts}=_X) ->
749    ct:log("~p",[_X]),
750    api_ng_cipher_increment({Type, Key, IV, PlainTexts, undefined});
751
752api_ng_cipher_increment({Type, Key, IV, PlainText0, ExpectedEncText}=_X) ->
753    ct:log("~p",[_X]),
754    PlainTexts = iolistify(PlainText0),
755    RefEnc = crypto:crypto_init(Type, Key, IV, true),
756    RefDec = crypto:crypto_init(Type, Key, IV, false),
757    EncTexts = api_ng_cipher_increment_loop(RefEnc, PlainTexts),
758    EncFinal = crypto:crypto_final(RefEnc),
759    Enc = iolist_to_binary(EncTexts++[EncFinal]),
760    case ExpectedEncText of
761        undefined ->
762            ok;
763        Enc ->
764            ok;
765        _ ->
766            ct:log("encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainTexts}, ExpectedEncText, Enc]),
767            ct:fail("api_ng_cipher_increment (encode)",[])
768    end,
769    Plain = iolist_to_binary(PlainTexts),
770    DecTexts = api_ng_cipher_increment_loop(RefDec, EncTexts),
771    DecFinal =  crypto:crypto_final(RefDec),
772    case iolist_to_binary(DecTexts++[DecFinal]) of
773        Plain ->
774            ok;
775        OtherPT ->
776            ct:log("decode~nIn: ~p~nExpected: ~p~nDec: ~p~n", [{Type,Key,IV,EncTexts}, Plain, OtherPT]),
777            ct:fail("api_ng_cipher_increment (encode)",[])
778    end.
779
780
781api_ng_cipher_increment_loop(Ref, InTexts) ->
782    lists:map(fun(Txt) ->
783                      try crypto:crypto_update(Ref, Txt)
784                      of
785                          Bin when is_binary(Bin) ->
786                              Bin
787                      catch
788                          error:Error ->
789                              ct:log("Txt = ~p",[Txt]),
790                              ct:fail("~p",[Error])
791                      end
792              end, InTexts).
793
794%%--------------------------------------------------------------------
795%% Check that crypto do not core dump on early 0.9.8 cryptolibs
796spec_0_bytes(Config) ->
797    Type = proplists:get_value(type, Config),
798    #{iv_length := IVS, key_length := KS} = Spec = crypto:cipher_info(Type),
799    Key = <<0:KS/unit:8>>,
800    IV = <<0:IVS/unit:8>>,
801    spec_0_bytes(Type, Key, IV, Spec).
802
803
804spec_0_bytes(chacha20_poly1305, _, _, _) ->
805    [];
806spec_0_bytes(Type, Key, IV, #{mode := M}) when M == ccm_mode ;
807                                               M == gcm_mode ->
808    AAD = <<>>,
809    Plain = <<>>,
810    {_, Tag} = crypto:crypto_one_time_aead(Type, Key, IV, Plain, AAD, true),
811    [{Type, Key, Plain, IV, AAD, <<>>, Tag, []}];
812spec_0_bytes(Type, Key, IV, _Spec) ->
813    [{Type, Key, IV, <<>>, <<>>}].
814
815%%--------------------------------------------------------------------
816api_ng_one_shot() ->
817     [{doc, "Test new api"}].
818
819api_ng_one_shot(Config) when is_list(Config) ->
820    [_|_] = Ciphers = lazy_eval(proplists:get_value(cipher, Config, [])),
821    lists:foreach(fun do_api_ng_one_shot/1, Ciphers ++ spec_0_bytes(Config)).
822
823do_api_ng_one_shot({Type, Key, PlainTexts}=_X) ->
824    ct:log("~p",[_X]),
825    do_api_ng_one_shot({Type, Key, <<>>, PlainTexts});
826
827do_api_ng_one_shot({Type, Key, IV, PlainTexts}=_X) ->
828    ct:log("~p",[_X]),
829    do_api_ng_one_shot({Type, Key, IV, PlainTexts, undefined});
830
831do_api_ng_one_shot({Type, Key, IV, PlainText0, ExpectedEncText}=_X) ->
832    ct:log("~p",[_X]),
833    PlainText = iolist_to_binary(lazy_eval(PlainText0)),
834    EncTxt = crypto:crypto_one_time(Type, Key, IV, PlainText, true),
835    case ExpectedEncText of
836        undefined ->
837            ok;
838        EncTxt ->
839            ok;
840        _ ->
841            ct:log("encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainText}, ExpectedEncText, EncTxt]),
842            ct:fail("api_ng_one_time (encode)",[])
843    end,
844    case crypto:crypto_one_time(Type, Key, IV, EncTxt, false) of
845        PlainText ->
846            ok;
847        OtherPT ->
848            ct:log("decode~nIn: ~p~nExpected: ~p~nDec: ~p~n", [{Type,Key,IV,EncTxt}, PlainText, OtherPT]),
849            ct:fail("api_ng_one_time (decode)",[])
850    end.
851
852%%--------------------------------------------------------------------
853api_ng_tls() ->
854     [{doc, "Test special tls api"}].
855
856api_ng_tls(Config) when is_list(Config) ->
857    [_|_] = Ciphers = lazy_eval(proplists:get_value(cipher, Config, [])),
858    lists:foreach(fun do_api_ng_tls/1, Ciphers).
859
860
861do_api_ng_tls({Type, Key, PlainTexts}) ->
862    do_api_ng_tls({Type, Key, <<>>, PlainTexts});
863
864do_api_ng_tls({Type, Key, IV, PlainTexts}) ->
865    do_api_ng_tls({Type, Key, IV, PlainTexts, undefined});
866
867do_api_ng_tls({Type, Key, IV, PlainText0, ExpectedEncText}) ->
868    PlainText = iolist_to_binary(lazy_eval(PlainText0)),
869    ct:log("Type = ~p~nKey = ~p~nIV = ~p~nPlainText = ~p~nExpectedEncText = ~p",
870           [Type, Key, IV, PlainText, ExpectedEncText]),
871    Renc = crypto:crypto_dyn_iv_init(Type, Key, true),
872    Rdec = crypto:crypto_dyn_iv_init(Type, Key, false),
873    EncTxt = crypto:crypto_dyn_iv_update(Renc, PlainText, IV),
874    case ExpectedEncText of
875        undefined ->
876            ok;
877        EncTxt ->
878            %% Now check that the state is NOT updated:
879            case crypto:crypto_dyn_iv_update(Renc, PlainText, IV) of
880                EncTxt ->
881                    ok;
882                EncTxt2 ->
883                    ct:log("2nd encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainText}, EncTxt, EncTxt2]),
884                    ct:fail("api_ng_tls (second encode)",[])
885            end;
886        OtherEnc ->
887            ct:log("1st encode~nIn: ~p~nExpected: ~p~nEnc: ~p~n", [{Type,Key,IV,PlainText}, ExpectedEncText, OtherEnc]),
888            ct:fail("api_ng_tls (encode)",[])
889    end,
890    case crypto:crypto_dyn_iv_update(Rdec, EncTxt, IV) of
891        PlainText ->
892            %% Now check that the state is NOT updated:
893            case crypto:crypto_dyn_iv_update(Rdec, EncTxt, IV) of
894                PlainText ->
895                    ok;
896                PlainText2 ->
897                    ct:log("2nd decode~nIn: ~p~nExpected: ~p~nDec: ~p~n", [{Type,Key,IV,EncTxt}, PlainText, PlainText2]),
898                    ct:fail("api_ng_tls (second decode)",[])
899            end;
900        OtherPT ->
901            ct:log("1st decode~nIn: ~p~nExpected: ~p~nDec: ~p~n", [{Type,Key,IV,EncTxt}, PlainText, OtherPT]),
902            ct:fail("api_ng_tlst (decode)",[])
903    end.
904
905%%--------------------------------------------------------------------
906cipher_padding(_Config) ->
907    Ciphers = [{C,pkcs_padding}
908               || C <- crypto:supports(ciphers),
909                  C =/= chacha20_poly1305,
910                  case crypto:cipher_info(C) of
911                      #{mode := ccm_mode} -> false;
912                      #{mode := gcm_mode} -> false;
913                      _ -> true
914                  end],
915    lists:foreach(fun cipher_padding_test/1, Ciphers).
916
917cipher_padding_test({Cipher, Padding}) ->
918    #{block_size := Sblock,
919      iv_length  := Siv,
920      key_length := Skey} = Inf = crypto:cipher_info(Cipher),
921    ct:log("~p ~p", [Cipher,Inf]),
922
923    Key = <<1:Skey/unit:8>>,
924    IV  = <<0:Siv/unit:8>>,
925    MsgLen = 5*Sblock + 3,
926    Tplain = crypto:strong_rand_bytes(MsgLen),
927    PadSize = if
928                  (Padding == zero) ; (Padding == random) ->
929                      (Sblock - (MsgLen rem Sblock)) rem Sblock;
930                  true ->
931                      0
932              end,
933    Tcrypt =
934        case Siv of
935            0 ->
936                crypto:crypto_one_time(Cipher, Key, Tplain, [{encrypt,true},{padding,Padding}]);
937            _ ->
938                crypto:crypto_one_time(Cipher, Key, IV, Tplain, [{encrypt,true},{padding,Padding}])
939        end,
940
941    TdecryptPadded =
942        case Siv of
943            0 ->
944                crypto:crypto_one_time(Cipher, Key, Tcrypt, [{encrypt,false},{padding,Padding}]);
945            _ ->
946                crypto:crypto_one_time(Cipher, Key, IV, Tcrypt, [{encrypt,false},{padding,Padding}])
947        end,
948
949    case split_binary(TdecryptPadded, size(TdecryptPadded) - PadSize) of
950        {Tplain, _} ->
951            ok;
952        {Tdecrypt,Tpad} ->
953            ct:log("Key = ~p~nIV = ~p~nTplain = ~p~nTcrypt = ~p~nTdecrypt = ~p~nPadding = ~p",
954                   [Key, IV, Tplain, Tcrypt, Tdecrypt, Tpad]),
955            ct:fail("~p", [Cipher])
956    end.
957
958%%--------------------------------------------------------------------
959ec_key_padding(_Config) ->
960    lists:foreach(fun test_ec_key_padding/1,
961                  crypto:supports(curves) -- [ed25519, ed448, x25519, x448]
962                 ).
963
964test_ec_key_padding(CurveName) ->
965    ExpectedSize = expected_ec_size(CurveName),
966    repeat(100, % Enough to provoke an error in the 85 curves
967               % With for example 1000, the total test time would be too large
968           fun() ->
969                   case crypto:generate_key(ecdh, CurveName) of
970                       {_PubKey, PrivKey} when byte_size(PrivKey) == ExpectedSize ->
971                           %% ct:pal("~p:~p Test ~p, size ~p, expected size ~p",
972                           %%        [?MODULE,?LINE, CurveName, byte_size(PrivKey), ExpectedSize]),
973                           ok;
974                       {_PubKey, PrivKey} ->
975                           ct:fail("Bad ~p size: ~p expected: ~p", [CurveName, byte_size(PrivKey), ExpectedSize]);
976                       Other ->
977                           ct:pal("~p:~p ~p", [?MODULE,?LINE,Other]),
978                           ct:fail("Bad public_key:generate_key result for ~p", [CurveName])
979                   end
980           end).
981
982repeat(Times, F) when Times > 0 -> F(), repeat(Times-1, F);
983repeat(_, _) -> ok.
984
985expected_ec_size(CurveName) when is_atom(CurveName) ->
986    expected_ec_size(crypto_ec_curves:curve(CurveName));
987expected_ec_size({{prime_field,_}, _, _, Order, _}) -> byte_size(Order);
988expected_ec_size({{characteristic_two_field, _, _}, _, _, Order, _}) -> size(Order).
989
990%%--------------------------------------------------------------------
991no_aead() ->
992     [{doc, "Test disabled aead ciphers"}].
993no_aead(Config) when is_list(Config) ->
994    EncArg4 =
995        case lazy_eval(proplists:get_value(cipher, Config)) of
996            [{Type, Key, PlainText, Nonce, AAD, CipherText, CipherTag, TagLen, _Info} | _] ->
997                {AAD, PlainText, TagLen};
998            [{Type, Key, PlainText, Nonce, AAD, CipherText, CipherTag, _Info} | _] ->
999                {AAD, PlainText}
1000        end,
1001    EncryptArgs = [Type, Key, Nonce, EncArg4],
1002    DecryptArgs = [Type, Key, Nonce, {AAD, CipherText, CipherTag}],
1003    notsup(fun crypto:block_encrypt/4, EncryptArgs),
1004    notsup(fun crypto:block_decrypt/4, DecryptArgs).
1005
1006%%--------------------------------------------------------------------
1007no_aead_ng() ->
1008     [{doc, "Test disabled aead ciphers"}].
1009no_aead_ng(Config) when is_list(Config) ->
1010    {EncFun, EncryptArgs} =
1011        case lazy_eval(proplists:get_value(cipher, Config)) of
1012            [{Type, Key, PlainText, IV, AAD, CipherText, CipherTag, TagLen, _Info} | _] ->
1013                {fun crypto:crypto_one_time_aead/7, [Type, Key, IV, PlainText, AAD, TagLen, true]};
1014
1015            [{Type, Key, PlainText, IV, AAD, CipherText, CipherTag, _Info} | _] ->
1016                {fun crypto:crypto_one_time_aead/6, [Type, Key, IV, PlainText, AAD, true]}
1017        end,
1018    notsup(EncFun, EncryptArgs),
1019
1020    DecryptArgs = [Type, Key, IV, CipherText, AAD, CipherTag, false],
1021    notsup(fun crypto:crypto_one_time_aead/7, DecryptArgs).
1022
1023%%--------------------------------------------------------------------
1024aead_ng(Config) when is_list(Config) ->
1025    [_|_] = AEADs = lazy_eval(proplists:get_value(cipher, Config)),
1026    FilteredAEADs =
1027	case proplists:get_bool(fips, Config) of
1028	    false ->
1029		AEADs;
1030	    true ->
1031		%% In FIPS mode, the IV length must be at least 12 bytes.
1032		lists:filter(
1033		  fun(Tuple) ->
1034			  IVLen = byte_size(element(4, Tuple)),
1035			  IVLen >= 12
1036		  end, AEADs)
1037	end,
1038    do_cipher_tests(fun aead_cipher_ng/1, FilteredAEADs ++ spec_0_bytes(Config)).
1039
1040%%--------------------------------------------------------------------
1041aead_bad_tag(Config) ->
1042    [_|_] = AEADs = lazy_eval(proplists:get_value(cipher, Config)),
1043    FilteredAEADs =
1044	case proplists:get_bool(fips, Config) of
1045	    false ->
1046		AEADs;
1047	    true ->
1048		%% In FIPS mode, the IV length must be at least 12 bytes.
1049		lists:filter(
1050		  fun(Tuple) ->
1051			  IVLen = byte_size(element(4, Tuple)),
1052			  IVLen >= 12
1053		  end, AEADs)
1054	end,
1055    do_cipher_tests(fun aead_cipher_bad_tag/1, FilteredAEADs).
1056
1057%%--------------------------------------------------------------------
1058sign_verify() ->
1059     [{doc, "Sign/verify digital signatures"}].
1060sign_verify(Config) when is_list(Config) ->
1061    SignVerify = proplists:get_value(sign_verify, Config),
1062    lists:foreach(fun do_sign_verify/1, SignVerify).
1063
1064%%--------------------------------------------------------------------
1065no_sign_verify() ->
1066    [{doc, "Test disabled sign/verify digital signatures"}].
1067no_sign_verify(Config) when is_list(Config) ->
1068    [SignVerifyHd|_] = proplists:get_value(sign_verify, Config),
1069    notsup(fun do_sign_verify/1, [SignVerifyHd]).
1070
1071%%--------------------------------------------------------------------
1072public_encrypt() ->
1073     [{doc, "Test public_encrypt/decrypt "}].
1074public_encrypt(Config) when is_list(Config) ->
1075    ct:log("public_encrypt", []),
1076    Params = proplists:get_value(pub_pub_encrypt, Config, []),
1077    lists:foreach(fun do_public_encrypt/1, Params).
1078
1079%%--------------------------------------------------------------------
1080private_encrypt() ->
1081     [{doc, "Test private_encrypt/decrypt functions. "}].
1082private_encrypt(Config) when is_list(Config) ->
1083    Params = proplists:get_value(pub_priv_encrypt, Config, []),
1084    lists:foreach(fun do_private_encrypt/1, Params).
1085
1086%%--------------------------------------------------------------------
1087generate_compute() ->
1088     [{doc, " Test crypto:genarate_key and crypto:compute_key"}].
1089generate_compute(Config) when is_list(Config) ->
1090    GenCom = proplists:get_value(generate_compute, Config),
1091    lists:foreach(fun do_generate_compute/1, GenCom).
1092%%--------------------------------------------------------------------
1093compute_bug() ->
1094    [{doc, "Test that it works even if the Secret is smaller than expected"}].
1095compute_bug(_Config) ->
1096    ExpectedSecret = <<118,89,171,16,156,18,156,103,189,134,130,49,28,144,111,241,247,82,79,32,228,11,209,141,119,176,251,80,105,143,235,251,203,121,223,211,129,3,233,133,45,2,31,157,24,111,5,75,153,66,135,185,128,115,229,178,216,39,73,52,80,151,8,241,34,52,226,71,137,167,53,48,59,224,175,154,89,110,76,83,24,117,149,21,72,6,186,78,149,74,188,56,98,244,30,77,108,248,88,194,195,237,23,51,20,242,254,123,21,12,209,74,217,168,230,65,7,60,211,139,128,239,234,153,22,229,180,59,159,121,41,156,121,200,177,130,163,162,54,224,93,1,94,11,177,254,118,28,156,26,116,10,207,145,219,166,214,189,214,230,221,170,228,15,69,88,31,68,94,255,113,58,49,82,86,192,248,176,131,133,39,186,194,172,206,84,184,16,66,68,153,128,178,227,27,118,52,130,122,92,24,222,102,195,221,207,255,13,152,175,65,32,167,84,54,244,243,109,244,18,234,16,159,224,188,2,106,123,27,17,131,171,226,34,111,251,62,119,155,124,221,124,254,62,97,167,1,105,116,98,98,19,197,30,72,180,79,221,100,134,120,117,124,85,73,132,224,223,222,41,155,137,218,130,238,237,157,161,134,150,69,206,91,141,17,89,120,218,235,229,37,150,76,197,7,157,56,144,42,203,137,100,200,72,141,194,239,1,67,236,238,183,48,214,75,76,108,235,3,237,67,40,137,45,182,236,246,37,116,103,144,237,142,211,88,233,11,24,21,218,41,245,250,51,130,250,104,74,189,17,69,145,70,50,50,215,253,155,10,128,41,114,185,211,82,164,72,92,17,145,104,66,6,140,226,80,43,62,1,166,216,153,118,96,15,147,126,137,118,191,192,75,149,241,206,18,92,17,154,215,219,18,6,139,190,103,210,156,184,29,224,213,157,60,112,189,104,220,125,40,186,50,119,17,143,136,149,38,74,107,21,192,59,61,59,42,231,144,59,175,3,176,87,23,16,122,54,31,82,34,230,211,44,81,41,47,86,37,228,175,130,148,88,136,131,254,241,202,99,199,175,1,141,215,124,155,120,43,141,89,11,140,120,141,29,35,82,219,155,204,75,12,66,241,253,33,250,84,24,85,68,13,80,85,142,227,34,139,26,146,24>>,
1097    OthersPublicKey = 635619632099733175381667940709387641100492974601603060984753028943194386334921787463327680809776598322996634648015962954045728174069768874873236397421720142610982770302060309928552098274817978606093380781524199673890631795310930242601197479471368910519338301177304682162189801040921618559902948819107531088646753320486728060005223263561551402855338732899079439899705951063999951507319258050864346087428042978411873495523439615429804957374639092580169417598963105885529553632847023899713490485619763926900318508906706745060947269748612049634207985438016935262521715769812475329234748426647554362991758104620357149045960316987533503707855364806010494793980069245562784050236811004893018183726397041999426883788660276453352521120006817370050691205529335316794439089316232980047277245051173281601960196573681285904611182521967067911862467395705665888521948321299521549941618586026714676885890192323289343756440666276226084448279082483536164085883288884231665240707495770544705648564889889198060417915693315346959170105413290799314390963124178046425737828369059171472978294050322371452255088799865552038756937873388385970088906560408959959429398326288750834357514847891423941047433478384621074116184703014798814515161475596555032391555842,
1098    MyPrivateKey = 387759582879975726965038486537011291913744975764132199838375902680222019267527675651273586836110220500657652661706223760165097275862806031329642160439090779625708664007910974206651834216043397115514725827856461492311499129200688538220719685637154290305617686974719521885238198226075381217068175824097878445476010193039590876624464274744156624589136789060427283492343902761765833713520850870233407503430180028104167029073459918756981323130062648615262139444306321256382009848217866984408901761817655567071716275177768316006340055589170095799943481591033461616307776069027985761229636731465482676467627154100912586936231051371168178564599296638350391246393336702334311781595616786107810962134407697848002331639021101685320844880636050048769216986088652236979636019052557155807310341483407890060105599892252118584570558049301477535792498672552850760356632076013402382600669875697284264329434950712239302528367835155163504374877787288116104285944993818319105835423479332617802010952731990182088670508346704423006877514817882782443833997288652405892920173712497948376815825396272381214976859009518623799156300136570204539240675245115597412280078940442452936425561984312708387584800789375684525365060589104566195610526570099527133097201479,
1099    P = 818034524162384276004384029858643530286875094391273833506734966261806257117433972760379103507630310628953496150318170372254219924175532996281953750642804369831900894594960807970232131410638888573275563720690293481410915588408505771183615664441221559618326229227448328879290185035795866796496147000467456347856187771645103733376761936369144682074588463621004219054111244232031965820058057143484947957179035662640791007685559024477920075136419228662974090561346329074935312181886940693299380892129818458511403741106419480550004799657220331973244248753744516935739033770420884365608406478656143540532371463443324228730693491647103274058971797182813283112583029849186056551355376851686616057869624968077484471229044125401535456699914745876082047459812392122562460031611344154642406382436701361983114768023990405077450124649862159757605118611426368650203370143674925598905779061402007525955196464201496773278952462368223659263492419274489020447849336502432222101793313731259141617677580646998184158969477474527427664187763741360356528830301163614618231141541403007931347398186427059736520580903587497382362610721261644208653717495736748724114113311672504064943864203789205551568648546606356374830209356446449765364678719909024329058480379,
1100    G = 2,
1101    DHParameters = [P, G],
1102    case crypto:compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) of
1103        ExpectedSecret ->
1104            ok;
1105        Others ->
1106            ct:log("Got ~p",[Others]),
1107            {fail, "crypto:compute_key(dh,...) failed for the bug test"}
1108    end.
1109
1110%%--------------------------------------------------------------------
1111no_generate_compute() ->
1112     [{doc, "Test crypto:genarate_key and crypto:compute_key "
1113       "for disabled algorithms"}].
1114no_generate_compute(Config) when is_list(Config) ->
1115    %% This test is specific to the SRP protocol
1116    srp = ?config(type, Config),
1117    {srp,
1118     UserPrivate, UserGenParams, UserComParams,
1119     HostPublic, HostPrivate, HostGenParams, HostComParams,
1120     _SessionKey} = srp3(),
1121    UserPublic = HostPublic,                    % use a fake public key
1122    notsup(fun crypto:generate_key/3, [srp, UserGenParams, UserPrivate]),
1123    notsup(fun crypto:generate_key/3, [srp, HostGenParams, HostPrivate]),
1124    notsup(fun crypto:compute_key/4,
1125           [srp, HostPublic, {UserPublic, UserPrivate}, UserComParams]),
1126    notsup(fun crypto:compute_key/4,
1127           [srp, UserPublic, {HostPublic, HostPrivate}, HostComParams]).
1128%%--------------------------------------------------------------------
1129compute() ->
1130     [{doc, " Test crypto:compute_key"}].
1131compute(Config) when is_list(Config) ->
1132    Gen = proplists:get_value(compute, Config),
1133    lists:foreach(fun do_compute/1, Gen).
1134%%--------------------------------------------------------------------
1135use_all_ec_sign_verify(_Config) ->
1136    Msg = <<"hello world!">>,
1137    Sups = crypto:supports(),
1138    Curves = proplists:get_value(curves, Sups),
1139    Hashs = proplists:get_value(hashs, Sups),
1140    ct:log("Lib: ~p~nFIPS: ~p~nCurves:~n~p~nHashs: ~p", [crypto:info_lib(),
1141                                                         crypto:info_fips(),
1142                                                         Curves,
1143                                                         Hashs]),
1144    Results =
1145        [{{Curve,Hash},
1146          try
1147              ct:log("~p ~p",[Curve,Hash]),
1148              {Pub,Priv} = crypto:generate_key(ecdh, Curve),
1149              true = is_binary(Pub),
1150              true = is_binary(Priv),
1151              Sig = crypto:sign(ecdsa, Hash, Msg, [Priv, Curve]),
1152              crypto:verify(ecdsa, Hash, Msg, Sig, [Pub, Curve])
1153          catch
1154              C:E ->
1155                  {C,E}
1156          end}
1157         || Curve <- Curves -- [ed25519, ed448, x25519, x448, ipsec3, ipsec4],
1158            Hash <- Hashs -- [md4, md5, ripemd160, sha3_224, sha3_256, sha3_384, sha3_512, blake2b, blake2s]
1159        ],
1160    Fails =
1161        lists:filter(fun({_,true}) -> false;
1162                        (_) -> true
1163                     end, Results),
1164    case Fails of
1165        [] ->
1166            ok;
1167        _ ->
1168            ct:log("Fails:~n~p",[Fails]),
1169            ct:fail("Bad curve(s)",[])
1170    end.
1171
1172%%--------------------------------------------------------------------
1173use_all_ecdh_generate_compute(Config) ->
1174    Curves = crypto:supports(curves) -- [ed25519, ed448, x25519, x448],
1175    do_dh_curves(Config, Curves).
1176
1177use_all_eddh_generate_compute(Config) ->
1178    AllCurves = crypto:supports(curves),
1179    Curves = [C || C <- [x25519, x448],
1180                     lists:member(C, AllCurves)],
1181    do_dh_curves(Config, Curves).
1182
1183do_dh_curves(_Config, Curves) ->
1184    ct:log("Lib: ~p~nFIPS: ~p~nCurves:~n~p~n", [crypto:info_lib(),
1185                                                crypto:info_fips(),
1186                                                Curves]),
1187    Results =
1188        [{Curve,
1189          try
1190              ct:log("~p",[Curve]),
1191              {APub,APriv} = crypto:generate_key(ecdh, Curve),
1192              {BPub,BPriv} = crypto:generate_key(ecdh, Curve),
1193              true = is_binary(APub),
1194              true = is_binary(APriv),
1195              true = is_binary(BPub),
1196              true = is_binary(BPriv),
1197
1198              ACommonSecret = crypto:compute_key(ecdh, BPub, APriv, Curve),
1199              BCommonSecret = crypto:compute_key(ecdh, APub, BPriv, Curve),
1200              ACommonSecret == BCommonSecret
1201          catch
1202              C:E ->
1203                  {C,E}
1204          end}
1205         || Curve <- Curves
1206        ],
1207
1208    Fails =
1209        lists:filter(fun({_,true}) -> false;
1210                        (_) -> true
1211                     end, Results),
1212
1213    case Fails of
1214        [] ->
1215            ct:comment("All ~p passed",[length(Results)]),
1216            ok;
1217        _ ->
1218            ct:comment("passed: ~p, failed: ~p",[length(Results),length(Fails)]),
1219            ct:log("Fails:~n~p",[Fails]),
1220            ct:fail("Bad curve(s)",[])
1221    end.
1222
1223%%--------------------------------------------------------------------
1224generate() ->
1225     [{doc, " Test crypto:generate_key"}].
1226generate(Config) when is_list(Config) ->
1227    Gen = proplists:get_value(generate, Config),
1228    lists:foreach(fun do_generate/1, Gen).
1229%%--------------------------------------------------------------------
1230mod_pow() ->
1231    [{doc, "mod_pow testing (A ^ M % P with bignums)"}].
1232mod_pow(Config) when is_list(Config) ->
1233    mod_pow_aux_test(2, 5, 10, 8).
1234%%--------------------------------------------------------------------
1235exor() ->
1236    [{doc, "Test the exor function"}].
1237exor(Config) when is_list(Config) ->
1238    do_exor(<<1, 2, 3, 4, 5, 6, 7, 8, 9, 10>>),
1239    do_exor(term_to_binary(lists:seq(1, 1000000))).
1240%%--------------------------------------------------------------------
1241rand_uniform() ->
1242    [{doc, "rand_uniform and random_bytes testing"}].
1243rand_uniform(Config) when is_list(Config) ->
1244    rand_uniform_aux_test(10),
1245    10 = byte_size(crypto:strong_rand_bytes(10)).
1246
1247%%--------------------------------------------------------------------
1248rand_threads() ->
1249    [{doc, "strong_rand_bytes in parallel threads"}].
1250rand_threads(Config) when is_list(Config) ->
1251    %% This will crash the emulator on at least one version of libcrypto
1252    %% with buggy multithreading in RAND_bytes().
1253    %% The test needs to run at least a few minutes...
1254    NofThreads = 4,
1255    Fun = fun F() -> crypto:strong_rand_bytes(16), F() end,
1256    PidRefs = [spawn_monitor(Fun) || _ <- lists:seq(1, NofThreads)],
1257%%% The test case takes too much time to run.
1258%%% Keep it around for reference by setting it down to just 10 seconds.
1259%%%    receive after 10 * 60 * 1000 -> ok end, % 10 minutes
1260    receive after 10 * 1000 -> ok end, % 10 seconds
1261    spawn_link(fun () -> receive after 5000 -> exit(timeout) end end),
1262    [exit(Pid, stop) || {Pid,_Ref} <- PidRefs],
1263    [receive {'DOWN',Ref,_,_,stop} -> ok end || {_Pid,Ref} <- PidRefs],
1264    ok.
1265
1266%%--------------------------------------------------------------------
1267rand_plugin() ->
1268    [{doc, "crypto rand plugin testing (implicit state / process dictionary)"}].
1269rand_plugin(Config) when is_list(Config) ->
1270    rand_plugin_aux(implicit_state).
1271
1272rand_plugin_s() ->
1273    [{doc, "crypto rand plugin testing (explicit state)"}].
1274rand_plugin_s(Config) when is_list(Config) ->
1275    rand_plugin_aux(explicit_state).
1276
1277%%--------------------------------------------------------------------
1278info(_Config) ->
1279    [{_,_,VerBin}] = crypto:info_lib(),
1280    Ver = binary:bin_to_list(VerBin),
1281    try
1282        crypto:info()
1283    of
1284        #{cryptolib_version_compiled := Ver,
1285          cryptolib_version_linked := Ver,
1286          compile_type := Tc,
1287          link_type := Tl} when is_atom(Tc), is_atom(Tl) ->
1288            ok;
1289        Other ->
1290            ct:log("Ver = ~p~ncrypto:info() -> ~p", [Ver,Other]),
1291            ct:fail("Version missmatch", [])
1292    catch
1293        C:E ->
1294            ct:log("Exception ~p:~p", [C,E]),
1295            ct:fail("Exception when calling crypto:info/0", [])
1296    end.
1297
1298%%--------------------------------------------------------------------
1299cipher_info() ->
1300    [{doc, "crypto cipher_info testing"}].
1301cipher_info(Config) when is_list(Config) ->
1302    #{type := _,key_length := _,iv_length := _,
1303        block_size := _,mode := _} = crypto:cipher_info(aes_128_cbc),
1304    {'EXIT',_} = (catch crypto:cipher_info(not_a_cipher)),
1305    case lists:foldl(fun(C,Ok) ->
1306                             try crypto:cipher_info(C)
1307                             of
1308                                 _ -> Ok
1309                             catch Cls:Exc ->
1310                                     ct:log("~p:~p ~p",[Cls,Exc,C]),
1311                                     false
1312                             end
1313                     end,
1314                     true,
1315                     crypto:supports(ciphers)
1316                    )
1317    of
1318        true ->
1319            ok;
1320        false ->
1321            ct:fail('Cipher unsupported',[])
1322    end.
1323
1324cipher_info_prop_aead_attr() ->
1325    [{doc, "crypto cipher_info prop_aead attribute testing"}].
1326cipher_info_prop_aead_attr(Config) when is_list(Config) ->
1327    AeadCiphers = [aes_128_ccm, aes_192_ccm, aes_256_ccm, aes_128_gcm, aes_192_gcm, aes_256_gcm, chacha20_poly1305],
1328    case lists:foldl(fun(C,Ok) ->
1329                        case crypto:cipher_info(C) of
1330                            #{prop_aead := true} ->
1331                                true and Ok;
1332                            _ ->
1333                                false
1334                        end
1335                     end,
1336                     true,
1337                     AeadCiphers
1338                    )
1339    of
1340        true ->
1341            ok;
1342        false ->
1343            ct:fail('AEAD Cipher attribute reported false',[])
1344    end,
1345    NonAeadCiphers = [aes_ige256, blowfish_cbc, blowfish_cfb64],
1346    case lists:foldl(fun(C,Ok) ->
1347                        case crypto:cipher_info(C) of
1348                            #{prop_aead := false} ->
1349                                true and Ok;
1350                            _ ->
1351                                false
1352                        end
1353                     end,
1354                     true,
1355                     NonAeadCiphers
1356                    )
1357    of
1358        true ->
1359            ok;
1360        false ->
1361            ct:fail('Non-AEAD Cipher attribute reported true',[])
1362    end.
1363
1364%%--------------------------------------------------------------------
1365hash_info() ->
1366    [{doc, "crypto hash_info testing"}].
1367hash_info(Config) when is_list(Config) ->
1368    #{type := _,size := _,block_size := _} = crypto:hash_info(sha256),
1369    {'EXIT',_} = (catch crypto:hash_info(not_a_hash)),
1370    lists:foreach(fun(H) -> crypto:hash_info(H) end,
1371        proplists:get_value(hashs, crypto:supports())).
1372
1373%%--------------------------------------------------------------------
1374%% Internal functions ------------------------------------------------
1375%%--------------------------------------------------------------------
1376hash(_, [], []) ->
1377    ok;
1378hash(Type, [Msg | RestMsg], [Digest| RestDigest]) ->
1379    case crypto:hash(Type, Msg) of
1380	Digest ->
1381	    hash(Type, RestMsg, RestDigest);
1382	Other ->
1383	    ct:fail({{crypto, hash, [Type, Msg]}, {expected, Digest}, {got, Other}})
1384    end.
1385
1386hash_increment(Type, Increments, Digest) ->
1387    State = crypto:hash_init(Type),
1388    case hash_increment(State, Increments) of
1389	Digest ->
1390	    ok;
1391	Other ->
1392	    ct:fail({{crypto, "hash_init/update/final", [Type, Increments]}, {expected, Digest}, {got, Other}})
1393    end.
1394
1395hash_increment(State, []) ->
1396    crypto:hash_final(State);
1397hash_increment(State0, [Increment | Rest]) ->
1398    State = crypto:hash_update(State0, Increment),
1399    hash_increment(State, Rest).
1400
1401%%%----------------------------------------------------------------
1402mac_check({MacType, SubType, Key, Text, Mac}=T) ->
1403    ExpMac = iolist_to_binary(Mac),
1404    cipher_test(T,
1405                fun() -> crypto:mac(MacType, SubType, Key, Text) end,
1406                ExpMac);
1407mac_check({MacType, SubType, Key, Text, Size, Mac}=T) ->
1408    ExpMac = iolist_to_binary(Mac),
1409    cipher_test(T,
1410                fun() -> crypto:mac(MacType, SubType, Key, Text, Size) end,
1411                ExpMac).
1412
1413aead_cipher_ng({Type, Key, PlainText, IV, AAD, CipherText, CipherTag, _Info}=T) ->
1414    Plain = iolist_to_binary(PlainText),
1415    cipher_test(T,
1416                fun() -> crypto:crypto_one_time_aead(Type, Key, IV, PlainText, AAD, true) end,
1417                {CipherText, CipherTag},
1418                fun() -> crypto:crypto_one_time_aead(Type, Key, IV, CipherText, AAD, CipherTag, false) end,
1419                Plain);
1420aead_cipher_ng({Type, Key, PlainText, IV, AAD, CipherText, CipherTag, TagLen, _Info}=T) ->
1421    <<TruncatedCipherTag:TagLen/binary, _/binary>> = CipherTag,
1422    Plain = iolist_to_binary(PlainText),
1423    cipher_test(T,
1424                fun() -> crypto:crypto_one_time_aead(Type, Key, IV, PlainText, AAD, TagLen, true) end,
1425                {CipherText, TruncatedCipherTag},
1426                fun() -> crypto:crypto_one_time_aead(Type, Key, IV, CipherText, AAD, TruncatedCipherTag, false) end,
1427                Plain).
1428
1429aead_cipher_bad_tag({Type, Key, _PlainText, IV, AAD, CipherText, CipherTag, _Info}=T) ->
1430    BadTag = mk_bad_tag(CipherTag),
1431    cipher_test(T,
1432                fun() -> crypto:crypto_one_time_aead(Type, Key, IV, CipherText, AAD, BadTag, false) end,
1433                error);
1434aead_cipher_bad_tag({Type, Key, _PlainText, IV, AAD, CipherText, CipherTag, TagLen, _Info}=T) ->
1435    <<TruncatedCipherTag:TagLen/binary, _/binary>> = CipherTag,
1436    BadTruncatedTag = mk_bad_tag(TruncatedCipherTag),
1437    cipher_test(T,
1438                fun() -> crypto:crypto_one_time_aead(Type, Key, IV, CipherText, AAD, BadTruncatedTag, false) end,
1439                error).
1440
1441
1442cipher_test(T, Fe, Ee, Fd, Ed) ->
1443    %% Test encrypt
1444    Re = cipher_test(encrypt, T, Fe, Ee),
1445    %% Test decrypt
1446    Rd = cipher_test(decrypt, T, Fd, Ed),
1447    case {Re, Rd} of
1448        {ok,ok} -> ok;
1449        {ok,_} -> Rd;
1450        {_,ok} -> Re;
1451        _ -> {Re,Rd}
1452    end.
1453
1454cipher_test(T, F, E) ->
1455    cipher_test(notag, T, F, E).
1456
1457cipher_test(Tag, T, F, E) ->
1458    try F() of
1459        E -> ok;
1460        Other -> {other, {Tag,T,Other}}
1461    catch
1462        error:Error -> {error, {Tag,T,Error}}
1463    end.
1464
1465do_cipher_tests(F, TestVectors) when is_function(F,1) ->
1466    {Passed,Failed} =
1467        lists:partition(
1468          fun(R) -> R == ok end,
1469          lists:map(F, TestVectors)
1470         ),
1471    BothFailed = lists:filter(fun({ok,_}) -> false;
1472                                 ({_,ok}) -> false;
1473                                 (ok) -> false;
1474                                 (_) -> true
1475                              end,
1476                              Failed),
1477    ct:log("Passed: ~p, BothFailed: ~p OnlyOneFailed: ~p",
1478           [length(Passed), length(BothFailed), length(Failed)-length(BothFailed)]),
1479    case Failed of
1480        [] ->
1481            ct:comment("All ~p passed", [length(Passed)]);
1482        _ ->
1483            ct:log("~p",[hd(Failed)]),
1484            ct:comment("Passed: ~p, BothFailed: ~p OnlyOneFailed: ~p",
1485                       [length(Passed), length(BothFailed), length(Failed)-length(BothFailed)]),
1486            ct:fail("Failed", [])
1487    end.
1488
1489
1490mk_bad_tag(CipherTag) ->
1491    case <<0:(size(CipherTag))/unit:8>> of
1492        CipherTag -> % The correct tag may happen to be a suite of zeroes
1493            <<1:(size(CipherTag))/unit:8>>;
1494        X ->
1495            X
1496    end.
1497
1498do_sign_verify({Type, undefined=Hash, Private, Public, Msg, Signature}) ->
1499    case crypto:sign(eddsa, Hash, Msg, [Private,Type]) of
1500        Signature ->
1501            ct:log("OK crypto:sign(eddsa, ~p, Msg, [Private,~p])", [Hash,Type]),
1502            case crypto:verify(eddsa, Hash, Msg, Signature, [Public,Type]) of
1503                true ->
1504                    ct:log("OK crypto:verify(eddsa, ~p, Msg, Signature, [Public,~p])", [Hash,Type]),
1505                    negative_verify(eddsa, Hash, Msg, <<10,20>>, [Public,Type]);
1506                false ->
1507                    ct:log("ERROR crypto:verify(eddsa, ~p, Msg= ~p, Signature= ~p, [Public= ~p,~p])",
1508                           [Hash,Msg,Signature,Public,Type]),
1509                    ct:fail({{crypto, verify, [eddsa, Hash, Msg, Signature, [Public,Type]]}})
1510            end;
1511        ErrorSig ->
1512            ct:log("ERROR crypto:sign(~p, ~p, ..., [Private= ~p,~p])", [eddsa,Hash,Private,Type]),
1513            ct:log("ERROR crypto:verify(eddsa, ~p, Msg= ~p, [Public= ~p,~p])~n"
1514                   "ErrorSig   = ~p~n"
1515                   "CorrectSig = ~p~n"
1516                  ,
1517                   [Hash,Msg,Public,Type,ErrorSig,Signature]),
1518            ct:fail({{crypto, sign, [Type, Hash, Msg, ErrorSig, [Private]]}})
1519    end;
1520
1521do_sign_verify({Type, Hash, Public, Private, Msg}) ->
1522    Signature = crypto:sign(Type, Hash, Msg, Private),
1523    case crypto:verify(Type, Hash, Msg, Signature, Public) of
1524	true ->
1525            ct:log("OK crypto:sign(~p, ~p, ..., ..., ...)", [Type,Hash]),
1526	    negative_verify(Type, Hash, Msg, <<10,20>>, Public);
1527	false ->
1528            ct:log("ERROR crypto:sign(~p, ~p, ..., ..., ...)", [Type,Hash]),
1529	    ct:fail({{crypto, verify, [Type, Hash, Msg, Signature, Public]}})
1530    end;
1531do_sign_verify({Type, Hash, Public, Private, Msg, Options}) ->
1532    LibVer =
1533        case crypto:info_lib() of
1534            [{<<"OpenSSL">>,Ver,<<"OpenSSL",_/binary>>}] -> Ver;
1535            _ -> infinity
1536        end,
1537    Pad = proplists:get_value(rsa_padding, Options),
1538    NotSupLow = lists:member(Pad, [rsa_pkcs1_pss_padding]),
1539    try
1540        crypto:sign(Type, Hash, Msg, Private, Options)
1541    of
1542        Signature ->
1543            case crypto:verify(Type, Hash, Msg, Signature, Public, Options) of
1544                true ->
1545                    ct:log("OK crypto:sign(~p, ~p, ..., ..., ..., ~p)", [Type,Hash,Options]),
1546                    negative_verify(Type, Hash, Msg, <<10,20>>, Public, Options);
1547                false ->
1548                    ct:log("ERROR crypto:sign(~p, ~p, ..., ..., ..., ~p)", [Type,Hash,Options]),
1549                    ct:fail({{crypto, verify, [Type, Hash, Msg, Signature, Public, Options]}})
1550            end
1551    catch
1552        error:notsup when NotSupLow == true,
1553                          is_integer(LibVer),
1554                          LibVer < 16#10001000 ->
1555            %% Those opts where introduced in 1.0.1
1556            ct:log("notsup but OK in old cryptolib crypto:sign(~p, ~p, ..., ..., ..., ~p)",
1557                   [Type,Hash,Options]),
1558            true;
1559        C:E ->
1560            ct:log("~p:~p  crypto:sign(~p, ~p, ..., ..., ..., ~p)", [C,E,Type,Hash,Options]),
1561            ct:fail({{crypto, sign_verify, [LibVer, Type, Hash, Msg, Public, Options]}})
1562    end.
1563
1564negative_verify(Type, Hash, Msg, Signature, Public) ->
1565    case crypto:verify(Type, Hash, Msg, Signature, Public) of
1566	true ->
1567	    ct:fail({{crypto, verify, [Type, Hash, Msg, Signature, Public]}, should_fail});
1568	false ->
1569	    ok
1570    end.
1571
1572negative_verify(Type, Hash, Msg, Signature, Public, Options) ->
1573    case crypto:verify(Type, Hash, Msg, Signature, Public, Options) of
1574	true ->
1575	    ct:fail({{crypto, verify, [Type, Hash, Msg, Signature, Public, Options]}, should_fail});
1576	false ->
1577	    ok
1578    end.
1579
1580do_public_encrypt({Type, Public, Private, Msg, Padding}) ->
1581    ct:log("do_public_encrypt Type=~p, Padding=~p,~nPublic = ~p,~nPrivate = ~p,~nMsg = ~p.",
1582           [Type, Padding, Public, Private, Msg]),
1583    timer:sleep(100),
1584    try
1585        crypto:public_encrypt(Type, Msg, Public, Padding)
1586    of
1587        PublicEcn ->
1588            ct:log("private_decrypt~nPublicEcn = ~p.", [PublicEcn]),
1589            timer:sleep(100),
1590            try
1591                crypto:private_decrypt(Type, PublicEcn, Private, Padding)
1592            of
1593                Msg ->
1594                    ct:log("~p:~p ok", [?MODULE,?LINE]),
1595                    timer:sleep(100),
1596                    ok;
1597                Other ->
1598                    ct:log("~p:~p Other = ~p", [?MODULE,?LINE,Other]),
1599                    timer:sleep(100),
1600                    ct:fail({{crypto, private_decrypt, [Type, PublicEcn, Private, Padding]}, {expected, Msg}, {got, Other}})
1601            catch
1602                CC:EE ->
1603                    ct:log("~p:~p EXC. ~p:~p", [?MODULE,?LINE,CC,EE]),
1604                    timer:sleep(100),
1605                    ct:fail({{crypto, private_decrypt, [Type, PublicEcn, Private, Padding]}, {expected, Msg}, {got, {CC,EE}}})
1606            end
1607    catch
1608        CC:EE ->
1609            ct:log("~p:~p EXC 2. ~p:~p", [?MODULE,?LINE,CC,EE]),
1610            timer:sleep(100),
1611            ct:fail({{crypto, public_encrypt, [Type, Msg, Public, Padding]}, {got, {CC,EE}}})
1612    end.
1613
1614
1615do_private_encrypt({Type, Public, Private, Msg, Padding}) ->
1616    ct:log("do_private_encrypt Type=~p, Padding=~p,~nPublic = ~p,~nPrivate = ~p,~nMsg = ~p.",
1617           [Type, Padding, Public, Private, Msg]),
1618    try
1619        crypto:private_encrypt(Type, Msg, Private, Padding)
1620    of
1621        PrivEcn ->
1622            try
1623                ct:log("public_decrypt~nPrivEcn = ~p.", [PrivEcn]),
1624                crypto:public_decrypt(Type, PrivEcn, Public, Padding)
1625            of
1626                Msg ->
1627                    ct:log("~p:~p ok", [?MODULE,?LINE]),
1628                    ok;
1629                Other ->
1630                    ct:log("~p:~p Other = ~p", [?MODULE,?LINE,Other]),
1631                    ct:fail({{crypto, public_decrypt, [Type, PrivEcn, Public, Padding]}, {expected, Msg}, {got, Other}})
1632            catch
1633                CC:EE ->
1634                    ct:log("~p:~p EXC. ~p:~p", [?MODULE,?LINE,CC,EE]),
1635                    ct:fail({{crypto, public_decrypt, [Type, PrivEcn, Public, Padding]}, {expected, Msg}, {got, {CC,EE}}})
1636            end
1637    catch
1638        CC:EE ->
1639            ct:log("~p:~p EXC 2. ~p:~p", [?MODULE,?LINE,CC,EE]),
1640            ct:fail({{crypto, private_encrypt, [Type, Msg, Private, Padding]}, {got, {CC,EE}}})
1641    end.
1642
1643do_generate_compute({srp = Type, UserPrivate, UserGenParams, UserComParams,
1644		     HostPublic, HostPrivate, HostGenParams, HostComParam, SessionKey}) ->
1645    {UserPublic, UserPrivate} = crypto:generate_key(Type, UserGenParams, UserPrivate),
1646    {HostPublic, HostPrivate} = crypto:generate_key(Type, HostGenParams, HostPrivate),
1647    SessionKey = crypto:compute_key(Type, HostPublic, {UserPublic, UserPrivate},
1648     				    UserComParams),
1649    SessionKey = crypto:compute_key(Type, UserPublic, {HostPublic, HostPrivate},
1650				    HostComParam);
1651
1652
1653
1654do_generate_compute({dh, P, G}) ->
1655    {UserPub, UserPriv} = crypto:generate_key(dh, [P, G]),
1656    {HostPub, HostPriv} = crypto:generate_key(dh, [P, G]),
1657    SharedSecret = crypto:compute_key(dh, HostPub, UserPriv, [P, G]),
1658    SharedSecret = crypto:compute_key(dh, UserPub, HostPriv, [P, G]).
1659
1660do_compute({ecdh = Type, Pub, Priv, Curve, SharedSecret}) ->
1661    ct:log("~p ~p", [Type,Curve]),
1662    Secret = crypto:compute_key(Type, Pub, Priv, Curve),
1663     case Secret of
1664	 SharedSecret ->
1665	     ok;
1666	 Other ->
1667	     ct:fail({{crypto, compute_key, [Type, Pub, Priv, Curve]}, {expected, SharedSecret}, {got, Other}})
1668     end.
1669
1670do_generate({Type, Curve, Priv, Pub}) when Type == ecdh ; Type == eddsa ->
1671    ct:log("~p ~p", [Type,Curve]),
1672    case crypto:generate_key(Type, Curve, Priv) of
1673	{Pub, _} ->
1674	    ok;
1675	{Other, _} ->
1676	    ct:fail({{crypto, generate_key, [Type, Priv, Curve]}, {expected, Pub}, {got, Other}})
1677    end;
1678do_generate({rsa = Type, Mod, Exp}) ->
1679    ct:log("~p", [Type]),
1680    case crypto:info_fips() of
1681        enabled when Mod < 3072 ->
1682            ct:log("SKIP do_generate ~p FIPS=~p, Mod=~p  Exp=~p", [Type, enabled, Mod, Exp]),
1683            {skip, "FIPS violation"};
1684        FIPS ->
1685            ct:log("do_generate ~p FIPS=~p, Mod=~p  Exp=~p", [Type, FIPS, Mod, Exp]),
1686            {Pub,Priv} = crypto:generate_key(Type, {Mod,Exp}),
1687            do_sign_verify({rsa, sha256, Pub, Priv, rsa_plain()})
1688    end.
1689
1690notsup(Fun, Args) ->
1691    Result =
1692        try
1693            {error, {return, apply(Fun, Args)}}
1694        catch
1695            error:notsup ->
1696                ok;
1697            error: {notsup, _, _} ->
1698                ok;
1699            Class:Error ->
1700                {error, {Class, Error}}
1701        end,
1702    case Result of
1703        ok ->
1704            ok;
1705        {error, Value} ->
1706            {module, Module} = erlang:fun_info(Fun, module),
1707            {name,   Name}   = erlang:fun_info(Fun, name),
1708            ct:fail({{Module, Name, Args}, {expected, {error, notsup}}, {got, Value}})
1709    end.
1710
1711hexstr2point(X, Y) ->
1712    <<4:8, (hexstr2bin(X))/binary, (hexstr2bin(Y))/binary>>.
1713
1714hexstr2bin(S) when is_binary(S) ->
1715    list_to_binary(hexstr2list(binary_to_list(S)));
1716hexstr2bin(S) ->
1717    list_to_binary(hexstr2list(S)).
1718
1719hexstr2list([$ |T]) ->
1720    hexstr2list(T);
1721hexstr2list([X,Y|T]) ->
1722    [mkint(X)*16 + mkint(Y) | hexstr2list(T)];
1723hexstr2list([]) ->
1724    [].
1725mkint(C) when $0 =< C, C =< $9 ->
1726    C - $0;
1727mkint(C) when $A =< C, C =< $F ->
1728    C - $A + 10;
1729mkint(C) when $a =< C, C =< $f ->
1730    C - $a + 10.
1731
1732decstr2int(S) when is_binary(S) ->
1733    list_to_integer(binary:bin_to_list(S));
1734decstr2int(S) ->
1735    list_to_integer(S).
1736
1737is_supported(Group) ->
1738    lists:member(Group, lists:append([Algo ||  {_, Algo}  <- crypto:supports()])).
1739
1740iolistify(X) ->
1741    iolistify1(lazy_eval(X)).
1742
1743iolistify1(<<"Test With Truncation">>)->
1744    %% Do not iolistify as it spoils this special case
1745    <<"Test With Truncation">>;
1746iolistify1(Msg) when is_binary(Msg) ->
1747    Length = erlang:byte_size(Msg),
1748    Split = Length div 2,
1749    List0 = binary_to_list(Msg),
1750   case lists:split(Split, List0) of
1751       {[Element | List1], List2} ->
1752	   [[Element], List1, List2];
1753       {List1, List2}->
1754	   [List1, List2]
1755   end;
1756iolistify1(Msg) when is_list(Msg) ->
1757    iolistify1(list_to_binary(Msg)).
1758
1759%%--------------------------------------------------------------------
1760mod_pow_aux_test(_, _, _, 0) ->
1761    ok;
1762mod_pow_aux_test(B, E, M, N) ->
1763    Result = crypto:bytes_to_integer(crypto:mod_pow(B, E, M)),
1764    Result = ipow(B, E, M),
1765    mod_pow_aux_test(B, E*E+1, M*M+1, N-1).
1766
1767%% mod_exp in erlang (copied from jungerl's ssh_math.erl)
1768ipow(A, B, M) when M > 0, B >= 0 ->
1769    if A == 1 ->
1770 	    1;
1771       true ->
1772 	    ipow(A, B, M, 1)
1773    end.
1774
1775ipow(A, 1, M, Prod) ->
1776    (A*Prod) rem M;
1777ipow(_A, 0, _M, Prod) ->
1778    Prod;
1779ipow(A, B, M, Prod)  ->
1780    B1 = B bsr 1,
1781    A1 = (A*A) rem M,
1782    if B - B1 == B1 ->
1783	    ipow(A1, B1, M, Prod);
1784       true ->
1785	    ipow(A1, B1, M, (A*Prod) rem M)
1786    end.
1787
1788do_exor(B) ->
1789    Z1 = zero_bin(B),
1790    Z1 = crypto:exor(B, B),
1791    B1 = crypto:strong_rand_bytes(100),
1792    B2 = crypto:strong_rand_bytes(100),
1793    Z2 = zero_bin(B1),
1794    Z2 = crypto:exor(B1, B1),
1795    Z2 = crypto:exor(B2, B2),
1796    R = xor_bytes(B1, B2),
1797    R = crypto:exor(B1, B2).
1798
1799zero_bin(N) when is_integer(N) ->
1800    N8 = N * 8,
1801    <<0:N8/integer>>;
1802zero_bin(B) when is_binary(B) ->
1803    zero_bin(size(B)).
1804xor_bytes(Bin1, Bin2) when is_binary(Bin1), is_binary(Bin2) ->
1805    L1 = binary_to_list(Bin1),
1806    L2 = binary_to_list(Bin2),
1807    list_to_binary(xor_bytes(L1, L2));
1808xor_bytes(L1, L2) ->
1809    xor_bytes(L1, L2, []).
1810
1811xor_bytes([], [], Acc) ->
1812    lists:reverse(Acc);
1813xor_bytes([N1 | Tl1], [N2 | Tl2], Acc) ->
1814    xor_bytes(Tl1, Tl2, [N1 bxor N2 | Acc]).
1815rand_uniform_aux_test(0) ->
1816    ok;
1817rand_uniform_aux_test(N) ->
1818    L = N*1000,
1819    H = N*100000+1,
1820    crypto_rand_uniform(L, H),
1821    crypto_rand_uniform(-L, L),
1822    crypto_rand_uniform(-H, -L),
1823    crypto_rand_uniform(-H, L),
1824    rand_uniform_aux_test(N-1).
1825
1826crypto_rand_uniform(L,H) ->
1827    R1 = (L-1) + rand:uniform(H-L),
1828    case (R1 >= L) and (R1 < H) of
1829	true  ->
1830	    ok;
1831	false ->
1832	    ct:fail({"Not in interval", R1, L, H})
1833    end.
1834
1835foldallmap(_Fun, AccN, []) ->
1836    {true, AccN};
1837foldallmap(Fun, AccN, [H|T]) ->
1838    case Fun(H, AccN) of
1839        {true, AccM} -> foldallmap(Fun, AccM, T);
1840        {{false, Result}, AccM} -> {Result, AccM}
1841    end.
1842
1843allmap(_Fun, []) ->
1844    true;
1845allmap(Fun, [H|T]) ->
1846    case Fun(H) of
1847        true -> allmap(Fun, T);
1848        {false, Result} -> Result
1849    end.
1850
1851rand_plugin_aux(StateType) ->
1852    {Seeder, SeedExporter, FloatGenerator, IntegerGenerator} = rand_plugin_functions(StateType),
1853    State0 = Seeder(),
1854    {crypto, no_seed} = SeedExporter(State0),
1855    {FloatTestResult, State1} = rand_plugin_aux_floats(State0, FloatGenerator),
1856    case FloatTestResult of
1857        true ->
1858            {IntegerTestResult, _State2} = rand_plugin_aux_integers(State1, IntegerGenerator),
1859            IntegerTestResult;
1860        {false, _} ->
1861            FloatTestResult
1862    end.
1863
1864% returns {Seeder, SeedExporter, FloatGenerator, IntegerGenerator} with consistent signatures
1865rand_plugin_functions(implicit_state) ->
1866    {fun () -> crypto:rand_seed(), implicit_state end,
1867     fun (implicit_state) -> rand:export_seed() end,
1868     fun (implicit_state) -> {rand:uniform(), implicit_state} end,
1869     fun (N, implicit_state) -> {rand:uniform(N), implicit_state} end};
1870rand_plugin_functions(explicit_state) ->
1871    {fun crypto:rand_seed_s/0,
1872     fun rand:export_seed_s/1,
1873     fun rand:uniform_s/1,
1874     fun rand:uniform_s/2}.
1875
1876rand_plugin_aux_floats(State0, FloatGenerator) ->
1877    {FloatSamples, State1} =
1878        lists:mapfoldl(
1879          fun (_, StateAcc) ->
1880                  FloatGenerator(StateAcc)
1881          end,
1882          State0,
1883          lists:seq(1, 10000)),
1884
1885    {allmap(
1886       fun (V) ->
1887               (V >= 0.0 andalso V < 1.0)
1888               orelse {false, ct:fail({"Float sample not in interval", V, 0.0, 1.0})}
1889       end,
1890       FloatSamples),
1891     State1}.
1892
1893rand_plugin_aux_integers(State0, IntegerGenerator) ->
1894    MaxIntegerCeiling = 1 bsl 32,
1895    {IntegerCeilings, State1} =
1896        lists:mapfoldl(
1897          fun (_, StateAcc) ->
1898                  IntegerGenerator(MaxIntegerCeiling, StateAcc)
1899          end,
1900          State0,
1901          lists:seq(1, 100)),
1902
1903    foldallmap(
1904      fun (Ceiling, StateAcc) ->
1905              case Ceiling >= 1 andalso Ceiling =< MaxIntegerCeiling of
1906                  false ->
1907                      {{false, ct:fail({"Integer ceiling not in interval",
1908                                        Ceiling, 1, MaxIntegerCeiling})},
1909                       StateAcc};
1910                  true ->
1911                      foldallmap(
1912                        fun (_, SubStateAcc) ->
1913                                {Sample, NewSubStateAcc} = IntegerGenerator(Ceiling, SubStateAcc),
1914                                case Sample >= 1 andalso Sample =< Ceiling of
1915                                    false ->
1916                                        {{false, ct:fail({"Integer sample not in interval",
1917                                                          Sample, 1, Ceiling})},
1918                                         NewSubStateAcc};
1919                                    true ->
1920                                        {true, NewSubStateAcc}
1921                                end
1922                        end,
1923                        StateAcc,
1924                        lists:seq(1, 100))
1925              end
1926      end,
1927      State1,
1928      IntegerCeilings).
1929
1930%%--------------------------------------------------------------------
1931%% Test data ------------------------------------------------
1932%%--------------------------------------------------------------------
1933group_config(md4 = Type, Config) ->
1934    Msgs = rfc_1321_msgs(),
1935    Digests = rfc_1321_md4_digests(),
1936    [{hash, {Type, Msgs, Digests}} | Config];
1937group_config(md5 = Type, Config) ->
1938    Msgs = rfc_1321_msgs(),
1939    Digests = rfc_1321_md5_digests(),
1940    [{hash, {Type, Msgs, Digests}} | Config];
1941group_config(ripemd160 = Type, Config) ->
1942    Msgs = ripemd160_msgs(),
1943    Digests = ripemd160_digests(),
1944   [{hash, {Type, Msgs, Digests}} | Config];
1945group_config(sha = Type, Config) ->
1946    Msgs = [rfc_4634_test1(), rfc_4634_test2_1(),long_msg()],
1947    Digests = rfc_4634_sha_digests() ++ [long_sha_digest()],
1948    [{hash, {Type, Msgs, Digests}} | Config];
1949group_config(sha224 = Type, Config) ->
1950    Msgs = [rfc_4634_test1(), rfc_4634_test2_1()],
1951    Digests = rfc_4634_sha224_digests(),
1952    [{hash, {Type, Msgs, Digests}} | Config];
1953group_config(sha256 = Type, Config) ->
1954    Msgs =   [rfc_4634_test1(), rfc_4634_test2_1(), long_msg()],
1955    Digests = rfc_4634_sha256_digests()  ++ [long_sha256_digest()],
1956    [{hash, {Type, Msgs, Digests}} | Config];
1957group_config(sha384 = Type, Config) ->
1958    Msgs =  [rfc_4634_test1(), rfc_4634_test2(), long_msg()],
1959    Digests = rfc_4634_sha384_digests()  ++ [long_sha384_digest()],
1960    [{hash, {Type, Msgs, Digests}} | Config];
1961group_config(sha512 = Type, Config) ->
1962    Msgs =  [rfc_4634_test1(), rfc_4634_test2(), long_msg()],
1963    Digests = rfc_4634_sha512_digests() ++ [long_sha512_digest()],
1964    [{hash, {Type, Msgs, Digests}} | Config];
1965group_config(sha3_224 = Type, Config) ->
1966    {Msgs,Digests} = sha3_test_vectors(Type),
1967    [{hash, {Type, Msgs, Digests}} | Config];
1968group_config(sha3_256 = Type, Config) ->
1969    {Msgs,Digests} = sha3_test_vectors(Type),
1970    [{hash, {Type, Msgs, Digests}} | Config];
1971group_config(sha3_384 = Type, Config) ->
1972    {Msgs,Digests} = sha3_test_vectors(Type),
1973    [{hash, {Type, Msgs, Digests}} | Config];
1974group_config(sha3_512 = Type, Config) ->
1975    {Msgs,Digests} = sha3_test_vectors(Type),
1976    [{hash, {Type, Msgs, Digests}} | Config];
1977group_config(blake2b = Type, Config) ->
1978    {Msgs, Digests} = blake2_test_vectors(Type),
1979    [{hash, {Type, Msgs, Digests}} | Config];
1980group_config(blake2s = Type, Config) ->
1981    {Msgs, Digests} = blake2_test_vectors(Type),
1982    [{hash, {Type, Msgs, Digests}} | Config];
1983group_config(rsa, Config) ->
1984    Msg = rsa_plain(),
1985    Public = rsa_public(),
1986    Private = rsa_private(),
1987    PublicS = rsa_public_stronger(),
1988    PrivateS = rsa_private_stronger(),
1989    MsgPubEnc = <<"7896345786348 Asldi">>,
1990    SignVerify_OptsToTry = [[{rsa_padding, rsa_x931_padding}],
1991                            [{rsa_padding, rsa_pkcs1_padding}],
1992                            [{rsa_padding, rsa_pkcs1_pss_padding}],
1993                            [{rsa_padding, rsa_pkcs1_pss_padding}, {rsa_pss_saltlen, -2}],
1994                            [{rsa_padding, rsa_pkcs1_pss_padding}, {rsa_pss_saltlen, 5}],
1995                            [{rsa_padding, rsa_pkcs1_pss_padding}, {rsa_mgf1_md,sha}],
1996                            [{rsa_padding, rsa_pkcs1_pss_padding}, {rsa_mgf1_md,sha}, {rsa_pss_saltlen, 5}]
1997                           ],
1998    PrivEnc_OptsToTry = [rsa_pkcs1_padding,              % Compatibility
1999                         [{rsa_pad, rsa_pkcs1_padding}], % Compatibility
2000                         [{rsa_padding, rsa_pkcs1_padding}],
2001                         [{rsa_padding,rsa_x931_padding}]
2002                        ],
2003    PubEnc_OptsToTry = [rsa_pkcs1_padding,              % Compatibility
2004                 [{rsa_pad, rsa_pkcs1_padding}], % Compatibility
2005                 [{rsa_padding, rsa_pkcs1_padding}],
2006                 [{rsa_padding,rsa_pkcs1_oaep_padding}],
2007                 [{rsa_padding,rsa_pkcs1_oaep_padding}, {rsa_oaep_label, <<"Hej hopp">>}],
2008                 [{rsa_padding,rsa_pkcs1_oaep_padding}, {rsa_oaep_md,sha}],
2009                 [{rsa_padding,rsa_pkcs1_oaep_padding}, {rsa_oaep_md,sha}, {rsa_oaep_label, <<"Hej hopp">>}],
2010                 [{rsa_padding,rsa_pkcs1_oaep_padding}, {rsa_mgf1_md,sha}],
2011                 [{rsa_padding,rsa_pkcs1_oaep_padding}, {rsa_mgf1_md,sha}, {rsa_oaep_label, <<"Hej hopp">>}],
2012                 [{rsa_padding,rsa_pkcs1_oaep_padding}, {rsa_mgf1_md,sha}, {rsa_oaep_md,sha}, {rsa_oaep_label, <<"Hej hopp">>}]
2013                 ],
2014    [{sign_verify,      rsa_sign_verify_tests(Config, Msg, Public, Private, PublicS, PrivateS, SignVerify_OptsToTry)},
2015     {pub_priv_encrypt, gen_rsa_pub_priv_tests(PublicS, PrivateS, MsgPubEnc, PrivEnc_OptsToTry)},
2016     {pub_pub_encrypt,  gen_rsa_pub_priv_tests(PublicS, PrivateS, MsgPubEnc, PubEnc_OptsToTry)},
2017     {generate, [{rsa, 1024, 3},  {rsa, 2048, 17},  {rsa, 3072, 65537}]}
2018     | Config];
2019group_config(dss = Type, Config) ->
2020    Msg = dss_plain(),
2021    Public = dss_params() ++ [dss_public()],
2022    Private = dss_params() ++ [dss_private()],
2023    SupportedHashs = proplists:get_value(hashs, crypto:supports(), []),
2024    DssHashs =
2025        case crypto:info_lib() of
2026            [{<<"OpenSSL">>,LibVer,_}] when is_integer(LibVer), LibVer > 16#10001000 ->
2027                [sha, sha224, sha256, sha384, sha512];
2028            [{<<"OpenSSL">>,LibVer,_}] when is_integer(LibVer), LibVer > 16#10000000 ->
2029                [sha, sha224, sha256];
2030            _Else ->
2031                [sha]
2032        end,
2033    SignVerify = [{Type, Hash, Public, Private, Msg}
2034                  || Hash <- DssHashs,
2035                     lists:member(Hash, SupportedHashs)],
2036    MsgPubEnc = <<"7896345786348 Asldi">>,
2037    PubPrivEnc = [{dss, Public, Private, MsgPubEnc, []}],
2038    [{sign_verify, SignVerify}, {pub_priv_encrypt, PubPrivEnc}  | Config];
2039group_config(ecdsa = Type, Config) ->
2040    {Private, Public} = ec_key_named(),
2041    Msg = ec_msg(),
2042    SupportedHashs = proplists:get_value(hashs, crypto:supports(), []),
2043    DssHashs = [sha, sha224, sha256, sha384, sha512],
2044    SignVerify = [{Type, Hash, Public, Private, Msg}
2045                  || Hash <- DssHashs,
2046                     lists:member(Hash, SupportedHashs)],
2047    MsgPubEnc = <<"7896345786348 Asldi">>,
2048    PubPrivEnc = [{ecdsa, Public, Private, MsgPubEnc, []}],
2049    [{sign_verify, SignVerify}, {pub_priv_encrypt, PubPrivEnc} | Config];
2050group_config(Type, Config) when Type == ed25519 ; Type == ed448 ->
2051    TestVectors = eddsa(Type),
2052    Generate = lists:map(fun({Curve, _Hash, Priv, Pub, _Msg, _Signature}) ->
2053                             {eddsa, Curve, Priv, Pub}
2054                         end, TestVectors),
2055    [{sign_verify,TestVectors}, {generate, Generate} | Config];
2056group_config(srp, Config) ->
2057    GenerateCompute = [srp3(), srp6(), srp6a(), srp6a_smaller_prime()],
2058    [{generate_compute, GenerateCompute} | Config];
2059group_config(ecdh, Config) ->
2060    Compute = ecdh(),
2061    Generate = ecc(),
2062    [{compute, Compute}, {generate, Generate} | Config];
2063group_config(eddh, Config) ->
2064    [{compute, []}, {generate, []} | Config];
2065group_config(dh, Config) ->
2066    GenerateCompute = [dh()],
2067    [{generate_compute, GenerateCompute} | Config];
2068
2069group_config(F, Config) ->
2070    TestVectors = fun() -> ?MODULE:F(Config) end,
2071    [{cipher, TestVectors} | Config].
2072
2073
2074configure_mac(MacType, SubType, Config) ->
2075    case do_configure_mac(MacType, SubType, Config) of
2076        undefined ->
2077            {skip, io:format("No ~p test vectors for ~p", [MacType, SubType])};
2078        Pairs ->
2079            [{MacType, Pairs} | Config]
2080    end.
2081
2082do_configure_mac(hmac, Type, _Config) ->
2083    case Type of
2084        md5 ->
2085            Keys = rfc_2202_md5_keys() ++ [long_hmac_key(md5)],
2086            Data = rfc_2202_msgs() ++ [long_msg()],
2087            Hmac = rfc_2202_hmac_md5()  ++ [long_hmac(md5)],
2088            zip3_special(hmac, Type, Keys, Data, Hmac);
2089        sha ->
2090            Keys = rfc_2202_sha_keys() ++ [long_hmac_key(sha)],
2091            Data = rfc_2202_msgs() ++ [long_msg()],
2092            Hmac = rfc_2202_hmac_sha()  ++ [long_hmac(sha)],
2093            zip3_special(hmac, Type, Keys, Data, Hmac);
2094        sha224 ->
2095            Keys = rfc_4231_keys(),
2096            Data = rfc_4231_msgs(),
2097            Hmac = rfc4231_hmac_sha224(),
2098            zip3_special(hmac, Type, Keys, Data, Hmac);
2099        sha256 ->
2100            Keys = rfc_4231_keys() ++ [long_hmac_key(sha256)],
2101            Data = rfc_4231_msgs()  ++ [long_msg()],
2102            Hmac = rfc4231_hmac_sha256()  ++ [long_hmac(sha256)],
2103            zip3_special(hmac, Type, Keys, Data, Hmac);
2104        sha384 ->
2105            Keys = rfc_4231_keys() ++ [long_hmac_key(sha384)],
2106            Data = rfc_4231_msgs()  ++ [long_msg()],
2107            Hmac = rfc4231_hmac_sha384()  ++ [long_hmac(sha384)],
2108            zip3_special(hmac, Type, Keys, Data, Hmac);
2109        sha512 ->
2110            Keys = rfc_4231_keys() ++ [long_hmac_key(sha512)],
2111            Data = rfc_4231_msgs() ++ [long_msg()],
2112            Hmac = rfc4231_hmac_sha512() ++ [long_hmac(sha512)],
2113            zip3_special(hmac, Type, Keys, Data, Hmac);
2114        sha3_224 ->
2115            hmac_sha3(Type);
2116        sha3_256 ->
2117            hmac_sha3(Type);
2118        sha3_384 ->
2119            hmac_sha3(Type);
2120        sha3_512 ->
2121            hmac_sha3(Type);
2122        blake2b ->
2123            blake2_hmac(Type);
2124        blake2s ->
2125            blake2_hmac(Type);
2126        _ ->
2127            undefined
2128    end;
2129do_configure_mac(cmac, Cipher, Config) ->
2130    case Cipher of
2131        aes_128_cbc ->
2132            fun() -> read_rsp(Config, Cipher,  ["CMACGenAES128.rsp", "CMACVerAES128.rsp"]) end;
2133        aes_256_cbc ->
2134            fun() -> read_rsp(Config, Cipher,  ["CMACGenAES256.rsp", "CMACVerAES256.rsp"]) end;
2135        _ ->
2136            undefined
2137    end.
2138
2139
2140zip3_special(Type, SubType, As, Bs, Cs) ->
2141    [{Type, SubType, A, B, C}
2142     || {A,B,C} <- lists:zip3(As, Bs, Cs)].
2143
2144
2145rsa_sign_verify_tests(Config, Msg, Public, Private, PublicS, PrivateS, OptsToTry) ->
2146        case ?config(fips, Config) of
2147            true ->
2148                %% Use only the strong keys in FIPS mode
2149                rsa_sign_verify_tests(Msg,
2150                                      PublicS, PrivateS,
2151                                      PublicS, PrivateS,
2152                                      OptsToTry);
2153            false ->
2154                rsa_sign_verify_tests(Msg,
2155                                      Public,  Private,
2156                                      PublicS, PrivateS,
2157                                      OptsToTry)
2158        end.
2159
2160rsa_sign_verify_tests(Msg, Public, Private, PublicS, PrivateS, OptsToTry) ->
2161    gen_rsa_sign_verify_tests([md5, ripemd160, sha, sha224, sha256], Msg, Public, Private,
2162                              [undefined | OptsToTry]) ++
2163	gen_rsa_sign_verify_tests([sha384, sha512], Msg, PublicS, PrivateS,
2164                                  [undefined | OptsToTry]).
2165
2166gen_rsa_sign_verify_tests(Hashs, Msg, Public, Private, Opts) ->
2167    SupOpts = proplists:get_value(rsa_opts, crypto:supports(), []),
2168    lists:foldr(fun(Hash, Acc0) ->
2169	case is_supported(Hash) of
2170	    true ->
2171		lists:foldr(fun
2172		    (undefined, Acc1) ->
2173			[{rsa, Hash, Public, Private, Msg} | Acc1];
2174		    ([{rsa_padding, rsa_x931_padding} | _], Acc1)
2175			    when Hash =:= md5
2176			    orelse Hash =:= ripemd160
2177			    orelse Hash =:= sha224 ->
2178			Acc1;
2179		    (Opt, Acc1) ->
2180                        case rsa_opt_is_supported(Opt, SupOpts) of
2181                            true ->
2182                                [{rsa, Hash, Public, Private, Msg, Opt} | Acc1];
2183                            false ->
2184                                Acc1
2185                        end
2186		end, Acc0, Opts);
2187	    false ->
2188		Acc0
2189	end
2190    end, [], Hashs).
2191
2192
2193gen_rsa_pub_priv_tests(Public, Private, Msg, OptsToTry) ->
2194    SupOpts = proplists:get_value(rsa_opts, crypto:supports(), []) --
2195        [rsa_x931_padding],
2196    lists:foldr(fun(Opt, Acc) ->
2197                        case rsa_opt_is_supported(Opt, SupOpts) of
2198                            true ->
2199                                [{rsa, Public, Private, Msg, Opt} | Acc];
2200                             false ->
2201                                Acc
2202                        end
2203                end, [], OptsToTry).
2204
2205
2206rsa_opt_is_supported([_|_]=Opt, Sup) ->
2207    lists:all(fun(O) -> rsa_opt_is_supported(O,Sup) end, Opt);
2208rsa_opt_is_supported({A,B}, Sup) ->
2209    rsa_opt_is_supported(A,Sup) orelse rsa_opt_is_supported(B,Sup);
2210rsa_opt_is_supported(Opt, Sup) ->
2211    lists:member(Opt, Sup).
2212
2213
2214rfc_1321_msgs() ->
2215    [<<"">>,
2216     <<"a">>,
2217     <<"abc">>,
2218     <<"message digest">>,
2219     <<"abcdefghijklmnopqrstuvwxyz">>,
2220     <<"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789">>,
2221     <<"12345678901234567890123456789012345678901234567890123456789012345678901234567890">>
2222    ].
2223
2224rfc_1321_md4_digests() ->
2225    [hexstr2bin("31d6cfe0d16ae931b73c59d7e0c089c0"),
2226     hexstr2bin("bde52cb31de33e46245e05fbdbd6fb24"),
2227     hexstr2bin("a448017aaf21d8525fc10ae87aa6729d"),
2228     hexstr2bin("d9130a8164549fe818874806e1c7014b"),
2229     hexstr2bin("d79e1c308aa5bbcdeea8ed63df412da9"),
2230     hexstr2bin("043f8582f241db351ce627e153e7f0e4"),
2231     hexstr2bin("e33b4ddc9c38f2199c3e7b164fcc0536")].
2232
2233rfc_1321_md5_digests() ->
2234    [hexstr2bin("d41d8cd98f00b204e9800998ecf8427e"),
2235     hexstr2bin("0cc175b9c0f1b6a831c399e269772661"),
2236     hexstr2bin("900150983cd24fb0d6963f7d28e17f72"),
2237     hexstr2bin("f96b697d7cb7938d525a2f31aaf161d0"),
2238     hexstr2bin("c3fcd3d76192e4007dfb496cca67e13b"),
2239     hexstr2bin("d174ab98d277d9f5a5611c2c9f419d9f"),
2240     hexstr2bin("57edf4a22be3c955ac49da2e2107b67a")].
2241
2242
2243%% BLAKE2 re-use SHA3 test vectors.
2244blake2_test_vectors(blake2b) ->
2245    {sha3_msgs(),
2246     [ <<186,128,165,63,152,28,77,13,106,39,151,182,159,18,246,233,76,33,47,20,104,90,196,183,75,18,187,111,219,255,162,209,125,135,197,57,42,171,121,45,194,82,213,222,69,51,204,149,24,211,138,168,219,241,146,90,185,35,134,237,212,0,153,35>>
2247     , <<120,106,2,247,66,1,89,3,198,198,253,133,37,82,210,114,145,47,71,64,225,88,71,97,138,134,226,23,247,31,84,25,210,94,16,49,175,238,88,83,19,137,100,68,147,78,176,75,144,58,104,91,20,72,183,85,213,111,112,26,254,155,226,206>>
2248     , <<114,133,255,62,139,215,104,214,155,230,43,59,241,135,101,163,37,145,127,169,116,74,194,245,130,162,8,80,188,43,17,65,237,27,62,69,40,89,90,204,144,119,43,223,45,55,220,138,71,19,11,68,243,58,2,232,115,14,90,216,225,102,232,136>>
2249     , <<206,116,26,197,147,15,227,70,129,17,117,197,34,123,183,191,205,71,244,38,18,250,228,108,8,9,81,79,158,14,58,17,238,23,115,40,113,71,205,234,238,223,245,7,9,170,113,99,65,254,101,36,15,74,214,119,125,107,250,249,114,110,94,82>>
2250     , <<152,251,62,251,114,6,253,25,235,246,155,111,49,44,247,182,78,59,148,219,225,161,113,7,145,57,117,167,147,241,119,225,208,119,96,157,127,186,54,60,187,160,13,5,247,170,78,79,168,113,93,100,40,16,76,10,117,100,59,15,243,253,62,175>>
2251     ]};
2252blake2_test_vectors(blake2s) ->
2253    {sha3_msgs(),
2254     [ <<80,140,94,140,50,124,20,226,225,167,43,163,78,235,69,47,55,69,139,32,158,214,58,41,77,153,155,76,134,103,89,130>>
2255     , <<105,33,122,48,121,144,128,148,225,17,33,208,66,53,74,124,31,85,182,72,44,161,165,30,27,37,13,253,30,208,238,249>>
2256     , <<111,77,245,17,106,111,51,46,218,177,217,225,14,232,125,246,85,123,234,182,37,157,118,99,243,188,213,114,44,19,241,137>>
2257     , <<53,141,210,237,7,128,212,5,78,118,203,111,58,91,206,40,65,232,226,245,71,67,29,77,9,219,33,182,109,148,31,199>>
2258     , <<190,192,192,230,205,229,182,122,203,115,184,31,121,166,122,64,121,174,28,96,218,201,210,102,26,241,142,159,139,80,223,165>>
2259     ]}.
2260
2261blake2_hmac(Type) ->
2262    [{hmac, Type, hexstr2bin(K), hexstr2bin(D), H}
2263     || {{K, D}, H} <- lists:zip(blake2_hmac_key_data(), blake2_hmac_hmac(Type)) ].
2264
2265blake2_hmac_key_data() ->
2266    [ {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b 0b0b0b0b",
2267       "4869205468657265"}
2268    , {"4a656665",
2269      "7768617420646f2079612077616e7420 666f72206e6f7468696e673f"}
2270    , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaa",
2271      "dddddddddddddddddddddddddddddddd dddddddddddddddddddddddddddddddd dddddddddddddddddddddddddddddddd dddd"}
2272    , {"0102030405060708090a0b0c0d0e0f10 111213141516171819",
2273      "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcd"}
2274    , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2275      "54657374205573696e67204c61726765 72205468616e20426c6f636b2d53697a 65204b6579202d2048617368204b6579 204669727374"}
2276    , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2277      "54657374205573696e67204c61726765 72205468616e20426c6f636b2d53697a 65204b6579202d2048617368204b6579 204669727374"}
2278    , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2279      "54686973206973206120746573742075 73696e672061206c6172676572207468 616e20626c6f636b2d73697a65206b65 7920616e642061206c61726765722074 68616e20626c6f636b2d73697a652064 6174612e20546865206b6579206e6565 647320746f2062652068617368656420 6265666f7265206265696e6720757365 642062792074686520484d414320616c 676f726974686d2e"}
2280    , {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2281      "54686973206973206120746573742075 73696e672061206c6172676572207468 616e20626c6f636b2d73697a65206b65 7920616e642061206c61726765722074 68616e20626c6f636b2d73697a652064 6174612e20546865206b6579206e6565 647320746f2062652068617368656420 6265666f7265206265696e6720757365 642062792074686520484d414320616c 676f726974686d2e"}
2282    ].
2283
2284blake2_hmac_hmac(blake2b) ->
2285    [ <<53,138,106,24,73,36,137,79,195,75,238,86,128,238,223,87,216,74,55,187,56,131,47,40,142,59,39,220,99,169,140,200,201,30,118,218,71,107,80,139,198,178,212,8,162,72,133,116,82,144,110,74,32,180,140,107,75,85,210,223,15,225,221,36>>
2286    , <<111,248,132,248,221,194,166,88,107,60,152,164,205,110,189,241,78,193,2,4,182,113,0,115,235,88,101,173,227,122,38,67,184,128,124,19,53,209,7,236,219,159,254,174,182,130,140,70,37,186,23,44,102,55,158,252,210,34,194,222,17,114,122,180>>
2287    , <<244,59,198,44,122,153,53,60,59,44,96,232,239,36,251,189,66,233,84,120,102,220,156,91,228,237,198,244,167,212,188,10,198,32,194,198,0,52,208,64,240,219,175,134,249,233,205,120,145,160,149,89,94,237,85,226,169,150,33,95,12,21,192,24>>
2288    , <<229,219,182,222,47,238,66,161,202,160,110,78,123,132,206,64,143,250,92,74,157,226,99,46,202,118,156,222,136,117,1,76,114,208,114,15,234,245,63,118,230,161,128,53,127,82,141,123,244,132,250,58,20,232,204,31,15,59,173,167,23,180,52,145>>
2289    , <<165,75,41,67,178,162,2,39,212,28,164,108,9,69,175,9,188,31,174,251,47,73,137,76,35,174,188,85,127,183,156,72,137,220,167,68,8,220,134,80,134,102,122,237,238,74,49,133,197,58,73,200,11,129,76,76,88,19,234,12,139,56,168,248>>
2290    , <<180,214,140,139,182,82,151,170,52,132,168,110,29,51,183,138,70,159,33,234,170,158,212,218,159,236,145,218,71,23,34,61,44,15,163,134,170,47,209,241,255,207,89,23,178,103,84,96,53,237,48,238,164,178,19,162,133,148,211,211,169,179,140,170>>
2291    , <<171,52,121,128,166,75,94,130,93,209,14,125,50,253,67,160,26,142,109,234,38,122,185,173,125,145,53,36,82,102,24,146,83,17,175,188,176,196,149,25,203,235,221,112,149,64,168,215,37,251,145,26,194,174,233,178,163,170,67,215,150,18,51,147>>
2292    , <<97,220,242,140,166,12,169,92,130,89,147,39,171,215,169,161,152,111,242,219,211,199,73,69,198,227,35,186,203,76,159,26,94,103,82,93,20,186,141,98,36,177,98,229,102,23,21,37,83,3,69,169,178,86,8,178,125,251,163,180,146,115,213,6>>
2293    ];
2294blake2_hmac_hmac(blake2s) ->
2295    [ <<101,168,183,197,204,145,54,212,36,232,44,55,226,112,126,116,233,19,192,101,91,153,199,95,64,237,243,135,69,58,50,96>>
2296    , <<144,182,40,30,47,48,56,201,5,106,240,180,167,231,99,202,230,254,93,158,180,56,106,14,201,82,55,137,12,16,79,240>>
2297    , <<252,196,245,149,41,80,46,52,195,216,218,63,253,171,130,150,106,44,182,55,255,94,155,215,1,19,92,46,148,105,231,144>>
2298    , <<70,68,52,220,190,206,9,93,69,106,29,98,214,236,86,248,152,230,37,163,158,92,82,189,249,77,175,17,27,173,131,170>>
2299    , <<210,61,121,57,79,83,213,54,160,150,230,81,68,71,238,170,187,5,222,208,27,227,44,25,55,218,106,143,113,3,188,78>>
2300    , <<92,76,83,46,110,69,89,83,133,78,21,16,149,38,110,224,127,213,88,129,190,223,139,57,8,217,95,13,190,54,159,234>>
2301    , <<203,96,246,167,145,241,64,191,138,162,229,31,243,88,205,178,204,92,3,51,4,91,127,183,122,186,122,179,176,207,178,55>>
2302    , <<190,53,233,217,99,171,215,108,1,184,171,181,22,36,240,209,16,96,16,92,213,22,16,58,114,241,117,214,211,189,30,202>>
2303    ].
2304
2305%%% https://www.di-mgt.com.au/sha_testvectors.html
2306sha3_msgs() ->
2307    ["abc",
2308     "",
2309     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", % length 448 bits
2310     "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", % length 896 bits
2311     lists:duplicate(1000000,$a)
2312    ].
2313
2314sha3_test_vectors(sha3_224) ->
2315    {sha3_msgs(),
2316     [hexstr2bin("e642824c3f8cf24a d09234ee7d3c766f c9a3a5168d0c94ad 73b46fdf"),
2317      hexstr2bin("6b4e03423667dbb7 3b6e15454f0eb1ab d4597f9a1b078e3f 5b5a6bc7"),
2318      hexstr2bin("8a24108b154ada21 c9fd5574494479ba 5c7e7ab76ef264ea d0fcce33"),
2319      hexstr2bin("543e6868e1666c1a 643630df77367ae5 a62a85070a51c14c bf665cbc"),
2320      hexstr2bin("d69335b93325192e 516a912e6d19a15c b51c6ed5c15243e7 a7fd653c")
2321     ]
2322    };
2323sha3_test_vectors(sha3_256) ->
2324    {sha3_msgs(),
2325     [hexstr2bin("3a985da74fe225b2 045c172d6bd390bd 855f086e3e9d525b 46bfe24511431532"),
2326      hexstr2bin("a7ffc6f8bf1ed766 51c14756a061d662 f580ff4de43b49fa 82d80a4b80f8434a"),
2327      hexstr2bin("41c0dba2a9d62408 49100376a8235e2c 82e1b9998a999e21 db32dd97496d3376"),
2328      hexstr2bin("916f6061fe879741 ca6469b43971dfdb 28b1a32dc36cb325 4e812be27aad1d18"),
2329      hexstr2bin("5c8875ae474a3634 ba4fd55ec85bffd6 61f32aca75c6d699 d0cdcb6c115891c1")
2330     ]
2331    };
2332sha3_test_vectors(sha3_384) ->
2333    {sha3_msgs(),
2334     [hexstr2bin("ec01498288516fc9 26459f58e2c6ad8d f9b473cb0fc08c25 96da7cf0e49be4b2 98d88cea927ac7f5 39f1edf228376d25"),
2335      hexstr2bin("0c63a75b845e4f7d 01107d852e4c2485 c51a50aaaa94fc61 995e71bbee983a2a c3713831264adb47 fb6bd1e058d5f004"),
2336      hexstr2bin("991c665755eb3a4b 6bbdfb75c78a492e 8c56a22c5c4d7e42 9bfdbc32b9d4ad5a a04a1f076e62fea1 9eef51acd0657c22"),
2337      hexstr2bin("79407d3b5916b59c 3e30b09822974791 c313fb9ecc849e40 6f23592d04f625dc 8c709b98b43b3852 b337216179aa7fc7"),
2338      hexstr2bin("eee9e24d78c18553 37983451df97c8ad 9eedf256c6334f8e 948d252d5e0e7684 7aa0774ddb90a842 190d2c558b4b8340")
2339     ]
2340    };
2341sha3_test_vectors(sha3_512) ->
2342    {sha3_msgs(),
2343     [hexstr2bin("b751850b1a57168a 5693cd924b6b096e 08f621827444f70d 884f5d0240d2712e 10e116e9192af3c9 1a7ec57647e39340 57340b4cf408d5a5 6592f8274eec53f0"),
2344      hexstr2bin("a69f73cca23a9ac5 c8b567dc185a756e 97c982164fe25859 e0d1dcc1475c80a6 15b2123af1f5f94c 11e3e9402c3ac558 f500199d95b6d3e3 01758586281dcd26"),
2345      hexstr2bin("04a371e84ecfb5b8 b77cb48610fca818 2dd457ce6f326a0f d3d7ec2f1e91636d ee691fbe0c985302 ba1b0d8dc78c0863 46b533b49c030d99 a27daf1139d6e75e"),
2346      hexstr2bin("afebb2ef542e6579 c50cad06d2e578f9 f8dd6881d7dc824d 26360feebf18a4fa 73e3261122948efc fd492e74e82e2189 ed0fb440d187f382 270cb455f21dd185"),
2347      hexstr2bin("3c3a876da14034ab 60627c077bb98f7e 120a2a5370212dff b3385a18d4f38859 ed311d0a9d5141ce 9cc5c66ee689b266 a8aa18ace8282a0e 0db596c90b0a7b87")
2348     ]
2349    }.
2350
2351
2352
2353%%% http://www.wolfgang-ehrhardt.de/hmac-sha3-testvectors.html
2354
2355hmac_sha3(Type) ->
2356    N = case Type of
2357            sha3_224 -> 1;
2358            sha3_256 -> 2;
2359            sha3_384 -> 3;
2360            sha3_512 -> 4
2361        end,
2362    [{hmac, Type, hexstr2bin(Key), hexstr2bin(Data), hexstr2bin(element(N,Hmacs))}
2363     || {Key,Data,Hmacs} <- hmac_sha3_data()].
2364
2365hmac_sha3_data() ->
2366    [
2367     {"0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b 0b0b0b0b",
2368      "4869205468657265",
2369      {"3b16546bbc7be2706a031dcafd56373d 9884367641d8c59af3c860f7",
2370       "ba85192310dffa96e2a3a40e69774351 140bb7185e1202cdcc917589f95e16bb",
2371       "68d2dcf7fd4ddd0a2240c8a437305f61 fb7334cfb5d0226e1bc27dc10a2e723a 20d370b47743130e26ac7e3d532886bd",
2372       "eb3fbd4b2eaab8f5c504bd3a41465aac ec15770a7cabac531e482f860b5ec7ba 47ccb2c6f2afce8f88d22b6dc61380f2 3a668fd3888bb80537c0a0b86407689e"
2373      }},
2374
2375     {"4a656665",
2376      "7768617420646f2079612077616e7420 666f72206e6f7468696e673f",
2377      {"7fdb8dd88bd2f60d1b798634ad386811 c2cfc85bfaf5d52bbace5e66",
2378       "c7d4072e788877ae3596bbb0da73b887 c9171f93095b294ae857fbe2645e1ba5",
2379       "f1101f8cbf9766fd6764d2ed61903f21 ca9b18f57cf3e1a23ca13508a93243ce 48c045dc007f26a21b3f5e0e9df4c20a",
2380       "5a4bfeab6166427c7a3647b747292b83 84537cdb89afb3bf5665e4c5e709350b 287baec921fd7ca0ee7a0c31d022a95e 1fc92ba9d77df883960275beb4e62024"
2381       }},
2382
2383     {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaa",
2384      "dddddddddddddddddddddddddddddddd dddddddddddddddddddddddddddddddd dddddddddddddddddddddddddddddddd dddd",
2385      {"676cfc7d16153638780390692be142d2 df7ce924b909c0c08dbfdc1a",
2386       "84ec79124a27107865cedd8bd82da996 5e5ed8c37b0ac98005a7f39ed58a4207",
2387       "275cd0e661bb8b151c64d288f1f782fb 91a8abd56858d72babb2d476f0458373 b41b6ab5bf174bec422e53fc3135ac6e",
2388       "309e99f9ec075ec6c6d475eda1180687 fcf1531195802a99b5677449a8625182 851cb332afb6a89c411325fbcbcd42af cb7b6e5aab7ea42c660f97fd8584bf03"
2389       }},
2390
2391     {"0102030405060708090a0b0c0d0e0f10 111213141516171819",
2392      "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd cdcd",
2393      {"a9d7685a19c4e0dbd9df2556cc8a7d2a 7733b67625ce594c78270eeb",
2394       "57366a45e2305321a4bc5aa5fe2ef8a9 21f6af8273d7fe7be6cfedb3f0aea6d7",
2395       "3a5d7a879702c086bc96d1dd8aa15d9c 46446b95521311c606fdc4e308f4b984 da2d0f9449b3ba8425ec7fb8c31bc136",
2396       "b27eab1d6e8d87461c29f7f5739dd58e 98aa35f8e823ad38c5492a2088fa0281 993bbfff9a0e9c6bf121ae9ec9bb09d8 4a5ebac817182ea974673fb133ca0d1d"
2397       }},
2398
2399     %% {"0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c 0c0c0c0c",
2400     %%  "546573742057697468205472756e6361 74696f6e",
2401     %%  {"49fdd3abd005ebb8ae63fea946d1883c",
2402     %%   "6e02c64537fb118057abb7fb66a23b3c",
2403     %%   "47c51ace1ffacffd7494724682615783",
2404     %%   "0fa7475948f43f48ca0516671e18978c"
2405     %%   }},
2406
2407     {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2408      "54657374205573696e67204c61726765 72205468616e20426c6f636b2d53697a 65204b6579202d2048617368204b6579 204669727374",
2409      {"b4a1f04c00287a9b7f6075b313d279b8 33bc8f75124352d05fb9995f",
2410       "ed73a374b96c005235f948032f09674a 58c0ce555cfc1f223b02356560312c3b",
2411       "0fc19513bf6bd878037016706a0e57bc 528139836b9a42c3d419e498e0e1fb96 16fd669138d33a1105e07c72b6953bcc",
2412       "00f751a9e50695b090ed6911a4b65524 951cdc15a73a5d58bb55215ea2cd839a c79d2b44a39bafab27e83fde9e11f634 0b11d991b1b91bf2eee7fc872426c3a4"
2413       }},
2414
2415     {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2416      "54657374205573696e67204c61726765 72205468616e20426c6f636b2d53697a 65204b6579202d2048617368204b6579 204669727374",
2417      {
2418       "b96d730c148c2daad8649d83defaa371 9738d34775397b7571c38515",
2419       "a6072f86de52b38bb349fe84cd6d97fb 6a37c4c0f62aae93981193a7229d3467",
2420       "713dff0302c85086ec5ad0768dd65a13 ddd79068d8d4c6212b712e4164944911 1480230044185a99103ed82004ddbfcc",
2421       "b14835c819a290efb010ace6d8568dc6 b84de60bc49b004c3b13eda763589451 e5dd74292884d1bdce64e6b919dd61dc 9c56a282a81c0bd14f1f365b49b83a5b"
2422      }},
2423
2424     {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2425      "54686973206973206120746573742075 73696e672061206c6172676572207468 616e20626c6f636b2d73697a65206b65 7920616e642061206c61726765722074 68616e20626c6f636b2d73697a652064 6174612e20546865206b6579206e6565 647320746f2062652068617368656420 6265666f7265206265696e6720757365 642062792074686520484d414320616c 676f726974686d2e",
2426      {
2427       "05d8cd6d00faea8d1eb68ade28730bbd 3cbab6929f0a086b29cd62a0",
2428       "65c5b06d4c3de32a7aef8763261e49ad b6e2293ec8e7c61e8de61701fc63e123",
2429       "026fdf6b50741e373899c9f7d5406d4e b09fc6665636fc1a530029ddf5cf3ca5 a900edce01f5f61e2f408cdf2fd3e7e8",
2430       "38a456a004bd10d32c9ab83366841128 62c3db61adcca31829355eaf46fd5c73 d06a1f0d13fec9a652fb3811b577b1b1 d1b9789f97ae5b83c6f44dfcf1d67eba"
2431       }},
2432
2433     {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaa",
2434      "54686973206973206120746573742075 73696e672061206c6172676572207468 616e20626c6f636b2d73697a65206b65 7920616e642061206c61726765722074 68616e20626c6f636b2d73697a652064 6174612e20546865206b6579206e6565 647320746f2062652068617368656420 6265666f7265206265696e6720757365 642062792074686520484d414320616c 676f726974686d2e",
2435      {
2436       "c79c9b093424e588a9878bbcb089e018 270096e9b4b1a9e8220c866a",
2437       "e6a36d9b915f86a093cac7d110e9e04c f1d6100d30475509c2475f571b758b5a",
2438       "cad18a8ff6c4cc3ad487b95f9769e9b6 1c062aefd6952569e6e6421897054cfc 70b5fdc6605c18457112fc6aaad45585",
2439       "dc030ee7887034f32cf402df34622f31 1f3e6cf04860c6bbd7fa488674782b46 59fdbdf3fd877852885cfe6e22185fe7 b2ee952043629bc9d5f3298a41d02c66"
2440       }}
2441    %%,
2442
2443    %%  {"4a656665",
2444    %%   "'11001' or LSB 13 or MSB c8",
2445    %%   {
2446     %% "5f8c0ea7fafecd0c3463aad09742cece  b142fe0ab6f4539438c59de8",
2447     %% "ec8222773fac68b3d3dcb182aec8b050  7ace4448d20a1147e682118da4e3f44c",
2448     %% "21fbd3bf3ebba3cfc9ef64c0591c92c5  acb265e92d8761d1f91a52a103a6c796  94cfd67a9a2ac1324f02fea63b81effc",
2449     %% "27f9388c1567ef4ef200602a6cf871d6  8a6fb048d4737ac4418a2f021289d13d  1fd1120fecb9cf964c5b117ab5b11c61  4b2da39dadd51f2f5e22aaccec7d576e"
2450     %%   }}
2451    ].
2452
2453
2454
2455rfc_4634_test1() ->
2456    <<"abc">>.
2457rfc_4634_test2_1() ->
2458    <<"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq">>.
2459rfc_4634_test2_2a() ->
2460    <<"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn">>.
2461rfc_4634_test2_2b() ->
2462    <<"hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu">>.
2463rfc_4634_test2() ->
2464    A2 =rfc_4634_test2_2a(),
2465    B2 = rfc_4634_test2_2b(),
2466    <<A2/binary, B2/binary>>.
2467
2468rfc_4634_sha_digests()->
2469     [hexstr2bin("A9993E364706816ABA3E25717850C26C9CD0D89D"),
2470      hexstr2bin("84983E441C3BD26EBAAE4AA1F95129E5E54670F1")].
2471rfc_4634_sha224_digests() ->
2472     [hexstr2bin("23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7"),
2473      hexstr2bin("75388B16512776CC5DBA5DA1FD890150B0C6455CB4F58B1952522525")].
2474rfc_4634_sha256_digests() ->
2475    [
2476     hexstr2bin("BA7816BF8F01CFEA4141"
2477		"40DE5DAE2223B00361A396177A9CB410FF61F20015AD"),
2478     hexstr2bin("248D6A61D20638B8"
2479		"E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1")
2480    ].
2481rfc_4634_sha384_digests() ->
2482    [hexstr2bin("CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED1631A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7"),
2483     hexstr2bin("09330C33F71147E83D192FC782CD1B4753111B173B3B05D22FA08086E3B0F712FCC7C71A557E2DB966C3E9FA91746039")
2484    ].
2485rfc_4634_sha512_digests() ->
2486    [hexstr2bin("DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA2"
2487		"0A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD"
2488		"454D4423643CE80E2A9AC94FA54CA49F"),
2489     hexstr2bin("8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA17299AEADB6889018501D289E4900F7E4331B99DEC4B5433AC7D329EEB6DD26545E96E55B874BE909")].
2490
2491long_msg() ->
2492    fun() -> lists:duplicate(1000000, $a) end.
2493
2494%% Passing huge terms (like long_msg/0) through config causes excessive memory
2495%% consumption and long runtimes in the test server. This results in test_server
2496%% crash with 'no_answer_from_tc_supervisor' sometimes on some machines.
2497%% Therefore lazy evaluation when test case has started.
2498lazy_eval(F) when is_function(F) -> F();
2499lazy_eval(Lst)  when is_list(Lst) -> lists:map(fun lazy_eval/1, Lst);
2500lazy_eval(Tpl) when is_tuple(Tpl) -> list_to_tuple(lists:map(fun lazy_eval/1, tuple_to_list(Tpl)));
2501lazy_eval(Term) -> Term.
2502
2503long_sha_digest() ->
2504    hexstr2bin("34aa973c" "d4c4daa4" "f61eeb2b" "dbad2731" "6534016f").
2505
2506long_sha256_digest() ->
2507    hexstr2bin("cdc76e5c" "9914fb92" "81a1c7e2" "84d73e67" "f1809a48" "a497200e" "046d39cc" "c7112cd0").
2508
2509long_sha384_digest() ->
2510    hexstr2bin("9d0e1809716474cb" "086e834e310a4a1c" "ed149e9c00f24852" "7972cec5704c2a5b"
2511	       "07b8b3dc38ecc4eb" "ae97ddd87f3d8985").
2512
2513long_sha512_digest() ->
2514    hexstr2bin("e718483d0ce76964" "4e2e42c7bc15b463" "8e1f98b13b204428" "5632a803afa973eb"
2515	       "de0ff244877ea60a" "4cb0432ce577c31b" "eb009c5c2c49aa2e" "4eadb217ad8cc09b").
2516
2517ripemd160_msgs() ->
2518    [<<"">>,
2519     <<"a">>,
2520     <<"abc">>,
2521     <<"message digest">>,
2522     <<"abcdefghijklmnopqrstuvwxyz">>,
2523     <<"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq">>,
2524     <<"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789">>
2525    ].
2526
2527ripemd160_digests() ->
2528    [hexstr2bin("9c1185a5c5e9fc54612808977ee8f548b2258d31"),
2529     hexstr2bin("0bdc9d2d256b3ee9daae347be6f4dc835a467ffe"),
2530     hexstr2bin("8eb208f7e05d987a9b044a8e98c6b087f15a0bfc"),
2531     hexstr2bin("5d0689ef49d2fae572b881b123a85ffa21595f36"),
2532     hexstr2bin("f71c27109c692c1b56bbdceb5b9d2865b3708dbc"),
2533     hexstr2bin("12a053384a9c0c88e405a06c27dcf49ada62eb2b"),
2534     hexstr2bin("b0e20b6e3116640286ed3a87a5713079b21f5189")
2535    ].
2536
2537ripemd160_incr_msgs() ->
2538     [<<"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg">>,<<"hijklmnopqrstuvwxyz0123456789">>].
2539ripemd160_incr_digest() ->
2540    hexstr2bin("b0e20b6e3116640286ed3a87a5713079b21f5189").
2541
2542rfc_2202_md5_keys() ->
2543    [binary:copy(<<16#0b>>, 16),
2544     <<"Jefe">>,
2545     binary:copy(<<16#aa>>, 16),
2546     list_to_binary(lists:seq(1, 16#19)),
2547     binary:copy(<<16#0c>>, 16),
2548     binary:copy(<<16#aa>>, 80),
2549     binary:copy(<<16#aa>>, 80)].
2550
2551rfc_2202_sha_keys() ->
2552    [binary:copy(<<16#0b>>, 20),
2553     <<"Jefe">>,
2554     binary:copy(<<16#aa>>, 20),
2555     list_to_binary(lists:seq(1, 16#19)),
2556     binary:copy(<<16#0c>>, 20),
2557     binary:copy(<<16#aa>>, 80),
2558     binary:copy(<<16#aa>>, 80)].
2559
2560rfc_2202_msgs()->
2561    [<<"Hi There">>,
2562     <<"what do ya want for nothing?">>,
2563     binary:copy(<<16#dd>>, 50),
2564     binary:copy(<<16#cd>>, 50),
2565     <<"Test With Truncation">>,
2566     <<"Test Using Larger Than Block-Size Key - Hash Key First">>,
2567     <<"Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data">>
2568    ].
2569
2570%% https://www.cosic.esat.kuleuven.be/nessie/testvectors/
2571long_hmac_key(Type) when Type == sha384;
2572			 Type == sha512 ->
2573    hexstr2bin("00112233445566778899AABBCCDDEEFF"
2574	       "0123456789ABCDEF0011223344556677"
2575	       "8899AABBCCDDEEFF0123456789ABCDEF"
2576	       "00112233445566778899AABBCCDDEEFF");
2577long_hmac_key(_) ->
2578    hexstr2bin("0123456789ABCDEF0123456789ABCDEF"
2579	       "0123456789ABCDEF0123456789ABCDEF"
2580	       "0123456789ABCDEF0123456789ABCDEF"
2581	       "0123456789ABCDEF0123456789ABCDEF").
2582long_hmac(md5) ->
2583    hexstr2bin("82FDDA30202CB6ACC6F24D4F8A50EB7A");
2584long_hmac(sha) ->
2585    hexstr2bin("61D1D0B6459860755FDA892938C23DD401E54A7E");
2586long_hmac(sha256) ->
2587    hexstr2bin("50008B8DC7ED3926936347FDC1A01E9D"
2588	       "5220C6CC4B038B482C0F28A4CD88CA37");
2589long_hmac(sha384) ->
2590    hexstr2bin("C1EB08DAFA015833D3FC6B29A387558B"
2591	       "3F6FA1524AA1A8EB64798D5A76A39D6E"
2592	       "A1465525342E060EE996277B4FFCDDC9");
2593long_hmac(sha512) ->
2594    hexstr2bin("D116BF471AAE1264854F1906025E846A"
2595	       "61618A965FCA30B695220EA2D6E547E3"
2596	       "F3B5A4B54E6778928C26D5D3D810498E"
2597	       "8DF86CB3CC1E9F66A00419B13B6B0C9A").
2598
2599rfc_2202_hmac_md5() ->
2600    [
2601     hexstr2bin("9294727a3638bb1c13f48ef8158bfc9d"),
2602     hexstr2bin("750c783e6ab0b503eaa86e310a5db738"),
2603     hexstr2bin("56be34521d144c88dbb8c733f0e8b3f6"),
2604     hexstr2bin("697eaf0aca3a3aea3a75164746ffaa79"),
2605     hexstr2bin("56461ef2342edc00f9bab995690efd4c"),
2606     hexstr2bin("6b1ab7fe4bd7bf8f0b62e6ce61b9d0cd"),
2607     hexstr2bin("6f630fad67cda0ee1fb1f562db3aa53e")
2608    ].
2609
2610rfc_2202_hmac_sha() ->
2611    [
2612     hexstr2bin("b617318655057264e28bc0b6fb378c8ef146be00"),
2613     hexstr2bin("effcdf6ae5eb2fa2d27416d5f184df9c259a7c79"),
2614     hexstr2bin("125d7342b9ac11cd91a39af48aa17b4f63f175d3"),
2615     hexstr2bin("4c9007f4026250c6bc8414f9bf50c86c2d7235da"),
2616     hexstr2bin("4c1a03424b55e07fe7f27be1d58bb9324a9a5a04"),
2617     hexstr2bin("aa4ae5e15272d00e95705637ce8a3b55ed402112"),
2618     hexstr2bin("e8e99d0f45237d786d6bbaa7965c7808bbff1a91")
2619    ].
2620
2621
2622rfc_4231_keys() ->
2623    [binary:copy(<<16#0b>>, 20),
2624     <<"Jefe">>,
2625     binary:copy(<<16#aa>>, 20),
2626     list_to_binary(lists:seq(1, 16#19)),
2627     binary:copy(<<16#0c>>, 20),
2628     binary:copy(<<16#aa>>, 131),
2629     binary:copy(<<16#aa>>, 131)
2630    ].
2631
2632rfc_4231_msgs() ->
2633    [<<"Hi There">>,
2634     <<"what do ya want for nothing?">>,
2635     binary:copy(<<16#dd>>, 50),
2636     binary:copy(<<16#cd>>, 50),
2637     <<"Test With Truncation">>,
2638     <<"Test Using Larger Than Block-Size Key - Hash Key First">>,
2639     <<"This is a test using a larger than block-size key and a larger t",
2640       "han block-size data. The key needs to be hashed before being use",
2641       "d by the HMAC algorithm.">>
2642    ].
2643
2644rfc4231_hmac_sha224() ->
2645    [hexstr2bin("896fb1128abbdf196832107cd49df33f"
2646		       "47b4b1169912ba4f53684b22"),
2647     hexstr2bin("a30e01098bc6dbbf45690f3a7e9e6d0f"
2648		       "8bbea2a39e6148008fd05e44"),
2649     hexstr2bin("7fb3cb3588c6c1f6ffa9694d7d6ad264"
2650		       "9365b0c1f65d69d1ec8333ea"),
2651     hexstr2bin("6c11506874013cac6a2abc1bb382627c"
2652		       "ec6a90d86efc012de7afec5a"),
2653     hexstr2bin("0e2aea68a90c8d37c988bcdb9fca6fa8"),
2654     hexstr2bin("95e9a0db962095adaebe9b2d6f0dbce2"
2655		       "d499f112f2d2b7273fa6870e"),
2656     hexstr2bin("3a854166ac5d9f023f54d517d0b39dbd"
2657		"946770db9c2b95c9f6f565d1")].
2658rfc4231_hmac_sha256() ->
2659    [hexstr2bin("b0344c61d8db38535ca8afceaf0bf12b"
2660		"881dc200c9833da726e9376c2e32cff7"),
2661     hexstr2bin("5bdcc146bf60754e6a042426089575c7"
2662		"5a003f089d2739839dec58b964ec3843"),
2663     hexstr2bin("773ea91e36800e46854db8ebd09181a7"
2664		"2959098b3ef8c122d9635514ced565fe"),
2665    hexstr2bin("82558a389a443c0ea4cc819899f2083a"
2666	       "85f0faa3e578f8077a2e3ff46729665b"),
2667     hexstr2bin("a3b6167473100ee06e0c796c2955552b"),
2668     hexstr2bin("60e431591ee0b67f0d8a26aacbf5b77f"
2669		"8e0bc6213728c5140546040f0ee37f54"),
2670     hexstr2bin("9b09ffa71b942fcb27635fbcd5b0e944"
2671		"bfdc63644f0713938a7f51535c3a35e2")].
2672
2673rfc4231_hmac_sha384() ->
2674    [hexstr2bin("afd03944d84895626b0825f4ab46907f"
2675		"15f9dadbe4101ec682aa034c7cebc59c"
2676		"faea9ea9076ede7f4af152e8b2fa9cb6"),
2677     hexstr2bin("af45d2e376484031617f78d2b58a6b1b"
2678		"9c7ef464f5a01b47e42ec3736322445e"
2679	       "8e2240ca5e69e2c78b3239ecfab21649"),
2680     hexstr2bin("88062608d3e6ad8a0aa2ace014c8a86f"
2681	       "0aa635d947ac9febe83ef4e55966144b"
2682		"2a5ab39dc13814b94e3ab6e101a34f27"),
2683     hexstr2bin("3e8a69b7783c25851933ab6290af6ca7"
2684		"7a9981480850009cc5577c6e1f573b4e"
2685		"6801dd23c4a7d679ccf8a386c674cffb"),
2686     hexstr2bin("3abf34c3503b2a23a46efc619baef897"),
2687     hexstr2bin("4ece084485813e9088d2c63a041bc5b4"
2688		"4f9ef1012a2b588f3cd11f05033ac4c6"
2689		"0c2ef6ab4030fe8296248df163f44952"),
2690     hexstr2bin("6617178e941f020d351e2f254e8fd32c"
2691		"602420feb0b8fb9adccebb82461e99c5"
2692		"a678cc31e799176d3860e6110c46523e")].
2693rfc4231_hmac_sha512() ->
2694    [hexstr2bin("87aa7cdea5ef619d4ff0b4241a1d6cb0"
2695		"2379f4e2ce4ec2787ad0b30545e17cde"
2696		"daa833b7d6b8a702038b274eaea3f4e4"
2697		"be9d914eeb61f1702e696c203a126854"),
2698     hexstr2bin("164b7a7bfcf819e2e395fbe73b56e0a3"
2699		"87bd64222e831fd610270cd7ea250554"
2700		"9758bf75c05a994a6d034f65f8f0e6fd"
2701		"caeab1a34d4a6b4b636e070a38bce737"),
2702     hexstr2bin("fa73b0089d56a284efb0f0756c890be9"
2703		"b1b5dbdd8ee81a3655f83e33b2279d39"
2704		"bf3e848279a722c806b485a47e67c807"
2705		"b946a337bee8942674278859e13292fb"),
2706     hexstr2bin("b0ba465637458c6990e5a8c5f61d4af7"
2707		"e576d97ff94b872de76f8050361ee3db"
2708		"a91ca5c11aa25eb4d679275cc5788063"
2709		"a5f19741120c4f2de2adebeb10a298dd"),
2710     hexstr2bin("415fad6271580a531d4179bc891d87a6"),
2711     hexstr2bin("80b24263c7c1a3ebb71493c1dd7be8b4"
2712		"9b46d1f41b4aeec1121b013783f8f352"
2713		"6b56d037e05f2598bd0fd2215d6a1e52"
2714		"95e64f73f63f0aec8b915a985d786598"),
2715     hexstr2bin("e37b6a775dc87dbaa4dfa9f96e5e3ffd"
2716		"debd71f8867289865df5a32d20cdc944"
2717		"b6022cac3c4982b10d5eeb55c3e4de15"
2718		"134676fb6de0446065c97440fa8c6a58")].
2719des_cbc(_) ->
2720    [{des_cbc,
2721     hexstr2bin("0123456789abcdef"),
2722     hexstr2bin("1234567890abcdef"),
2723     <<"Now is the time for all ">> }].
2724
2725des_cfb(_) ->
2726    [{des_cfb,
2727     hexstr2bin("0123456789abcdef"),
2728     hexstr2bin("1234567890abcdef"),
2729     <<"Now is the">>}].
2730
2731des3_cbc(_) ->
2732    [{des3_cbc,
2733     [hexstr2bin("0123456789abcdef"),
2734      hexstr2bin("fedcba9876543210"),
2735      hexstr2bin("0f2d4b6987a5c3e1")],
2736     hexstr2bin("1234567890abcdef"),
2737     <<"Now is the time for all ">>
2738     }].
2739
2740des_ede3(_) ->
2741    [{des_ede3,
2742     [hexstr2bin("8000000000000000"),
2743      hexstr2bin("4000000000000000"),
2744      hexstr2bin("2000000000000000")],
2745      hexstr2bin("7AD16FFB79C45926"),
2746      hexstr2bin("0000000000000000")
2747     }].
2748
2749des_ede3_cbc(_) ->
2750    [{des_ede3_cbc,
2751     [hexstr2bin("0123456789abcdef"),
2752      hexstr2bin("fedcba9876543210"),
2753      hexstr2bin("0f2d4b6987a5c3e1")],
2754     hexstr2bin("1234567890abcdef"),
2755     <<"Now is the time for all ">>
2756     },
2757     {des_ede3_cbc,
2758     [hexstr2bin("8000000000000000"),
2759      hexstr2bin("4000000000000000"),
2760      hexstr2bin("2000000000000000")],
2761      hexstr2bin("7AD16FFB79C45926"),
2762      hexstr2bin("0000000000000000")
2763     }].
2764
2765des3_cbf(_) ->
2766    [{des3_cbf,
2767     [hexstr2bin("0123456789abcdef"),
2768      hexstr2bin("fedcba9876543210"),
2769      hexstr2bin("0f2d4b6987a5c3e1")],
2770     hexstr2bin("1234567890abcdef"),
2771     <<"Now is the time for all ">>
2772     }].
2773
2774des3_cfb(_) ->
2775    [{des3_cfb,
2776     [hexstr2bin("0123456789abcdef"),
2777      hexstr2bin("fedcba9876543210"),
2778      hexstr2bin("0f2d4b6987a5c3e1")],
2779     hexstr2bin("1234567890abcdef"),
2780     <<"Now is the time for all ">>
2781     }].
2782
2783des_ede3_cfb(_) ->
2784    [{des_ede3_cfb,
2785     [hexstr2bin("0123456789abcdef"),
2786      hexstr2bin("fedcba9876543210"),
2787      hexstr2bin("0f2d4b6987a5c3e1")],
2788     hexstr2bin("1234567890abcdef"),
2789     <<"Now is the time for all ">>
2790     }].
2791
2792rc2_cbc(_) ->
2793    [{rc2_cbc,
2794     <<146,210,160,124,215,227,153,239,227,17,222,140,3,93,27,191>>,
2795      <<72,91,135,182,25,42,35,210>>,
2796     <<36,245,206,158,168,230,58,69,148,137,32,192,250,41,237,181,181,251, 192,2,175,135,177,171,57,30,111,117,159,149,15,28,88,158,28,81,28,115, 85,219,241,82,117,222,91,85,73,117,164,25,182,52,191,64,123,57,26,19, 211,27,253,31,194,219,231,104,247,240,172,130,119,21,225,154,101,247, 32,216,42,216,133,169,78,22,97,27,227,26,196,224,172,168,17,9,148,55, 203,91,252,40,61,226,236,221,215,160,78,63,13,181,68,57,196,241,185, 207, 116,129,152,237,60,139,247,153,27,146,161,246,222,98,185,222,152, 187,135, 236,86,34,7,110,91,230,173,34,160,242,202,222,121,127,181,140, 101,203,195, 190,88,250,86,147,127,87,72,126,171,16,71,47,110,248,88, 14,29,143,161,152, 129,236,148,22,152,186,208,119,70,8,174,193,203,100, 193,203,200,117,102,242, 134,142,96,125,135,200,217,190,76,117,50,70, 209,186,101,241,200,91,40,193,54, 90,195,38,47,59,197,38,234,86,223,16, 51,253,204,129,20,171,66,21,241,26,135,216, 196,114,110,91,15,53,40, 164,201,136,113,95,247,51,181,208,241,68,168,98,151,36, 155,72,24,57, 42,191,14,125,204,10,167,214,233,138,115,125,234,121,134,227,26,247, 77,200,117,110,117,111,168,156,206,67,159,149,189,173,150,193,91,199, 216,153,22, 189,137,185,89,160,13,131,132,58,109,28,110,246,252,251,14, 232,91,38,52,29,101,188,69,123,50,0,130,178,93,73,239,118,7,77,35,59, 253,10,159,45,86,142,37,78,232,48>>
2797     }].
2798
2799%% AES CBC test vectors from http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf
2800aes_cbc(Config) ->
2801    %% RETIRED aes_*_cbc
2802    read_rsp(Config, aes_cbc,
2803            ["CBCVarTxt128.rsp", "CBCVarKey128.rsp", "CBCGFSbox128.rsp", "CBCKeySbox128.rsp",
2804             "CBCVarTxt192.rsp", "CBCVarKey192.rsp", "CBCGFSbox192.rsp", "CBCKeySbox192.rsp",
2805             "CBCVarTxt256.rsp", "CBCVarKey256.rsp", "CBCGFSbox256.rsp", "CBCKeySbox256.rsp",
2806             "CBCMMT128.rsp", "CBCMMT192.rsp", "CBCMMT256.rsp"
2807            ]).
2808
2809aes_cbc128(Config) ->
2810    %% RETIRED aes_128_cbc
2811    read_rsp(Config, aes_cbc128,
2812             ["CBCVarTxt128.rsp", "CBCVarKey128.rsp", "CBCGFSbox128.rsp", "CBCKeySbox128.rsp",
2813              "CBCMMT128.rsp"]).
2814
2815aes_cbc256(Config) ->
2816    %% RETIRED aes_256_cbc
2817    read_rsp(Config, aes_cbc256,
2818             ["CBCVarTxt256.rsp", "CBCVarKey256.rsp", "CBCGFSbox256.rsp", "CBCKeySbox256.rsp",
2819              "CBCMMT256.rsp"]).
2820
2821aes_128_cbc(Config) ->
2822    read_rsp(Config, aes_128_cbc,
2823             ["CBCVarTxt128.rsp", "CBCVarKey128.rsp", "CBCGFSbox128.rsp", "CBCKeySbox128.rsp",
2824              "CBCMMT128.rsp"]).
2825
2826aes_192_cbc(Config) ->
2827    read_rsp(Config, aes_192_cbc,
2828             ["CBCVarTxt192.rsp", "CBCVarKey192.rsp", "CBCGFSbox192.rsp", "CBCKeySbox192.rsp",
2829              "CBCMMT192.rsp"]).
2830
2831aes_256_cbc(Config) ->
2832    read_rsp(Config, aes_256_cbc,
2833             ["CBCVarTxt256.rsp", "CBCVarKey256.rsp", "CBCGFSbox256.rsp", "CBCKeySbox256.rsp",
2834              "CBCMMT256.rsp"]).
2835
2836aes_ecb(Config) ->
2837    read_rsp(Config, aes_ecb,
2838             ["ECBVarTxt128.rsp", "ECBVarKey128.rsp", "ECBGFSbox128.rsp", "ECBKeySbox128.rsp",
2839              "ECBVarTxt192.rsp", "ECBVarKey192.rsp", "ECBGFSbox192.rsp", "ECBKeySbox192.rsp",
2840              "ECBVarTxt256.rsp", "ECBVarKey256.rsp", "ECBGFSbox256.rsp", "ECBKeySbox256.rsp",
2841              "ECBMMT128.rsp", "ECBMMT192.rsp", "ECBMMT256.rsp"]).
2842
2843aes_128_ecb(Config) ->
2844    read_rsp(Config, aes_128_ecb,
2845             ["ECBVarTxt128.rsp", "ECBVarKey128.rsp", "ECBGFSbox128.rsp", "ECBKeySbox128.rsp",
2846              "ECBMMT128.rsp"]).
2847
2848aes_192_ecb(Config) ->
2849    read_rsp(Config, aes_192_ecb,
2850             ["ECBVarTxt192.rsp", "ECBVarKey192.rsp", "ECBGFSbox192.rsp", "ECBKeySbox192.rsp",
2851              "ECBMMT192.rsp"]).
2852
2853aes_256_ecb(Config) ->
2854    read_rsp(Config, aes_256_ecb,
2855             ["ECBVarTxt256.rsp", "ECBVarKey256.rsp", "ECBGFSbox256.rsp", "ECBKeySbox256.rsp",
2856              "ECBMMT256.rsp"]).
2857
2858aes_cfb8(Config) ->
2859    read_rsp(Config, aes_cfb8,
2860             ["CFB8VarTxt128.rsp", "CFB8VarKey128.rsp", "CFB8GFSbox128.rsp", "CFB8KeySbox128.rsp",
2861              "CFB8VarTxt192.rsp", "CFB8VarKey192.rsp", "CFB8GFSbox192.rsp", "CFB8KeySbox192.rsp",
2862              "CFB8VarTxt256.rsp", "CFB8VarKey256.rsp", "CFB8GFSbox256.rsp", "CFB8KeySbox256.rsp",
2863              "CFB8MMT128.rsp", "CFB8MMT192.rsp", "CFB8MMT256.rsp"]).
2864
2865aes_128_cfb8(Config) ->
2866    read_rsp(Config, aes_128_cfb8,
2867             ["CFB8VarTxt128.rsp", "CFB8VarKey128.rsp", "CFB8GFSbox128.rsp", "CFB8KeySbox128.rsp",
2868              "CFB8MMT128.rsp"]).
2869
2870aes_192_cfb8(Config) ->
2871    read_rsp(Config, aes_192_cfb8,
2872             ["CFB8VarTxt192.rsp", "CFB8VarKey192.rsp", "CFB8GFSbox192.rsp", "CFB8KeySbox192.rsp",
2873              "CFB8MMT192.rsp"]).
2874
2875aes_256_cfb8(Config) ->
2876    read_rsp(Config, aes_256_cfb8,
2877             ["CFB8VarTxt256.rsp", "CFB8VarKey256.rsp", "CFB8GFSbox256.rsp", "CFB8KeySbox256.rsp",
2878              "CFB8MMT256.rsp"]).
2879
2880
2881aes_cfb128(Config) ->
2882    read_rsp(Config, aes_cfb128,
2883             ["CFB128VarTxt128.rsp", "CFB128VarKey128.rsp", "CFB128GFSbox128.rsp", "CFB128KeySbox128.rsp",
2884              "CFB128VarTxt192.rsp", "CFB128VarKey192.rsp", "CFB128GFSbox192.rsp", "CFB128KeySbox192.rsp",
2885              "CFB128VarTxt256.rsp", "CFB128VarKey256.rsp", "CFB128GFSbox256.rsp", "CFB128KeySbox256.rsp",
2886              "CFB128MMT128.rsp", "CFB128MMT192.rsp", "CFB128MMT256.rsp"]).
2887
2888aes_128_cfb128(Config) ->
2889    read_rsp(Config, aes_128_cfb128,
2890             ["CFB128VarTxt128.rsp", "CFB128VarKey128.rsp", "CFB128GFSbox128.rsp", "CFB128KeySbox128.rsp",
2891              "CFB128MMT128.rsp"]).
2892
2893aes_192_cfb128(Config) ->
2894    read_rsp(Config, aes_192_cfb128,
2895             ["CFB128VarTxt192.rsp", "CFB128VarKey192.rsp", "CFB128GFSbox192.rsp", "CFB128KeySbox192.rsp",
2896              "CFB128MMT192.rsp"]).
2897
2898aes_256_cfb128(Config) ->
2899    read_rsp(Config, aes_256_cfb128,
2900             ["CFB128VarTxt256.rsp", "CFB128VarKey256.rsp", "CFB128GFSbox256.rsp", "CFB128KeySbox256.rsp",
2901              "CFB128MMT256.rsp"]).
2902
2903
2904blowfish_cbc(_) ->
2905    [{blowfish_cbc,
2906      hexstr2bin("0123456789ABCDEFF0E1D2C3B4A59687"),
2907      hexstr2bin("FEDCBA9876543210"),
2908      hexstr2bin("37363534333231204E6F77206973207468652074696D6520666F722000000000")
2909     }].
2910
2911blowfish_ecb(_) ->
2912    [
2913     {blowfish_ecb,
2914      hexstr2bin("0000000000000000"),
2915      hexstr2bin("0000000000000000")},
2916     {blowfish_ecb,
2917      hexstr2bin("FFFFFFFFFFFFFFFF"),
2918      hexstr2bin("FFFFFFFFFFFFFFFF")},
2919     {blowfish_ecb,
2920      hexstr2bin("3000000000000000"),
2921      hexstr2bin("1000000000000001")},
2922     {blowfish_ecb,
2923      hexstr2bin("1111111111111111"),
2924      hexstr2bin("1111111111111111")},
2925     {blowfish_ecb,
2926      hexstr2bin("0123456789ABCDEF"),
2927      hexstr2bin("1111111111111111")},
2928     {blowfish_ecb,
2929      hexstr2bin("0000000000000000"),
2930      hexstr2bin("0000000000000000")},
2931     {blowfish_ecb,
2932      hexstr2bin("FEDCBA9876543210"),
2933      hexstr2bin("0123456789ABCDEF")},
2934     {blowfish_ecb,
2935      hexstr2bin("7CA110454A1A6E57"),
2936      hexstr2bin("01A1D6D039776742")},
2937     {blowfish_ecb,
2938      hexstr2bin("0131D9619DC1376E"),
2939      hexstr2bin("5CD54CA83DEF57DA")},
2940     {blowfish_ecb,
2941      hexstr2bin("07A1133E4A0B2686"),
2942      hexstr2bin("0248D43806F67172")},
2943     {blowfish_ecb,
2944      hexstr2bin("3849674C2602319E"),
2945      hexstr2bin("51454B582DDF440A")},
2946     {blowfish_ecb,
2947      hexstr2bin("04B915BA43FEB5B6"),
2948      hexstr2bin("42FD443059577FA2")},
2949     {blowfish_ecb,
2950      hexstr2bin("0113B970FD34F2CE"),
2951      hexstr2bin("059B5E0851CF143A")},
2952     {blowfish_ecb,
2953      hexstr2bin("0170F175468FB5E6"),
2954      hexstr2bin("0756D8E0774761D2")},
2955     {blowfish_ecb,
2956      hexstr2bin("43297FAD38E373FE"),
2957      hexstr2bin("762514B829BF486A")},
2958     {blowfish_ecb,
2959      hexstr2bin("07A7137045DA2A16"),
2960      hexstr2bin("3BDD119049372802")},
2961     {blowfish_ecb,
2962      hexstr2bin("04689104C2FD3B2F"),
2963      hexstr2bin("26955F6835AF609A")},
2964     {blowfish_ecb,
2965      hexstr2bin("37D06BB516CB7546"),
2966      hexstr2bin("164D5E404F275232")},
2967     {blowfish_ecb,
2968      hexstr2bin("1F08260D1AC2465E"),
2969      hexstr2bin("6B056E18759F5CCA")},
2970     {blowfish_ecb,
2971      hexstr2bin("584023641ABA6176"),
2972      hexstr2bin("004BD6EF09176062")},
2973     {blowfish_ecb,
2974      hexstr2bin("025816164629B007"),
2975      hexstr2bin("480D39006EE762F2")},
2976     {blowfish_ecb,
2977      hexstr2bin("49793EBC79B3258F"),
2978      hexstr2bin("437540C8698F3CFA")},
2979     {blowfish_ecb,
2980      hexstr2bin("018310DC409B26D6"),
2981      hexstr2bin("1D9D5C5018F728C2")},
2982     {blowfish_ecb,
2983      hexstr2bin("1C587F1C13924FEF"),
2984      hexstr2bin("305532286D6F295A")},
2985     {blowfish_ecb,
2986      hexstr2bin("0101010101010101"),
2987      hexstr2bin("0123456789ABCDEF")},
2988     {blowfish_ecb,
2989      hexstr2bin("1F1F1F1F0E0E0E0E"),
2990      hexstr2bin("0123456789ABCDEF")},
2991     {blowfish_ecb,
2992      hexstr2bin("E0FEE0FEF1FEF1FE"),
2993      hexstr2bin("0123456789ABCDEF")},
2994     {blowfish_ecb,
2995      hexstr2bin("0000000000000000"),
2996      hexstr2bin("FFFFFFFFFFFFFFFF")},
2997     {blowfish_ecb,
2998      hexstr2bin("FFFFFFFFFFFFFFFF"),
2999      hexstr2bin("0000000000000000")},
3000     {blowfish_ecb,
3001      hexstr2bin("0123456789ABCDEF"),
3002      hexstr2bin("0000000000000000")},
3003     {blowfish_ecb,
3004      hexstr2bin("FEDCBA9876543210"),
3005      hexstr2bin("FFFFFFFFFFFFFFFF")}
3006    ].
3007
3008blowfish_cfb64(_) ->
3009    [{blowfish_cfb64,
3010      hexstr2bin("0123456789ABCDEFF0E1D2C3B4A59687"),
3011      hexstr2bin("FEDCBA9876543210"),
3012      hexstr2bin("37363534333231204E6F77206973207468652074696D6520666F722000")
3013     }].
3014blowfish_ofb64(_) ->
3015    [{blowfish_ofb64,
3016      hexstr2bin("0123456789ABCDEFF0E1D2C3B4A59687"),
3017      hexstr2bin("FEDCBA9876543210"),
3018      hexstr2bin("37363534333231204E6F77206973207468652074696D6520666F722000")
3019     }].
3020
3021rc4(_) ->
3022    [{rc4, <<"apaapa">>, <<"Yo baby yo">>},
3023     {rc4, <<"apaapa">>, list_to_binary(lists:seq(0, 255))},
3024     {rc4, <<"apaapa">>, long_msg()}
3025    ].
3026
3027aes_128_ctr(_) ->
3028    [  %% F.5.3  CTR-AES192.Encrypt
3029       {aes_128_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
3030	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
3031	hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
3032       {aes_128_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
3033	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff00"),
3034	hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
3035       {aes_128_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
3036	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff01"),
3037	hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef") },
3038       {aes_128_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
3039	hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff02"),
3040	hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
3041    ].
3042
3043aes_192_ctr(_) ->
3044    [ %% F.5.3  CTR-AES192.Encrypt
3045      {aes_192_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
3046       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
3047       hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
3048      {aes_192_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
3049       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff00"),
3050       hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
3051      {aes_192_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
3052       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff01"),
3053	hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
3054      {aes_192_ctr, hexstr2bin("8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b"),
3055       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff02"),
3056       hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")}
3057    ].
3058
3059aes_256_ctr(_) ->
3060    [ %% F.5.5  CTR-AES256.Encrypt
3061      {aes_256_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3062       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
3063       hexstr2bin("6bc1bee22e409f96e93d7e117393172a")},
3064      {aes_256_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3065       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff00"),
3066       hexstr2bin("ae2d8a571e03ac9c9eb76fac45af8e51")},
3067      {aes_256_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3068       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff01"),
3069       hexstr2bin("30c81c46a35ce411e5fbc1191a0a52ef")},
3070      {aes_256_ctr, hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3071       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdff02"),
3072       hexstr2bin("f69f2445df4f9b17ad2b417be66c3710")},
3073
3074      {aes_256_ctr,  hexstr2bin("603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4"),
3075       hexstr2bin("f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
3076       long_msg()}
3077    ].
3078
3079
3080aes_gcm(Config) ->
3081    %% RETIRED aes_*_gcm
3082    read_rsp(Config, aes_gcm,
3083             ["gcmDecrypt128.rsp",
3084              "gcmDecrypt192.rsp",
3085              "gcmDecrypt256.rsp",
3086              "gcmEncryptExtIV128.rsp",
3087              "gcmEncryptExtIV192.rsp",
3088              "gcmEncryptExtIV256.rsp"]).
3089
3090aes_128_gcm(Config) ->
3091   read_rsp(Config, aes_128_gcm,
3092            ["gcmDecrypt128.rsp",
3093             "gcmEncryptExtIV128.rsp"]).
3094
3095aes_192_gcm(Config) ->
3096   read_rsp(Config, aes_192_gcm,
3097            ["gcmDecrypt192.rsp",
3098             "gcmEncryptExtIV192.rsp"]).
3099
3100aes_256_gcm(Config) ->
3101   read_rsp(Config, aes_256_gcm,
3102            ["gcmDecrypt256.rsp",
3103             "gcmEncryptExtIV256.rsp"]).
3104
3105
3106aes_ccm(Config) ->
3107    %% RETIRED aes_*_ccm
3108    read_rsp(Config, aes_ccm,
3109             ["VADT128.rsp", "VADT192.rsp", "VADT256.rsp",
3110              "VNT128.rsp",  "VNT192.rsp",  "VNT256.rsp",
3111              "VPT128.rsp",  "VPT192.rsp",  "VPT256.rsp"
3112             ]).
3113
3114aes_128_ccm(Config) ->
3115    read_rsp(Config, aes_128_ccm,
3116            ["VADT128.rsp", "VNT128.rsp", "VPT128.rsp"]).
3117
3118aes_192_ccm(Config) ->
3119   read_rsp(Config, aes_192_ccm,
3120            ["VADT192.rsp", "VNT192.rsp", "VPT192.rsp"]).
3121
3122aes_256_ccm(Config) ->
3123   read_rsp(Config, aes_256_ccm,
3124            ["VADT256.rsp", "VNT256.rsp", "VPT256.rsp"]).
3125
3126
3127
3128%% https://tools.ietf.org/html/rfc7539#appendix-A.5
3129chacha20_poly1305(_) ->
3130    [
3131     {chacha20_poly1305,
3132      hexstr2bin("1c9240a5eb55d38af333888604f6b5f0"                      %% Key
3133			"473917c1402b80099dca5cbc207075c0"),
3134      hexstr2bin("496e7465726e65742d44726166747320"                      %% PlainText
3135      "61726520647261667420646f63756d65"
3136      "6e74732076616c696420666f72206120"
3137      "6d6178696d756d206f6620736978206d"
3138      "6f6e74687320616e64206d6179206265"
3139      "20757064617465642c207265706c6163"
3140      "65642c206f72206f62736f6c65746564"
3141      "206279206f7468657220646f63756d65"
3142      "6e747320617420616e792074696d652e"
3143      "20497420697320696e617070726f7072"
3144      "6961746520746f2075736520496e7465"
3145      "726e65742d4472616674732061732072"
3146      "65666572656e6365206d617465726961"
3147      "6c206f7220746f206369746520746865"
3148      "6d206f74686572207468616e20617320"
3149      "2fe2809c776f726b20696e2070726f67"
3150      "726573732e2fe2809d"),
3151      hexstr2bin("000000000102030405060708"),                            %% Nonce
3152      hexstr2bin("f33388860000000000004e91"),                            %% AAD
3153      hexstr2bin("64a0861575861af460f062c79be643bd"                      %% CipherText
3154      "5e805cfd345cf389f108670ac76c8cb2"
3155      "4c6cfc18755d43eea09ee94e382d26b0"
3156      "bdb7b73c321b0100d4f03b7f355894cf"
3157      "332f830e710b97ce98c8a84abd0b9481"
3158      "14ad176e008d33bd60f982b1ff37c855"
3159      "9797a06ef4f0ef61c186324e2b350638"
3160      "3606907b6a7c02b0f9f6157b53c867e4"
3161      "b9166c767b804d46a59b5216cde7a4e9"
3162      "9040c5a40433225ee282a1b0a06c523e"
3163      "af4534d7f83fa1155b0047718cbc546a"
3164      "0d072b04b3564eea1b422273f548271a"
3165      "0bb2316053fa76991955ebd63159434e"
3166      "cebb4e466dae5a1073a6727627097a10"
3167      "49e617d91d361094fa68f0ff77987130"
3168      "305beaba2eda04df997b714d6c6f2c29"
3169      "a6ad5cb4022b02709b"),
3170      hexstr2bin("eead9d67890cbb22392336fea1851f38"),                    %% CipherTag
3171      no_info
3172      }
3173    ].
3174
3175
3176chacha20(_) ->
3177%%% chacha20 (no mode) test vectors from RFC 7539 A.2
3178    [
3179     %% Test Vector #1:
3180     {chacha20,
3181      hexstr2bin("00000000000000000000000000000000"
3182                 "00000000000000000000000000000000"),                    %% Key
3183      hexstr2bin("00000000" % Initial counter = 0, little-endian
3184                 "000000000000000000000000"),                            %% IV
3185      hexstr2bin("00000000000000000000000000000000"                      %% PlainText
3186                 "00000000000000000000000000000000"
3187                 "00000000000000000000000000000000"
3188                 "00000000000000000000000000000000"),
3189      hexstr2bin("76b8e0ada0f13d90405d6ae55386bd28"                      %% CipherText
3190                 "bdd219b8a08ded1aa836efcc8b770dc7"
3191                 "da41597c5157488d7724e03fb8d84a37"
3192                 "6a43b8f41518a11cc387b669b2ee6586")},
3193     %% Test Vector #2:
3194     {chacha20,
3195      hexstr2bin("00000000000000000000000000000000"
3196                 "00000000000000000000000000000001"),                    %% Key
3197      hexstr2bin("01000000" % Initial counter = 1, little-endian
3198                 "000000000000000000000002"),                            %% IV
3199      hexstr2bin("416e79207375626d697373696f6e2074"                      %% PlainText
3200                 "6f20746865204945544620696e74656e"
3201                 "6465642062792074686520436f6e7472"
3202                 "696275746f7220666f72207075626c69"
3203                 "636174696f6e20617320616c6c206f72"
3204                 "2070617274206f6620616e2049455446"
3205                 "20496e7465726e65742d447261667420"
3206                 "6f722052464320616e6420616e792073"
3207                 "746174656d656e74206d616465207769"
3208                 "7468696e2074686520636f6e74657874"
3209                 "206f6620616e20494554462061637469"
3210                 "7669747920697320636f6e7369646572"
3211                 "656420616e20224945544620436f6e74"
3212                 "7269627574696f6e222e205375636820"
3213                 "73746174656d656e747320696e636c75"
3214                 "6465206f72616c2073746174656d656e"
3215                 "747320696e2049455446207365737369"
3216                 "6f6e732c2061732077656c6c20617320"
3217                 "7772697474656e20616e6420656c6563"
3218                 "74726f6e696320636f6d6d756e696361"
3219                 "74696f6e73206d61646520617420616e"
3220                 "792074696d65206f7220706c6163652c"
3221                 "20776869636820617265206164647265"
3222                 "7373656420746f"),
3223      hexstr2bin("a3fbf07df3fa2fde4f376ca23e827370"                      %% CipherText
3224                 "41605d9f4f4f57bd8cff2c1d4b7955ec"
3225                 "2a97948bd3722915c8f3d337f7d37005"
3226                 "0e9e96d647b7c39f56e031ca5eb6250d"
3227                 "4042e02785ececfa4b4bb5e8ead0440e"
3228                 "20b6e8db09d881a7c6132f420e527950"
3229                 "42bdfa7773d8a9051447b3291ce1411c"
3230                 "680465552aa6c405b7764d5e87bea85a"
3231                 "d00f8449ed8f72d0d662ab052691ca66"
3232                 "424bc86d2df80ea41f43abf937d3259d"
3233                 "c4b2d0dfb48a6c9139ddd7f76966e928"
3234                 "e635553ba76c5c879d7b35d49eb2e62b"
3235                 "0871cdac638939e25e8a1e0ef9d5280f"
3236                 "a8ca328b351c3c765989cbcf3daa8b6c"
3237                 "cc3aaf9f3979c92b3720fc88dc95ed84"
3238                 "a1be059c6499b9fda236e7e818b04b0b"
3239                 "c39c1e876b193bfe5569753f88128cc0"
3240                 "8aaa9b63d1a16f80ef2554d7189c411f"
3241                 "5869ca52c5b83fa36ff216b9c1d30062"
3242                 "bebcfd2dc5bce0911934fda79a86f6e6"
3243                 "98ced759c3ff9b6477338f3da4f9cd85"
3244                 "14ea9982ccafb341b2384dd902f3d1ab"
3245                 "7ac61dd29c6f21ba5b862f3730e37cfd"
3246                 "c4fd806c22f221")},
3247     %%Test Vector #3:
3248     {chacha20,
3249      hexstr2bin("1c9240a5eb55d38af333888604f6b5f0"
3250                 "473917c1402b80099dca5cbc207075c0"),                    %% Key
3251      hexstr2bin("2a000000" % Initial counter = 42 (decimal), little-endian
3252                 "000000000000000000000002"),                            %% IV
3253      hexstr2bin("2754776173206272696c6c69672c2061"                      %% PlainText
3254                 "6e642074686520736c6974687920746f"
3255                 "7665730a446964206779726520616e64"
3256                 "2067696d626c6520696e207468652077"
3257                 "6162653a0a416c6c206d696d73792077"
3258                 "6572652074686520626f726f676f7665"
3259                 "732c0a416e6420746865206d6f6d6520"
3260                 "7261746873206f757467726162652e"),
3261      hexstr2bin("62e6347f95ed87a45ffae7426f27a1df"                      %% CipherText
3262                 "5fb69110044c0d73118effa95b01e5cf"
3263                 "166d3df2d721caf9b21e5fb14c616871"
3264                 "fd84c54f9d65b283196c7fe4f60553eb"
3265                 "f39c6402c42234e32a356b3e764312a6"
3266                 "1a5532055716ead6962568f87d3f3f77"
3267                 "04c6a8d1bcd1bf4d50d6154b6da731b1"
3268                 "87b58dfd728afa36757a797ac188d1")}
3269    ].
3270
3271
3272rsa_plain() ->
3273    <<"7896345786348756234 Hejsan Svejsan, erlang crypto debugger"
3274      "09812312908312378623487263487623412039812 huagasd">>.
3275rsa_public() ->
3276    [65537, 7919488123861148172698919999061127847747888703039837999377650217570191053151807772962118671509138346758471459464133273114654252861270845708312601272799123].
3277rsa_private() ->
3278    rsa_public() ++ [7531712708607620783801185371644749935066152052780368689827275932079815492940396744378735701395659435842364793962992309884847527234216715366607660219930945].
3279
3280rsa_public_stronger() ->
3281    [65537, 24629450921918866883077380602720734920775458960049554761386137065662137652635369332143446151320538248280934442179850504891395344346514465469955766163141133564033962851182759993807898821114734943339732032639891483186089941567854227407119560631150779000222837755424893038740314247760600374970909894211201220612920040986106639419467243909950276018045907029941478599124238353052062083560294570722081552510960894164859765695309596889747541376908786225647625736062865138957717982693312699025417086612046330464651009693307624955796202070510577399561730651967517158452930742355327167632521808183383868100102455048819375344881].
3282
3283rsa_private_stronger() ->
3284    rsa_public_stronger() ++ [13565232776562604620467234237694854016819673873109064019820773052201665024482754648718278717031083946624786145611240731564761987114634269887293030432042088547345315212418830656522115993209293567218379960177754901461542373481136856927955012596579314262051109321754382091434920473734937991286600905464814063189230779981494358415076362038786197620360127262110530926733754185204773610295221669711309000953136320804528874719105049753061737780710448207922456570922652651354760939379096788728229638142403068102990416717272880560951246813789730402978652924934794503277969128609831043469924881848849409122972426787999886557185].
3285
3286dss_plain() ->
3287    rsa_plain().
3288dss_public() ->
3289    25854665488880835237281628794585130313500176551981812527054397586638455298000483144002221850980183404910190346416063318160497344811383498859129095184158800144312512447497510551471331451396405348497845813002058423110442376886564659959543650802132345311573634832461635601376738282831340827591903548964194832978.
3290dss_private() ->
3291    441502407453038284293378221372000880210588566361.
3292dss_params() ->
3293    [109799869232806890760655301608454668257695818999841877165019612946154359052535682480084145133201304812979481136659521529774182959764860329095546511521488413513097576425638476458000255392402120367876345280670101492199681798674053929238558140260669578407351853803102625390950534052428162468100618240968893110797,
3294     1349199015905534965792122312016505075413456283393,
3295     18320614775012672475365915366944922415598782131828709277168615511695849821411624805195787607930033958243224786899641459701930253094446221381818858674389863050420226114787005820357372837321561754462061849169568607689530279303056075793886577588606958623645901271866346406773590024901668622321064384483571751669].
3296
3297ec_key_named() ->
3298    Curve = hd(crypto:ec_curves()),
3299    {D2_pub, D2_priv} = crypto:generate_key(ecdh, Curve),
3300    {[D2_priv, Curve], [D2_pub, Curve]}.
3301
3302ec_msg() ->
3303    <<99,234,6,64,190,237,201,99,80,248,58,40,70,45,149,218,5,246,242,63>>.
3304
3305srp3() ->
3306    Username = <<"alice">>,
3307    Password = <<"password123">>,
3308    Salt = hexstr2bin("2857827A19266A1F2BC6"),
3309    Prime = hexstr2bin("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
3310		       "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
3311		       "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
3312		       "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
3313		       "FD5138FE8376435B9FC61D2FC0EB06E3"),
3314    Generator = <<2>>,
3315    Version = '3',
3316    Scrambler = hexstr2bin("02E2476A"),
3317
3318    %% X = hexstr2bin("96E54AB0CD4C5123EDCFA4A1502918AAD3C9E2A8"),
3319    Verifier = hexstr2bin("96EB5F13621D911AA1CA405DE9C64217D4108EEEECAFFE500034FE0E"
3320			  "C031E42C8714667C161BCE0E7996F7DDE1B63824C130D2D7286C08C0"
3321			  "49758420735961347112AE102A3F23B3F687F8FEE0DF2BFAF933C608"
3322			  "D6FE5B5EEE3116FE54016E065BF8E8C9FDBBC08719231AC215149140"
3323			  "519E8FDD9AA4F410C28A58AF42974D2D"),
3324    ClientPrivate = hexstr2bin("6411DE75538BED8170677D577D0608F39112BC95B503C447EB6AC945"
3325			  "49C75C7B"),
3326    ServerPrivate = hexstr2bin("85E44A6F694DBE676145DB245A045CD37C99F05C562C7840A31F270D"
3327			  "9AADCF8B"),
3328    ClientPublic = hexstr2bin("B22B1FFA2244B8CB94F3A9080F419CAEAB0DBA93EA1965B5E84587EE"
3329			 "55C79E7A118865DC59B9D0353362C2A8261E7C1B0D221A0E233C2AD1"
3330			 "640DACBB8664CBC9733EAC392DA7800142860380C3FC573C3C064329"
3331			 "CF54063FD114C7210E9CB3A611EA8002B1844B698F930D95D143899B"
3332			 "948A090E0C25938E5F84067D1883DC63"),
3333    ServerPublic = hexstr2bin("93A8C4D8B7F7395ADCFD4ABA37B015124513D3F37B3E85EB23064BE5"
3334			 "F53C0AE32FFB9D8C0AA0DCFFA74D632DD67DEBB5C35AAE9812286CC8"
3335			 "C43CC176ECBC6D3F447594D9554E995B2509127BF88FADDDA4982D03"
3336			 "8EC3001320712D3B1269308CE70F319B2295FA57674F03A2D993CFB1"
3337			 "F84C35B7D0C012FA73CD4C8F7D5A71C7"),
3338
3339    SessionKey = hexstr2bin("C29A986C4D521BBC66428ED11D994CD7431574A6184B83CDCC345092"
3340			    "791E75748A1D38CAC4BD14760F0D2694B711236419240FF2F172454C"
3341			    "46ABF4FF39498DAFDD2C82924F7D7BD76CDFCE688C77D93F18A65409"
3342			    "9176A9192615DC0277AE7C12F1F6A7F6563FCA11675D809AF578BDE5"
3343			    "2B51E05D440B63099A017A0B45044801"),
3344    UserPassHash = crypto:hash(sha, [Salt, crypto:hash(sha, [Username, <<$:>>, Password])]),
3345    Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
3346    ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
3347    srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPrivate, UserPassHash, Scrambler, SessionKey).
3348
3349srp6() ->
3350    Username = <<"alice">>,
3351    Password = <<"password123">>,
3352    Salt = hexstr2bin("2857827A19266A1F2BC6"),
3353    Prime = hexstr2bin("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
3354		       "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
3355		       "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
3356		       "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
3357		       "FD5138FE8376435B9FC61D2FC0EB06E3"),
3358    Generator = <<2>>,
3359    Version = '6',
3360    Scrambler = hexstr2bin("0A2534C0BF52A0DA9001EEC62CF2A546AB0908A7"),
3361    Verifier = hexstr2bin("96EB5F13621D911AA1CA405DE9C64217D4108EEEECAFFE500034FE0E"
3362			  "C031E42C8714667C161BCE0E7996F7DDE1B63824C130D2D7286C08C0"
3363			  "49758420735961347112AE102A3F23B3F687F8FEE0DF2BFAF933C608"
3364			  "D6FE5B5EEE3116FE54016E065BF8E8C9FDBBC08719231AC215149140"
3365			  "519E8FDD9AA4F410C28A58AF42974D2D"),
3366    ClientPrivate = hexstr2bin("6411DE75538BED8170677D577D0608F39112BC95B503C447EB6AC945"
3367			  "49C75C7B"),
3368    ServerPrivate = hexstr2bin("85E44A6F694DBE676145DB245A045CD37C99F05C562C7840A31F270D"
3369			  "9AADCF8B"),
3370    ClientPublic = hexstr2bin("B22B1FFA2244B8CB94F3A9080F419CAEAB0DBA93EA1965B5E84587EE"
3371			 "55C79E7A118865DC59B9D0353362C2A8261E7C1B0D221A0E233C2AD1"
3372			 "640DACBB8664CBC9733EAC392DA7800142860380C3FC573C3C064329"
3373			 "CF54063FD114C7210E9CB3A611EA8002B1844B698F930D95D143899B"
3374			 "948A090E0C25938E5F84067D1883DC63"),
3375    ServerPublic = hexstr2bin("D2D07845CE7ECDB9845DD36B10ACD3598CC29049DE9F467F84CE16B6"
3376			 "D97A6DC567AF8B0F9FEDF74962400AD5C357951E64E67B641246F264"
3377			 "C8DE6D9A72E554D6C8D3194548780A0C438A0FCC509CA88A14AA1DEB"
3378			 "C0F09E4B37A965D1545DB4AD361346F3189B0EA569C06D326C4E4797"
3379			 "9E381C748293B7C0591BE0BE419E053E"),
3380
3381    SessionKey = hexstr2bin("19D22C19612874EBF1F2581F8EFCFDC44C6FDA3B87B0A73823D7E962"
3382				 "554295D4E48D3A336523ADBDDD0EC8FB0F02687109E97E01C17C93CC"
3383				 "7216F9CD8A4AC39F0429857D8D1023066614BDFCBCB89F59A0FEB81C"
3384				 "72E992AAD89095A84B6A5FADA152369AB1E350A03693BEF044DF3EDF"
3385				 "0C34741F4696C30E9F675D09F58ACBEB"),
3386    UserPassHash = crypto:hash(sha, [Salt, crypto:hash(sha, [Username, <<$:>>, Password])]),
3387    Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
3388    ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
3389    srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPrivate, UserPassHash, Scrambler, SessionKey).
3390
3391
3392srp6a_smaller_prime() ->
3393    Username = <<"alice">>,
3394    Password = <<"password123">>,
3395    Salt = <<"mystrongsalt">>,
3396    Prime = hexstr2bin("894B645E89E1535BBDAD5B8B290650530801B18EBFBF5E8FAB3C82872A3E9BB7"),
3397    Generator = <<7>>,
3398    Version = '6a',
3399    Scrambler = hexstr2bin("18DE4A002AD05EF464B19AE2B6929F9B1319C7AA"),
3400    Verifier = hexstr2bin("867401D5DE10964768184EAF246B322760C847604075FA66A4423907"
3401			  "8428BCA5"),
3402    ClientPrivate = hexstr2bin("C49F832EE8D67ECF9E7F2785EB0622D8B3FE2344C00F96E1AEF4103C"
3403			  "A44D51F9"),
3404    ServerPrivate = hexstr2bin("6C78CCEAAEC15E69068A87795B2A20ED7B45CFC5A254EBE2F17F144A"
3405			  "4D99DB18"),
3406    ClientPublic = hexstr2bin("2452A57166BBBF690DB77539BAF9C57CD1ED99D5AA15ED925AD9B5C3"
3407			  "64BBEDFF"),
3408    ServerPublic = hexstr2bin("2C0464DE84B91E4963A3546CAC0EFE55F31F49208C3F0AD7EE55F444"
3409			  "8F38BA7F"),
3410
3411    SessionKey = hexstr2bin("65581B2302580BD26F522A5A421CF969B9CCBCE4051196B034A2A9D22065D848"),
3412    UserPassHash = crypto:hash(sha, [Salt, crypto:hash(sha, [Username, <<$:>>, Password])]),
3413    Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
3414    ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
3415    srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPrivate, UserPassHash, Scrambler, SessionKey).
3416
3417srp6a() ->
3418    Username = <<"alice">>,
3419    Password = <<"password123">>,
3420    Salt = hexstr2bin("BEB25379D1A8581EB5A727673A2441EE"),
3421    Prime = hexstr2bin("EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C"
3422		       "9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE4"
3423		       "8E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B29"
3424		       "7BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9A"
3425		       "FD5138FE8376435B9FC61D2FC0EB06E3"),
3426    Generator = <<2>>,
3427    Version = '6a',
3428    Scrambler = hexstr2bin("CE38B9593487DA98554ED47D70A7AE5F462EF019"),
3429    Verifier = hexstr2bin("7E273DE8696FFC4F4E337D05B4B375BEB0DDE1569E8FA00A9886D812"
3430			  "9BADA1F1822223CA1A605B530E379BA4729FDC59F105B4787E5186F5"
3431			  "C671085A1447B52A48CF1970B4FB6F8400BBF4CEBFBB168152E08AB5"
3432			  "EA53D15C1AFF87B2B9DA6E04E058AD51CC72BFC9033B564E26480D78"
3433			  "E955A5E29E7AB245DB2BE315E2099AFB"),
3434    ClientPrivate = hexstr2bin("60975527035CF2AD1989806F0407210BC81EDC04E2762A56AFD529DD"
3435			  "DA2D4393"),
3436    ServerPrivate = hexstr2bin("E487CB59D31AC550471E81F00F6928E01DDA08E974A004F49E61F5D1"
3437			  "05284D20"),
3438    ClientPublic = hexstr2bin("61D5E490F6F1B79547B0704C436F523DD0E560F0C64115BB72557EC4"
3439			      "4352E8903211C04692272D8B2D1A5358A2CF1B6E0BFCF99F921530EC"
3440			      "8E39356179EAE45E42BA92AEACED825171E1E8B9AF6D9C03E1327F44"
3441			      "BE087EF06530E69F66615261EEF54073CA11CF5858F0EDFDFE15EFEA"
3442			      "B349EF5D76988A3672FAC47B0769447B"),
3443    ServerPublic = hexstr2bin("BD0C61512C692C0CB6D041FA01BB152D4916A1E77AF46AE105393011"
3444			      "BAF38964DC46A0670DD125B95A981652236F99D9B681CBF87837EC99"
3445			      "6C6DA04453728610D0C6DDB58B318885D7D82C7F8DEB75CE7BD4FBAA"
3446			      "37089E6F9C6059F388838E7A00030B331EB76840910440B1B27AAEAE"
3447			      "EB4012B7D7665238A8E3FB004B117B58"),
3448
3449    SessionKey = hexstr2bin("B0DC82BABCF30674AE450C0287745E7990A3381F63B387AAF271A10D"
3450			    "233861E359B48220F7C4693C9AE12B0A6F67809F0876E2D013800D6C"
3451			    "41BB59B6D5979B5C00A172B4A2A5903A0BDCAF8A709585EB2AFAFA8F"
3452			    "3499B200210DCC1F10EB33943CD67FC88A2F39A4BE5BEC4EC0A3212D"
3453			    "C346D7E474B29EDE8A469FFECA686E5A"),
3454    UserPassHash = crypto:hash(sha, [Salt, crypto:hash(sha, [Username, <<$:>>, Password])]),
3455    Verifier = crypto:mod_pow(Generator, UserPassHash, Prime),
3456    ClientPublic = crypto:mod_pow(Generator, ClientPrivate, Prime),
3457    srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPrivate, UserPassHash, Scrambler, SessionKey).
3458
3459srp(ClientPrivate, Generator, Prime, Version, Verifier, ServerPublic, ServerPrivate, UserPassHash, Scrambler, SessionKey)->
3460    {srp, ClientPrivate,
3461     {user, [Generator, Prime, Version]}, {user, [UserPassHash, Prime, Generator, Version, Scrambler]},
3462     ServerPublic, ServerPrivate, {host, [Verifier, Generator, Prime, Version]},
3463     {host, [Verifier, Prime, Version, Scrambler]},
3464     SessionKey}.
3465
3466eddsa(ed25519) ->
3467    %% https://tools.ietf.org/html/rfc8032#section-7.1
3468    %% {ALGORITHM, (SHA), SECRET KEY, PUBLIC KEY,  MESSAGE, SIGNATURE}
3469    [
3470     %% TEST 1
3471     {ed25519, undefined,
3472      hexstr2bin("9d61b19deffd5a60ba844af492ec2cc4"
3473                 "4449c5697b326919703bac031cae7f60"),
3474      hexstr2bin("d75a980182b10ab7d54bfed3c964073a"
3475                 "0ee172f3daa62325af021a68f707511a"),
3476      hexstr2bin(""),
3477      hexstr2bin("e5564300c360ac729086e2cc806e828a"
3478                 "84877f1eb8e5d974d873e06522490155"
3479                 "5fb8821590a33bacc61e39701cf9b46b"
3480                 "d25bf5f0595bbe24655141438e7a100b")},
3481     %% TEST 2
3482     {ed25519, undefined,
3483      hexstr2bin("4ccd089b28ff96da9db6c346ec114e0f"
3484                 "5b8a319f35aba624da8cf6ed4fb8a6fb"),
3485      hexstr2bin("3d4017c3e843895a92b70aa74d1b7ebc"
3486                 "9c982ccf2ec4968cc0cd55f12af4660c"),
3487      hexstr2bin("72"),
3488      hexstr2bin("92a009a9f0d4cab8720e820b5f642540"
3489                 "a2b27b5416503f8fb3762223ebdb69da"
3490                 "085ac1e43e15996e458f3613d0f11d8c"
3491                 "387b2eaeb4302aeeb00d291612bb0c00")},
3492     %% TEST 3
3493     {ed25519, undefined,
3494      hexstr2bin("c5aa8df43f9f837bedb7442f31dcb7b1"
3495                 "66d38535076f094b85ce3a2e0b4458f7"),
3496      hexstr2bin("fc51cd8e6218a1a38da47ed00230f058"
3497                 "0816ed13ba3303ac5deb911548908025"),
3498      hexstr2bin("af82"),
3499      hexstr2bin("6291d657deec24024827e69c3abe01a3"
3500                 "0ce548a284743a445e3680d7db5ac3ac"
3501                 "18ff9b538d16f290ae67f760984dc659"
3502                 "4a7c15e9716ed28dc027beceea1ec40a")},
3503     %% TEST 1024
3504     {ed25519, undefined,
3505      hexstr2bin("f5e5767cf153319517630f226876b86c"
3506                 "8160cc583bc013744c6bf255f5cc0ee5"),
3507      hexstr2bin("278117fc144c72340f67d0f2316e8386"
3508                 "ceffbf2b2428c9c51fef7c597f1d426e"),
3509      hexstr2bin("08b8b2b733424243760fe426a4b54908"
3510                 "632110a66c2f6591eabd3345e3e4eb98"
3511                 "fa6e264bf09efe12ee50f8f54e9f77b1"
3512                 "e355f6c50544e23fb1433ddf73be84d8"
3513                 "79de7c0046dc4996d9e773f4bc9efe57"
3514                 "38829adb26c81b37c93a1b270b20329d"
3515                 "658675fc6ea534e0810a4432826bf58c"
3516                 "941efb65d57a338bbd2e26640f89ffbc"
3517                 "1a858efcb8550ee3a5e1998bd177e93a"
3518                 "7363c344fe6b199ee5d02e82d522c4fe"
3519                 "ba15452f80288a821a579116ec6dad2b"
3520                 "3b310da903401aa62100ab5d1a36553e"
3521                 "06203b33890cc9b832f79ef80560ccb9"
3522                 "a39ce767967ed628c6ad573cb116dbef"
3523                 "efd75499da96bd68a8a97b928a8bbc10"
3524                 "3b6621fcde2beca1231d206be6cd9ec7"
3525                 "aff6f6c94fcd7204ed3455c68c83f4a4"
3526                 "1da4af2b74ef5c53f1d8ac70bdcb7ed1"
3527                 "85ce81bd84359d44254d95629e9855a9"
3528                 "4a7c1958d1f8ada5d0532ed8a5aa3fb2"
3529                 "d17ba70eb6248e594e1a2297acbbb39d"
3530                 "502f1a8c6eb6f1ce22b3de1a1f40cc24"
3531                 "554119a831a9aad6079cad88425de6bd"
3532                 "e1a9187ebb6092cf67bf2b13fd65f270"
3533                 "88d78b7e883c8759d2c4f5c65adb7553"
3534                 "878ad575f9fad878e80a0c9ba63bcbcc"
3535                 "2732e69485bbc9c90bfbd62481d9089b"
3536                 "eccf80cfe2df16a2cf65bd92dd597b07"
3537                 "07e0917af48bbb75fed413d238f5555a"
3538                 "7a569d80c3414a8d0859dc65a46128ba"
3539                 "b27af87a71314f318c782b23ebfe808b"
3540                 "82b0ce26401d2e22f04d83d1255dc51a"
3541                 "ddd3b75a2b1ae0784504df543af8969b"
3542                 "e3ea7082ff7fc9888c144da2af58429e"
3543                 "c96031dbcad3dad9af0dcbaaaf268cb8"
3544                 "fcffead94f3c7ca495e056a9b47acdb7"
3545                 "51fb73e666c6c655ade8297297d07ad1"
3546                 "ba5e43f1bca32301651339e22904cc8c"
3547                 "42f58c30c04aafdb038dda0847dd988d"
3548                 "cda6f3bfd15c4b4c4525004aa06eeff8"
3549                 "ca61783aacec57fb3d1f92b0fe2fd1a8"
3550                 "5f6724517b65e614ad6808d6f6ee34df"
3551                 "f7310fdc82aebfd904b01e1dc54b2927"
3552                 "094b2db68d6f903b68401adebf5a7e08"
3553                 "d78ff4ef5d63653a65040cf9bfd4aca7"
3554                 "984a74d37145986780fc0b16ac451649"
3555                 "de6188a7dbdf191f64b5fc5e2ab47b57"
3556                 "f7f7276cd419c17a3ca8e1b939ae49e4"
3557                 "88acba6b965610b5480109c8b17b80e1"
3558                 "b7b750dfc7598d5d5011fd2dcc5600a3"
3559                 "2ef5b52a1ecc820e308aa342721aac09"
3560                 "43bf6686b64b2579376504ccc493d97e"
3561                 "6aed3fb0f9cd71a43dd497f01f17c0e2"
3562                 "cb3797aa2a2f256656168e6c496afc5f"
3563                 "b93246f6b1116398a346f1a641f3b041"
3564                 "e989f7914f90cc2c7fff357876e506b5"
3565                 "0d334ba77c225bc307ba537152f3f161"
3566                 "0e4eafe595f6d9d90d11faa933a15ef1"
3567                 "369546868a7f3a45a96768d40fd9d034"
3568                 "12c091c6315cf4fde7cb68606937380d"
3569                 "b2eaaa707b4c4185c32eddcdd306705e"
3570                 "4dc1ffc872eeee475a64dfac86aba41c"
3571                 "0618983f8741c5ef68d3a101e8a3b8ca"
3572                 "c60c905c15fc910840b94c00a0b9d0"),
3573      hexstr2bin("0aab4c900501b3e24d7cdf4663326a3a"
3574                 "87df5e4843b2cbdb67cbf6e460fec350"
3575                 "aa5371b1508f9f4528ecea23c436d94b"
3576                 "5e8fcd4f681e30a6ac00a9704a188a03")},
3577     %% TEST SHA(abc)
3578     {ed25519, undefined,
3579      hexstr2bin("833fe62409237b9d62ec77587520911e"
3580                 "9a759cec1d19755b7da901b96dca3d42"),
3581      hexstr2bin("ec172b93ad5e563bf4932c70e1245034"
3582                 "c35467ef2efd4d64ebf819683467e2bf"),
3583      hexstr2bin("ddaf35a193617abacc417349ae204131"
3584                 "12e6fa4e89a97ea20a9eeee64b55d39a"
3585                 "2192992a274fc1a836ba3c23a3feebbd"
3586                 "454d4423643ce80e2a9ac94fa54ca49f"),
3587      hexstr2bin("dc2a4459e7369633a52b1bf277839a00"
3588                 "201009a3efbf3ecb69bea2186c26b589"
3589                 "09351fc9ac90b3ecfdfbc7c66431e030"
3590                 "3dca179c138ac17ad9bef1177331a704")}
3591    ];
3592
3593eddsa(ed448) ->
3594    %% https://tools.ietf.org/html/rfc8032#section-7.4
3595    [{ed448, undefined,
3596      hexstr2bin("6c82a562cb808d10d632be89c8513ebf"
3597                 "6c929f34ddfa8c9f63c9960ef6e348a3"
3598                 "528c8a3fcc2f044e39a3fc5b94492f8f"
3599                 "032e7549a20098f95b"),
3600      hexstr2bin("5fd7449b59b461fd2ce787ec616ad46a"
3601                 "1da1342485a70e1f8a0ea75d80e96778"
3602                 "edf124769b46c7061bd6783df1e50f6c"
3603                 "d1fa1abeafe8256180"),
3604      hexstr2bin(""),
3605      hexstr2bin("533a37f6bbe457251f023c0d88f976ae"
3606                 "2dfb504a843e34d2074fd823d41a591f"
3607                 "2b233f034f628281f2fd7a22ddd47d78"
3608                 "28c59bd0a21bfd3980ff0d2028d4b18a"
3609                 "9df63e006c5d1c2d345b925d8dc00b41"
3610                 "04852db99ac5c7cdda8530a113a0f4db"
3611                 "b61149f05a7363268c71d95808ff2e65"
3612                 "2600")},
3613     %% 1 octet
3614     {ed448, undefined,
3615      hexstr2bin("c4eab05d357007c632f3dbb48489924d"
3616                 "552b08fe0c353a0d4a1f00acda2c463a"
3617                 "fbea67c5e8d2877c5e3bc397a659949e"
3618                 "f8021e954e0a12274e"),
3619      hexstr2bin("43ba28f430cdff456ae531545f7ecd0a"
3620                 "c834a55d9358c0372bfa0c6c6798c086"
3621                 "6aea01eb00742802b8438ea4cb82169c"
3622                 "235160627b4c3a9480"),
3623      hexstr2bin("03"),
3624      hexstr2bin("26b8f91727bd62897af15e41eb43c377"
3625                 "efb9c610d48f2335cb0bd0087810f435"
3626                 "2541b143c4b981b7e18f62de8ccdf633"
3627                 "fc1bf037ab7cd779805e0dbcc0aae1cb"
3628                 "cee1afb2e027df36bc04dcecbf154336"
3629                 "c19f0af7e0a6472905e799f1953d2a0f"
3630                 "f3348ab21aa4adafd1d234441cf807c0"
3631                 "3a00")},
3632
3633     %% %% 1 octet (with context)
3634     %% {ed448, undefined,
3635     %%  hexstr2bin("c4eab05d357007c632f3dbb48489924d"
3636     %%             "552b08fe0c353a0d4a1f00acda2c463a"
3637     %%             "fbea67c5e8d2877c5e3bc397a659949e"
3638     %%             "f8021e954e0a12274e"),
3639     %%  hexstr2bin("43ba28f430cdff456ae531545f7ecd0a"
3640     %%             "c834a55d9358c0372bfa0c6c6798c086"
3641     %%             "6aea01eb00742802b8438ea4cb82169c"
3642     %%             "235160627b4c3a9480"),
3643     %%  hexstr2bin("03"),
3644     %%  hexstr2bin("666f6f"), % Context
3645     %%  hexstr2bin("d4f8f6131770dd46f40867d6fd5d5055"
3646     %%             "de43541f8c5e35abbcd001b32a89f7d2"
3647     %%             "151f7647f11d8ca2ae279fb842d60721"
3648     %%             "7fce6e042f6815ea000c85741de5c8da"
3649     %%             "1144a6a1aba7f96de42505d7a7298524"
3650     %%             "fda538fccbbb754f578c1cad10d54d0d"
3651     %%             "5428407e85dcbc98a49155c13764e66c"
3652     %%             "3c00")},
3653
3654     %% 11 octets
3655     {ed448, undefined,
3656      hexstr2bin("cd23d24f714274e744343237b93290f5"
3657                 "11f6425f98e64459ff203e8985083ffd"
3658                 "f60500553abc0e05cd02184bdb89c4cc"
3659                 "d67e187951267eb328"),
3660      hexstr2bin("dcea9e78f35a1bf3499a831b10b86c90"
3661                 "aac01cd84b67a0109b55a36e9328b1e3"
3662                 "65fce161d71ce7131a543ea4cb5f7e9f"
3663                 "1d8b00696447001400"),
3664      hexstr2bin("0c3e544074ec63b0265e0c"),
3665      hexstr2bin("1f0a8888ce25e8d458a21130879b840a"
3666                 "9089d999aaba039eaf3e3afa090a09d3"
3667                 "89dba82c4ff2ae8ac5cdfb7c55e94d5d"
3668                 "961a29fe0109941e00b8dbdeea6d3b05"
3669                 "1068df7254c0cdc129cbe62db2dc957d"
3670                 "bb47b51fd3f213fb8698f064774250a5"
3671                 "028961c9bf8ffd973fe5d5c206492b14"
3672                 "0e00")},
3673     %% 12 octets
3674     {ed448, undefined,
3675      hexstr2bin("258cdd4ada32ed9c9ff54e63756ae582"
3676                 "fb8fab2ac721f2c8e676a72768513d93"
3677                 "9f63dddb55609133f29adf86ec9929dc"
3678                 "cb52c1c5fd2ff7e21b"),
3679      hexstr2bin("3ba16da0c6f2cc1f30187740756f5e79"
3680                 "8d6bc5fc015d7c63cc9510ee3fd44adc"
3681                 "24d8e968b6e46e6f94d19b945361726b"
3682                 "d75e149ef09817f580"),
3683      hexstr2bin("64a65f3cdedcdd66811e2915"),
3684      hexstr2bin("7eeeab7c4e50fb799b418ee5e3197ff6"
3685                 "bf15d43a14c34389b59dd1a7b1b85b4a"
3686                 "e90438aca634bea45e3a2695f1270f07"
3687                 "fdcdf7c62b8efeaf00b45c2c96ba457e"
3688                 "b1a8bf075a3db28e5c24f6b923ed4ad7"
3689                 "47c3c9e03c7079efb87cb110d3a99861"
3690                 "e72003cbae6d6b8b827e4e6c143064ff"
3691                 "3c00")},
3692     %% 13 octets
3693     {ed448, undefined,
3694      hexstr2bin("7ef4e84544236752fbb56b8f31a23a10"
3695                 "e42814f5f55ca037cdcc11c64c9a3b29"
3696                 "49c1bb60700314611732a6c2fea98eeb"
3697                 "c0266a11a93970100e"),
3698      hexstr2bin("b3da079b0aa493a5772029f0467baebe"
3699                 "e5a8112d9d3a22532361da294f7bb381"
3700                 "5c5dc59e176b4d9f381ca0938e13c6c0"
3701                 "7b174be65dfa578e80"),
3702      hexstr2bin("64a65f3cdedcdd66811e2915e7"),
3703      hexstr2bin("6a12066f55331b6c22acd5d5bfc5d712"
3704                 "28fbda80ae8dec26bdd306743c5027cb"
3705                 "4890810c162c027468675ecf645a8317"
3706                 "6c0d7323a2ccde2d80efe5a1268e8aca"
3707                 "1d6fbc194d3f77c44986eb4ab4177919"
3708                 "ad8bec33eb47bbb5fc6e28196fd1caf5"
3709                 "6b4e7e0ba5519234d047155ac727a105"
3710                 "3100")},
3711     %% 64 octets
3712     {ed448, undefined,
3713      hexstr2bin("d65df341ad13e008567688baedda8e9d"
3714                 "cdc17dc024974ea5b4227b6530e339bf"
3715                 "f21f99e68ca6968f3cca6dfe0fb9f4fa"
3716                 "b4fa135d5542ea3f01"),
3717      hexstr2bin("df9705f58edbab802c7f8363cfe5560a"
3718                 "b1c6132c20a9f1dd163483a26f8ac53a"
3719                 "39d6808bf4a1dfbd261b099bb03b3fb5"
3720                 "0906cb28bd8a081f00"),
3721      hexstr2bin("bd0f6a3747cd561bdddf4640a332461a"
3722                 "4a30a12a434cd0bf40d766d9c6d458e5"
3723                 "512204a30c17d1f50b5079631f64eb31"
3724                 "12182da3005835461113718d1a5ef944"),
3725      hexstr2bin("554bc2480860b49eab8532d2a533b7d5"
3726                 "78ef473eeb58c98bb2d0e1ce488a98b1"
3727                 "8dfde9b9b90775e67f47d4a1c3482058"
3728                 "efc9f40d2ca033a0801b63d45b3b722e"
3729                 "f552bad3b4ccb667da350192b61c508c"
3730                 "f7b6b5adadc2c8d9a446ef003fb05cba"
3731                 "5f30e88e36ec2703b349ca229c267083"
3732                 "3900")},
3733     %% 256 octets
3734     {ed448, undefined,
3735      hexstr2bin("2ec5fe3c17045abdb136a5e6a913e32a"
3736                 "b75ae68b53d2fc149b77e504132d3756"
3737                 "9b7e766ba74a19bd6162343a21c8590a"
3738                 "a9cebca9014c636df5"),
3739      hexstr2bin("79756f014dcfe2079f5dd9e718be4171"
3740                 "e2ef2486a08f25186f6bff43a9936b9b"
3741                 "fe12402b08ae65798a3d81e22e9ec80e"
3742                 "7690862ef3d4ed3a00"),
3743      hexstr2bin("15777532b0bdd0d1389f636c5f6b9ba7"
3744                 "34c90af572877e2d272dd078aa1e567c"
3745                 "fa80e12928bb542330e8409f31745041"
3746                 "07ecd5efac61ae7504dabe2a602ede89"
3747                 "e5cca6257a7c77e27a702b3ae39fc769"
3748                 "fc54f2395ae6a1178cab4738e543072f"
3749                 "c1c177fe71e92e25bf03e4ecb72f47b6"
3750                 "4d0465aaea4c7fad372536c8ba516a60"
3751                 "39c3c2a39f0e4d832be432dfa9a706a6"
3752                 "e5c7e19f397964ca4258002f7c0541b5"
3753                 "90316dbc5622b6b2a6fe7a4abffd9610"
3754                 "5eca76ea7b98816af0748c10df048ce0"
3755                 "12d901015a51f189f3888145c03650aa"
3756                 "23ce894c3bd889e030d565071c59f409"
3757                 "a9981b51878fd6fc110624dcbcde0bf7"
3758                 "a69ccce38fabdf86f3bef6044819de11"),
3759      hexstr2bin("c650ddbb0601c19ca11439e1640dd931"
3760                 "f43c518ea5bea70d3dcde5f4191fe53f"
3761                 "00cf966546b72bcc7d58be2b9badef28"
3762                 "743954e3a44a23f880e8d4f1cfce2d7a"
3763                 "61452d26da05896f0a50da66a239a8a1"
3764                 "88b6d825b3305ad77b73fbac0836ecc6"
3765                 "0987fd08527c1a8e80d5823e65cafe2a"
3766                 "3d00")},
3767     %% 1023 octets
3768     {ed448, undefined,
3769      hexstr2bin("872d093780f5d3730df7c212664b37b8"
3770                 "a0f24f56810daa8382cd4fa3f77634ec"
3771                 "44dc54f1c2ed9bea86fafb7632d8be19"
3772                 "9ea165f5ad55dd9ce8"),
3773      hexstr2bin("a81b2e8a70a5ac94ffdbcc9badfc3feb"
3774                 "0801f258578bb114ad44ece1ec0e799d"
3775                 "a08effb81c5d685c0c56f64eecaef8cd"
3776                 "f11cc38737838cf400"),
3777      hexstr2bin("6ddf802e1aae4986935f7f981ba3f035"
3778                 "1d6273c0a0c22c9c0e8339168e675412"
3779                 "a3debfaf435ed651558007db4384b650"
3780                 "fcc07e3b586a27a4f7a00ac8a6fec2cd"
3781                 "86ae4bf1570c41e6a40c931db27b2faa"
3782                 "15a8cedd52cff7362c4e6e23daec0fbc"
3783                 "3a79b6806e316efcc7b68119bf46bc76"
3784                 "a26067a53f296dafdbdc11c77f7777e9"
3785                 "72660cf4b6a9b369a6665f02e0cc9b6e"
3786                 "dfad136b4fabe723d2813db3136cfde9"
3787                 "b6d044322fee2947952e031b73ab5c60"
3788                 "3349b307bdc27bc6cb8b8bbd7bd32321"
3789                 "9b8033a581b59eadebb09b3c4f3d2277"
3790                 "d4f0343624acc817804728b25ab79717"
3791                 "2b4c5c21a22f9c7839d64300232eb66e"
3792                 "53f31c723fa37fe387c7d3e50bdf9813"
3793                 "a30e5bb12cf4cd930c40cfb4e1fc6225"
3794                 "92a49588794494d56d24ea4b40c89fc0"
3795                 "596cc9ebb961c8cb10adde976a5d602b"
3796                 "1c3f85b9b9a001ed3c6a4d3b1437f520"
3797                 "96cd1956d042a597d561a596ecd3d173"
3798                 "5a8d570ea0ec27225a2c4aaff26306d1"
3799                 "526c1af3ca6d9cf5a2c98f47e1c46db9"
3800                 "a33234cfd4d81f2c98538a09ebe76998"
3801                 "d0d8fd25997c7d255c6d66ece6fa56f1"
3802                 "1144950f027795e653008f4bd7ca2dee"
3803                 "85d8e90f3dc315130ce2a00375a318c7"
3804                 "c3d97be2c8ce5b6db41a6254ff264fa6"
3805                 "155baee3b0773c0f497c573f19bb4f42"
3806                 "40281f0b1f4f7be857a4e59d416c06b4"
3807                 "c50fa09e1810ddc6b1467baeac5a3668"
3808                 "d11b6ecaa901440016f389f80acc4db9"
3809                 "77025e7f5924388c7e340a732e554440"
3810                 "e76570f8dd71b7d640b3450d1fd5f041"
3811                 "0a18f9a3494f707c717b79b4bf75c984"
3812                 "00b096b21653b5d217cf3565c9597456"
3813                 "f70703497a078763829bc01bb1cbc8fa"
3814                 "04eadc9a6e3f6699587a9e75c94e5bab"
3815                 "0036e0b2e711392cff0047d0d6b05bd2"
3816                 "a588bc109718954259f1d86678a579a3"
3817                 "120f19cfb2963f177aeb70f2d4844826"
3818                 "262e51b80271272068ef5b3856fa8535"
3819                 "aa2a88b2d41f2a0e2fda7624c2850272"
3820                 "ac4a2f561f8f2f7a318bfd5caf969614"
3821                 "9e4ac824ad3460538fdc25421beec2cc"
3822                 "6818162d06bbed0c40a387192349db67"
3823                 "a118bada6cd5ab0140ee273204f628aa"
3824                 "d1c135f770279a651e24d8c14d75a605"
3825                 "9d76b96a6fd857def5e0b354b27ab937"
3826                 "a5815d16b5fae407ff18222c6d1ed263"
3827                 "be68c95f32d908bd895cd76207ae7264"
3828                 "87567f9a67dad79abec316f683b17f2d"
3829                 "02bf07e0ac8b5bc6162cf94697b3c27c"
3830                 "d1fea49b27f23ba2901871962506520c"
3831                 "392da8b6ad0d99f7013fbc06c2c17a56"
3832                 "9500c8a7696481c1cd33e9b14e40b82e"
3833                 "79a5f5db82571ba97bae3ad3e0479515"
3834                 "bb0e2b0f3bfcd1fd33034efc6245eddd"
3835                 "7ee2086ddae2600d8ca73e214e8c2b0b"
3836                 "db2b047c6a464a562ed77b73d2d841c4"
3837                 "b34973551257713b753632efba348169"
3838                 "abc90a68f42611a40126d7cb21b58695"
3839                 "568186f7e569d2ff0f9e745d0487dd2e"
3840                 "b997cafc5abf9dd102e62ff66cba87"),
3841      hexstr2bin("e301345a41a39a4d72fff8df69c98075"
3842                 "a0cc082b802fc9b2b6bc503f926b65bd"
3843                 "df7f4c8f1cb49f6396afc8a70abe6d8a"
3844                 "ef0db478d4c6b2970076c6a0484fe76d"
3845                 "76b3a97625d79f1ce240e7c576750d29"
3846                 "5528286f719b413de9ada3e8eb78ed57"
3847                 "3603ce30d8bb761785dc30dbc320869e"
3848                 "1a00")}
3849    ].
3850
3851ecdh() ->
3852    %% http://csrc.nist.gov/groups/STM/cavp/
3853    Curves = crypto:supports(curves),
3854    lists:filter(
3855      fun ({_Type, _Pub, _Priv, Curve, _SharedSecret}) ->
3856              lists:member(Curve, Curves)
3857      end,
3858
3859      [{ecdh, hexstr2point("42ea6dd9969dd2a61fea1aac7f8e98edcc896c6e55857cc0", "dfbe5d7c61fac88b11811bde328e8a0d12bf01a9d204b523"),
3860          hexstr2bin("f17d3fea367b74d340851ca4270dcb24c271f445bed9d527"),
3861          secp192r1,
3862          hexstr2bin("803d8ab2e5b6e6fca715737c3a82f7ce3c783124f6d51cd0")},
3863         {ecdh, hexstr2point("deb5712fa027ac8d2f22c455ccb73a91e17b6512b5e030e7", "7e2690a02cc9b28708431a29fb54b87b1f0c14e011ac2125"),
3864          hexstr2bin("56e853349d96fe4c442448dacb7cf92bb7a95dcf574a9bd5"),
3865          secp192r1,
3866          hexstr2bin("c208847568b98835d7312cef1f97f7aa298283152313c29d")},
3867         {ecdh, hexstr2point("af33cd0629bc7e996320a3f40368f74de8704fa37b8fab69abaae280", "882092ccbba7930f419a8a4f9bb16978bbc3838729992559a6f2e2d7"),
3868          hexstr2bin("8346a60fc6f293ca5a0d2af68ba71d1dd389e5e40837942df3e43cbd"),
3869          secp224r1,
3870          hexstr2bin("7d96f9a3bd3c05cf5cc37feb8b9d5209d5c2597464dec3e9983743e8")},
3871         {ecdh, hexstr2point("13bfcd4f8e9442393cab8fb46b9f0566c226b22b37076976f0617a46", "eeb2427529b288c63c2f8963c1e473df2fca6caa90d52e2f8db56dd4"),
3872          hexstr2bin("043cb216f4b72cdf7629d63720a54aee0c99eb32d74477dac0c2f73d"),
3873          secp224r1,
3874          hexstr2bin("ee93ce06b89ff72009e858c68eb708e7bc79ee0300f73bed69bbca09")},
3875         {ecdh, hexstr2point("700c48f77f56584c5cc632ca65640db91b6bacce3a4df6b42ce7cc838833d287", "db71e509e3fd9b060ddb20ba5c51dcc5948d46fbf640dfe0441782cab85fa4ac"),
3876          hexstr2bin("7d7dc5f71eb29ddaf80d6214632eeae03d9058af1fb6d22ed80badb62bc1a534"),
3877          secp256r1,
3878          hexstr2bin("46fc62106420ff012e54a434fbdd2d25ccc5852060561e68040dd7778997bd7b")},
3879         {ecdh, hexstr2point("809f04289c64348c01515eb03d5ce7ac1a8cb9498f5caa50197e58d43a86a7ae", "b29d84e811197f25eba8f5194092cb6ff440e26d4421011372461f579271cda3"),
3880          hexstr2bin("38f65d6dce47676044d58ce5139582d568f64bb16098d179dbab07741dd5caf5"),
3881          secp256r1,
3882          hexstr2bin("057d636096cb80b67a8c038c890e887d1adfa4195e9b3ce241c8a778c59cda67")},
3883         {ecdh, hexstr2point("a7c76b970c3b5fe8b05d2838ae04ab47697b9eaf52e764592efda27fe7513272734466b400091adbf2d68c58e0c50066", "ac68f19f2e1cb879aed43a9969b91a0839c4c38a49749b661efedf243451915ed0905a32b060992b468c64766fc8437a"),
3884          hexstr2bin("3cc3122a68f0d95027ad38c067916ba0eb8c38894d22e1b15618b6818a661774ad463b205da88cf699ab4d43c9cf98a1"),
3885          secp384r1,
3886          hexstr2bin("5f9d29dc5e31a163060356213669c8ce132e22f57c9a04f40ba7fcead493b457e5621e766c40a2e3d4d6a04b25e533f1")},
3887         {ecdh, hexstr2point("30f43fcf2b6b00de53f624f1543090681839717d53c7c955d1d69efaf0349b7363acb447240101cbb3af6641ce4b88e0", "25e46c0c54f0162a77efcc27b6ea792002ae2ba82714299c860857a68153ab62e525ec0530d81b5aa15897981e858757"),
3888          hexstr2bin("92860c21bde06165f8e900c687f8ef0a05d14f290b3f07d8b3a8cc6404366e5d5119cd6d03fb12dc58e89f13df9cd783"),
3889          secp384r1,
3890          hexstr2bin("a23742a2c267d7425fda94b93f93bbcc24791ac51cd8fd501a238d40812f4cbfc59aac9520d758cf789c76300c69d2ff")},
3891         {ecdh, hexstr2point("00685a48e86c79f0f0875f7bc18d25eb5fc8c0b07e5da4f4370f3a9490340854334b1e1b87fa395464c60626124a4e70d0f785601d37c09870ebf176666877a2046d", "01ba52c56fc8776d9e8f5db4f0cc27636d0b741bbe05400697942e80b739884a83bde99e0f6716939e632bc8986fa18dccd443a348b6c3e522497955a4f3c302f676"),
3892          hexstr2bin("017eecc07ab4b329068fba65e56a1f8890aa935e57134ae0ffcce802735151f4eac6564f6ee9974c5e6887a1fefee5743ae2241bfeb95d5ce31ddcb6f9edb4d6fc47"),
3893          secp521r1,
3894          hexstr2bin("005fc70477c3e63bc3954bd0df3ea0d1f41ee21746ed95fc5e1fdf90930d5e136672d72cc770742d1711c3c3a4c334a0ad9759436a4d3c5bf6e74b9578fac148c831")},
3895         {ecdh, hexstr2point("01df277c152108349bc34d539ee0cf06b24f5d3500677b4445453ccc21409453aafb8a72a0be9ebe54d12270aa51b3ab7f316aa5e74a951c5e53f74cd95fc29aee7a", "013d52f33a9f3c14384d1587fa8abe7aed74bc33749ad9c570b471776422c7d4505d9b0a96b3bfac041e4c6a6990ae7f700e5b4a6640229112deafa0cd8bb0d089b0"),
3896          hexstr2bin("00816f19c1fb10ef94d4a1d81c156ec3d1de08b66761f03f06ee4bb9dcebbbfe1eaa1ed49a6a990838d8ed318c14d74cc872f95d05d07ad50f621ceb620cd905cfb8"),
3897          secp521r1,
3898          hexstr2bin("000b3920ac830ade812c8f96805da2236e002acbbf13596a9ab254d44d0e91b6255ebf1229f366fb5a05c5884ef46032c26d42189273ca4efa4c3db6bd12a6853759")},
3899
3900         %% RFC-6954, Appendix A
3901         {ecdh, hexstr2point("A9C21A569759DA95E0387041184261440327AFE33141CA04B82DC92E",
3902                             "98A0F75FBBF61D8E58AE5511B2BCDBE8E549B31E37069A2825F590C1"),
3903          hexstr2bin("6060552303899E2140715816C45B57D9B42204FB6A5BF5BEAC10DB00"),
3904          brainpoolP224r1,
3905          hexstr2bin("1A4BFE705445120C8E3E026699054104510D119757B74D5FE2462C66")},
3906         {ecdh, hexstr2point("034A56C550FF88056144E6DD56070F54B0135976B5BF77827313F36B",
3907                             "75165AD99347DC86CAAB1CBB579E198EAF88DC35F927B358AA683681"),
3908          hexstr2bin("39F155483CEE191FBECFE9C81D8AB1A03CDA6790E7184ACE44BCA161"),
3909          brainpoolP224r1,
3910          hexstr2bin("1A4BFE705445120C8E3E026699054104510D119757B74D5FE2462C66")},
3911         {ecdh, hexstr2point("44106E913F92BC02A1705D9953A8414DB95E1AAA49E81D9E85F929A8E3100BE5",
3912                             "8AB4846F11CACCB73CE49CBDD120F5A900A69FD32C272223F789EF10EB089BDC"),
3913          hexstr2bin("55E40BC41E37E3E2AD25C3C6654511FFA8474A91A0032087593852D3E7D76BD3"),
3914          brainpoolP256r1,
3915          hexstr2bin("89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B")},
3916         {ecdh, hexstr2point("8D2D688C6CF93E1160AD04CC4429117DC2C41825E1E9FCA0ADDD34E6F1B39F7B",
3917                             "990C57520812BE512641E47034832106BC7D3E8DD0E4C7F1136D7006547CEC6A"),
3918          hexstr2bin("81DB1EE100150FF2EA338D708271BE38300CB54241D79950F77B063039804F1D"),
3919          brainpoolP256r1,
3920          hexstr2bin("89AFC39D41D3B327814B80940B042590F96556EC91E6AE7939BCE31F3A18BF2B")},
3921         {ecdh, hexstr2point("68B665DD91C195800650CDD363C625F4E742E8134667B767B1B476793588F885AB698C852D4A6E77A252D6380FCAF068",
3922                             "55BC91A39C9EC01DEE36017B7D673A931236D2F1F5C83942D049E3FA20607493E0D038FF2FD30C2AB67D15C85F7FAA59"),
3923          hexstr2bin("032640BC6003C59260F7250C3DB58CE647F98E1260ACCE4ACDA3DD869F74E01F8BA5E0324309DB6A9831497ABAC96670"),
3924          brainpoolP384r1,
3925          hexstr2bin("0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42")},
3926         {ecdh, hexstr2point("4D44326F269A597A5B58BBA565DA5556ED7FD9A8A9EB76C25F46DB69D19DC8CE6AD18E404B15738B2086DF37E71D1EB4",
3927                             "62D692136DE56CBE93BF5FA3188EF58BC8A3A0EC6C1E151A21038A42E9185329B5B275903D192F8D4E1F32FE9CC78C48"),
3928          hexstr2bin("1E20F5E048A5886F1F157C74E91BDE2B98C8B52D58E5003D57053FC4B0BD65D6F15EB5D1EE1610DF870795143627D042"),
3929          brainpoolP384r1,
3930          hexstr2bin("0BD9D3A7EA0B3D519D09D8E48D0785FB744A6B355E6304BC51C229FBBCE239BBADF6403715C35D4FB2A5444F575D4F42")},
3931         {ecdh, hexstr2point("0A420517E406AAC0ACDCE90FCD71487718D3B953EFD7FBEC5F7F27E28C6149999397E91E029E06457DB2D3E640668B392C2A7E737A7F0BF04436D11640FD09FD",
3932                             "72E6882E8DB28AAD36237CD25D580DB23783961C8DC52DFA2EC138AD472A0FCEF3887CF62B623B2A87DE5C588301EA3E5FC269B373B60724F5E82A6AD147FDE7"),
3933          hexstr2bin("230E18E1BCC88A362FA54E4EA3902009292F7F8033624FD471B5D8ACE49D12CFABBC19963DAB8E2F1EBA00BFFB29E4D72D13F2224562F405CB80503666B25429"),
3934          brainpoolP512r1,
3935          hexstr2bin("A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F")},
3936         {ecdh, hexstr2point("9D45F66DE5D67E2E6DB6E93A59CE0BB48106097FF78A081DE781CDB31FCE8CCBAAEA8DD4320C4119F1E9CD437A2EAB3731FA9668AB268D871DEDA55A5473199F",
3937                             "2FDC313095BCDD5FB3A91636F07A959C8E86B5636A1E930E8396049CB481961D365CC11453A06C719835475B12CB52FC3C383BCE35E27EF194512B71876285FA"),
3938          hexstr2bin("16302FF0DBBB5A8D733DAB7141C1B45ACBC8715939677F6A56850A38BD87BD59B09E80279609FF333EB9D4C061231FB26F92EEB04982A5F1D1764CAD57665422"),
3939          brainpoolP512r1,
3940          hexstr2bin("A7927098655F1F9976FA50A9D566865DC530331846381C87256BAF3226244B76D36403C024D7BBF0AA0803EAFF405D3D24F11A9B5C0BEF679FE1454B21C4CD1F")},
3941
3942         %% RFC 7748, 6.1
3943         {ecdh,
3944          16#8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a,
3945          16#5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb,
3946          x25519,
3947          hexstr2bin("4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742")},
3948         {ecdh,
3949          16#de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f,
3950          16#77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a,
3951          x25519,
3952          hexstr2bin("4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742")},
3953
3954         %% RFC 7748, 6.2
3955         {ecdh,
3956          16#9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0,
3957          16#1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d,
3958          x448,
3959          hexstr2bin("07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d")},
3960         {ecdh,
3961          16#3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b43027d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609,
3962          16#9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28dd9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b,
3963          x448,
3964          hexstr2bin("07fff4181ac6cc95ec1c16a94a0f74d12da232ce40a77552281d282bb60c0b56fd2464c335543936521c24403085d59a449a5037514a879d")}
3965        ]
3966        ).
3967
3968dh() ->
3969    {dh, 90970053988169282502023478715631717259407236400413906591937635666709823903223997309250405131675572047545403771567755831138144089197560332757755059848492919215391041119286178688014693040542889497092308638580104031455627238700168892909539193174537248629499995652186913900511641708112112482297874449292467498403, 2}.
3970
3971
3972
3973rsa_oaep() ->
3974    %% ftp://ftp.rsa.com/pub/rsalabs/tmp/pkcs1v15crypt-vectors.txt
3975    Public = [hexstr2bin("010001"),
3976	      hexstr2bin("a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb")],
3977    Private = Public ++ [hexstr2bin("53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1"),
3978			 hexstr2bin("d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d"),
3979			 hexstr2bin("cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d77"),
3980			 hexstr2bin("0e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c1"),
3981			 hexstr2bin("95297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d71583"),
3982			 hexstr2bin("4f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1")],
3983    %%Msg = hexstr2bin("6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34"),
3984    Msg =  hexstr2bin("750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"),
3985    {rsa, Public, Private, Msg, [{rsa_padding, rsa_pkcs1_oaep_padding}]}.
3986
3987rsa_oaep_label() ->
3988    Public = [hexstr2bin("010001"),
3989	      hexstr2bin("a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb")],
3990    Private = Public ++ [hexstr2bin("53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1"),
3991			 hexstr2bin("d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d"),
3992			 hexstr2bin("cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d77"),
3993			 hexstr2bin("0e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c1"),
3994			 hexstr2bin("95297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d71583"),
3995			 hexstr2bin("4f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1")],
3996    Msg = hexstr2bin("750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"),
3997    Lbl = hexstr2bin("1332a67ca7088f75c9b8fb5e3d072882"),
3998    {rsa, Public, Private, Msg, [{rsa_padding, rsa_pkcs1_oaep_padding}, {rsa_oaep_label, Lbl}]}.
3999
4000rsa_oaep256() ->
4001    Public = [hexstr2bin("010001"),
4002	      hexstr2bin("a8b3b284af8eb50b387034a860f146c4919f318763cd6c5598c8ae4811a1e0abc4c7e0b082d693a5e7fced675cf4668512772c0cbc64a742c6c630f533c8cc72f62ae833c40bf25842e984bb78bdbf97c0107d55bdb662f5c4e0fab9845cb5148ef7392dd3aaff93ae1e6b667bb3d4247616d4f5ba10d4cfd226de88d39f16fb")],
4003    Private = Public ++ [hexstr2bin("53339cfdb79fc8466a655c7316aca85c55fd8f6dd898fdaf119517ef4f52e8fd8e258df93fee180fa0e4ab29693cd83b152a553d4ac4d1812b8b9fa5af0e7f55fe7304df41570926f3311f15c4d65a732c483116ee3d3d2d0af3549ad9bf7cbfb78ad884f84d5beb04724dc7369b31def37d0cf539e9cfcdd3de653729ead5d1"),
4004			 hexstr2bin("d32737e7267ffe1341b2d5c0d150a81b586fb3132bed2f8d5262864a9cb9f30af38be448598d413a172efb802c21acf1c11c520c2f26a471dcad212eac7ca39d"),
4005			 hexstr2bin("cc8853d1d54da630fac004f471f281c7b8982d8224a490edbeb33d3e3d5cc93c4765703d1dd791642f1f116a0dd852be2419b2af72bfe9a030e860b0288b5d77"),
4006			 hexstr2bin("0e12bf1718e9cef5599ba1c3882fe8046a90874eefce8f2ccc20e4f2741fb0a33a3848aec9c9305fbecbd2d76819967d4671acc6431e4037968db37878e695c1"),
4007			 hexstr2bin("95297b0f95a2fa67d00707d609dfd4fc05c89dafc2ef6d6ea55bec771ea333734d9251e79082ecda866efef13c459e1a631386b7e354c899f5f112ca85d71583"),
4008			 hexstr2bin("4f456c502493bdc0ed2ab756a3a6ed4d67352a697d4216e93212b127a63d5411ce6fa98d5dbefd73263e3728142743818166ed7dd63687dd2a8ca1d2f4fbd8e1")],
4009    Msg = hexstr2bin("750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5"),
4010    {rsa, Public, Private, Msg, [{rsa_padding, rsa_pkcs1_oaep_padding}, {rsa_oaep_md, sha256}]}.
4011
4012ecc() ->
4013%%               http://point-at-infinity.org/ecc/nisttv
4014%%
4015%% Test vectors for the NIST elliptic curves P192, P224, P256, P384, P521,
4016%% B163, B233, B283, B409, B571, K163, K233, K283, K409 and K571. For more
4017%% information about the curves see
4018%%       http://csrc.nist.gov/encryption/dss/ecdsa/NISTReCur.pdf
4019%%
4020    Curves = crypto:supports(curves),
4021    lists:filter(
4022      fun ({_Type, Curve, _Priv, _Pub}) ->
4023              lists:member(Curve, Curves)
4024      end,
4025        [{ecdh,secp192r1,1,
4026          hexstr2point("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
4027                       "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")},
4028         {ecdh,secp192r1,2,
4029          hexstr2point("DAFEBF5828783F2AD35534631588A3F629A70FB16982A888",
4030                       "DD6BDA0D993DA0FA46B27BBC141B868F59331AFA5C7E93AB")},
4031         {ecdh,secp192r1,3,
4032          hexstr2point("76E32A2557599E6EDCD283201FB2B9AADFD0D359CBB263DA",
4033                       "782C37E372BA4520AA62E0FED121D49EF3B543660CFD05FD")},
4034         {ecdh,secp192r1,4,
4035          hexstr2point("35433907297CC378B0015703374729D7A4FE46647084E4BA",
4036                       "A2649984F2135C301EA3ACB0776CD4F125389B311DB3BE32")},
4037         %% RFC 7748, 6.2
4038         {ecdh, x448,
4039          hexstr2bin("9a8f4925d1519f5775cf46b04b5800d4ee9ee8bae8bc5565d498c28d"
4040                     "d9c9baf574a9419744897391006382a6f127ab1d9ac2d8c0a598726b"),
4041          hexstr2bin("9b08f7cc31b7e3e67d22d5aea121074a273bd2b83de09c63faa73d2c"
4042                     "22c5d9bbc836647241d953d40c5b12da88120d53177f80e532c41fa0")},
4043         {ecdh, x448,
4044          hexstr2bin("1c306a7ac2a0e2e0990b294470cba339e6453772b075811d8fad0d1d"
4045                     "6927c120bb5ee8972b0d3e21374c9c921b09d1b0366f10b65173992d"),
4046          hexstr2bin("3eb7a829b0cd20f5bcfc0b599b6feccf6da4627107bdb0d4f345b430"
4047                     "27d8b972fc3e34fb4232a13ca706dcb57aec3dae07bdc1c67bf33609")},
4048         %% RFC 7748, 6.1
4049         {ecdh, x25519,
4050          hexstr2bin("77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a"),
4051          hexstr2bin("8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a")},
4052         {ecdh, x25519,
4053          hexstr2bin("5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb"),
4054          hexstr2bin("de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f")}
4055        ]
4056     ).
4057
4058datadir(Config) ->
4059    proplists:get_value(data_dir, Config).
4060
4061-define(KiB, 1024).
4062-define(MiB, (1024 * 1024)).
4063-define(GiB, (1024 * 1024 * 1024)).
4064
4065fmt_words(Words) ->
4066    BSize = Words * erlang:system_info(wordsize),
4067    if BSize < ?KiB ->
4068            integer_to_list(BSize);
4069       BSize < ?MiB ->
4070            io_lib:format("~8.2fKiB (~8w)", [BSize / ?KiB, BSize]);
4071       BSize < ?GiB ->
4072            io_lib:format("~8.2fMiB (~8w)", [BSize / ?MiB, BSize]);
4073       true ->
4074            io_lib:format("~8.2fGiB (~8w)", [BSize / ?GiB, BSize])
4075    end.
4076
4077log_rsp_size(Label, Term) ->
4078    S = erts_debug:size(Term),
4079    ct:log("~s: ~w test(s), Memory used: ~s",
4080           [Label, length(Term), fmt_words(S)]).
4081
4082read_rsp(Config, Type, Files) ->
4083    Tests =
4084        lists:foldl(
4085          fun(FileName, Acc) ->
4086                  NewAcc = read_rsp_file(filename:join(datadir(Config), FileName),
4087                                         Type, Acc),
4088                  ct:log("~p: ~p tests read.~n",[FileName,length(NewAcc)-length(Acc)]),
4089                  NewAcc
4090          end, [], Files),
4091    log_rsp_size(Type, Tests),
4092    Tests.
4093
4094read_rsp_file(FileName, Type, Acc) ->
4095    case file:read_file(FileName) of
4096        {ok, Raw} ->
4097            Split = binary:split(Raw, [<<"\r">>, <<"\n">>], [global, trim_all]),
4098            parse_rsp(Type, Split, #{file => FileName}, Acc);
4099        Other ->
4100            ct:fail("~p ~p",[FileName, Other])
4101    end.
4102
4103parse_rsp(_Type, [], _State, Acc) ->
4104    Acc;
4105parse_rsp(_Type, [<<"DECRYPT">>|_], _State, Acc) ->
4106    Acc;
4107parse_rsp(_Type, [<<"ENCRYPT">>|_], _State, Acc) ->
4108    Acc;
4109%% AES format
4110parse_rsp(Type, [<<"COUNT = ", _/binary>>,
4111                 <<"KEY = ", Key/binary>>,
4112                 <<"PLAINTEXT = ", PlainText/binary>>,
4113                 <<"CIPHERTEXT = ", CipherText/binary>>|Next], State, Acc) ->
4114    parse_rsp(Type, Next, State,
4115              [{Type, hexstr2bin(Key),
4116                hexstr2bin(PlainText), hexstr2bin(CipherText)}|Acc]);
4117parse_rsp(Type, [<<"COUNT = ", _/binary>>,
4118                 <<"KEY = ", Key/binary>>,
4119                 <<"IV = ", IV/binary>>,
4120                 <<"PLAINTEXT = ", PlainText/binary>>,
4121                 <<"CIPHERTEXT = ", CipherText/binary>>|Next], State, Acc) ->
4122    parse_rsp(Type, Next, State,
4123              [{Type, hexstr2bin(Key), hexstr2bin(IV),
4124                hexstr2bin(PlainText), hexstr2bin(CipherText)}|Acc]);
4125%% CMAC format
4126parse_rsp(Type, [<<"Count = ", _/binary>>,
4127                 <<"Klen = ", _/binary>>,
4128                 <<"Mlen = ", Mlen/binary>>,
4129                 <<"Tlen = ", Tlen/binary>>,
4130                 <<"Key = ", Key/binary>>,
4131                 <<"Msg = ", Msg/binary>>,
4132                 <<"Mac = ", MAC/binary>>|Rest], State, Acc) ->
4133    case Rest of
4134        [<<"Result = P">>|Next] ->
4135            parse_rsp_cmac(Type, Key, Msg, Mlen, Tlen, MAC, Next, State, Acc);
4136        [<<"Result = ", _/binary>>|Next] ->
4137            parse_rsp(Type, Next, State, Acc);
4138        _ ->
4139            parse_rsp_cmac(Type, Key, Msg, Mlen, Tlen, MAC, Rest, State, Acc)
4140    end;
4141%% GCM format decode format
4142parse_rsp(Type, [<<"Count = ", Count/binary>>,
4143                 <<"Key = ", Key/binary>>,
4144                 <<"IV = ",  IV/binary>>,
4145                 <<"CT = ",  CipherText/binary>>,
4146                 <<"AAD = ", AAD/binary>>,
4147                 <<"Tag = ", CipherTag0/binary>>,
4148                 <<"PT = ",  PlainText/binary>>|Next], #{file:=File}=State, Acc) ->
4149    CipherTag = hexstr2bin(CipherTag0),
4150    TestCase = {Type,
4151                hexstr2bin(Key),
4152                hexstr2bin(PlainText),
4153                hexstr2bin(IV),
4154                hexstr2bin(AAD),
4155                hexstr2bin(CipherText),
4156                CipherTag,
4157                size(CipherTag),
4158                {File,decstr2int(Count)}},
4159    parse_rsp(Type, Next, State, [TestCase|Acc]);
4160%% GCM format encode format
4161parse_rsp(Type, [<<"Count = ", Count/binary>>,
4162                 <<"Key = ", Key/binary>>,
4163                 <<"IV = ",  IV/binary>>,
4164                 <<"PT = ",  PlainText/binary>>,
4165                 <<"AAD = ", AAD/binary>>,
4166                 <<"CT = ",  CipherText/binary>>,
4167                 <<"Tag = ", CipherTag0/binary>>|Next], #{file:=File}=State, Acc) ->
4168    CipherTag = hexstr2bin(CipherTag0),
4169    TestCase = {Type,
4170                hexstr2bin(Key),
4171                hexstr2bin(PlainText),
4172                hexstr2bin(IV),
4173                hexstr2bin(AAD),
4174                hexstr2bin(CipherText),
4175                CipherTag,
4176                size(CipherTag),
4177                {File,decstr2int(Count)}},
4178    parse_rsp(Type, Next, State, [TestCase|Acc]);
4179%% CCM-VADT format
4180parse_rsp(Type, [<<"[Alen = ", AlenB0/binary>>|Next], State0, Acc) ->
4181    AlenSize = size(AlenB0) - 1, % remove closing ']'
4182    Alen = decstr2int(<<AlenB0:AlenSize/binary>>),
4183    State = State0#{alen => Alen},
4184    parse_rsp(Type, Next, State, Acc);
4185parse_rsp(Type, [<<"[Nlen = ", NlenB0/binary>>|Next], State0, Acc) ->
4186    NlenSize = size(NlenB0) - 1, % remove closing ']'
4187    Nlen = decstr2int(<<NlenB0:NlenSize/binary>>),
4188    State = State0#{nlen => Nlen},
4189    parse_rsp(Type, Next, State, Acc);
4190parse_rsp(Type, [<<"[Plen = ", PlenB0/binary>>|Next], State0, Acc) ->
4191    PlenSize = size(PlenB0) - 1, % remove closing ']'
4192    Plen = decstr2int(<<PlenB0:PlenSize/binary>>),
4193    State = State0#{plen => Plen},
4194    parse_rsp(Type, Next, State, Acc);
4195parse_rsp(Type, [<<"[Tlen = ", TlenB0/binary>>|Next], State0, Acc) ->
4196    TlenSize = size(TlenB0) - 1, % remove closing ']'
4197    Tlen = decstr2int(<<TlenB0:TlenSize/binary>>),
4198    State = State0#{tlen => Tlen},
4199    parse_rsp(Type, Next, State, Acc);
4200parse_rsp(Type, [<<"Alen = ", B/binary>>|Next], State0, Acc) ->
4201    State = State0#{alen => decstr2int(B)},
4202    parse_rsp(Type, Next, State, Acc);
4203parse_rsp(Type, [<<"Plen = ", B/binary>>|Next], State0, Acc) ->
4204    State = State0#{plen => decstr2int(B)},
4205    parse_rsp(Type, Next, State, Acc);
4206parse_rsp(Type, [<<"Count = ", B/binary>>|Next], State0, Acc) ->
4207    State = State0#{count => B},
4208    parse_rsp(Type, Next, State, Acc);
4209parse_rsp(Type, [<<"Nlen = ", B/binary>>|Next], State0, Acc) ->
4210    State = State0#{nlen => decstr2int(B)},
4211    parse_rsp(Type, Next, State, Acc);
4212parse_rsp(Type, [<<"Tlen = ", B/binary>>|Next], State0, Acc) ->
4213    State = State0#{tlen => decstr2int(B)},
4214    parse_rsp(Type, Next, State, Acc);
4215parse_rsp(Type, [<<"Key = ",Key/binary>>|Next], State0, Acc) ->
4216    State = State0#{key => hexstr2bin(Key)},
4217    parse_rsp(Type, Next, State, Acc);
4218parse_rsp(Type, [<<"Nonce = ",Nonce/binary>>|Next], State0, Acc) ->
4219    State = State0#{nonce => hexstr2bin(Nonce)},
4220    parse_rsp(Type, Next, State, Acc);
4221parse_rsp(Type, [<<"Adata = ",Adata/binary>>|Next], State0, Acc) ->
4222    State = State0#{adata => hexstr2bin(Adata)},
4223    parse_rsp(Type, Next, State, Acc);
4224parse_rsp(Type, [<<"Payload = ",Payload/binary>>|Next], State0, Acc) ->
4225    State = State0#{payload => hexstr2bin(Payload)},
4226    parse_rsp(Type, Next, State, Acc);
4227parse_rsp(Type,
4228          [<<"CT = ", CT/binary>>|Next],
4229          #{count := Count,
4230            file := File,
4231            alen := Alen,
4232            plen := Plen,
4233            nlen := _Nlen,
4234            tlen := Tlen,
4235            key := Key,
4236            nonce := IV,
4237            adata := Adata,
4238            payload := Payload
4239           } = State, Acc) ->
4240    AAD = <<Adata:Alen/binary>>,
4241    PlainText = <<Payload:Plen/binary>>,
4242    <<CipherText:Plen/binary, CipherTag:Tlen/binary>> = hexstr2bin(CT),
4243    TestCase = {Type,
4244                Key,
4245                PlainText,
4246                IV,
4247                AAD,
4248                CipherText,
4249                CipherTag,
4250                Tlen,
4251                {File,decstr2int(Count)}},
4252    parse_rsp(Type, Next, State, [TestCase|Acc]);
4253parse_rsp(Type, [_|Next], State, Acc) ->
4254    parse_rsp(Type, Next, State, Acc).
4255
4256
4257parse_rsp_cmac(Type, Key0, Msg0, Mlen0, Tlen, MAC0, Next, State, Acc) ->
4258    Key = hexstr2bin(Key0),
4259    Mlen = binary_to_integer(Mlen0),
4260    <<Msg:Mlen/bytes, _/binary>> = hexstr2bin(Msg0),
4261    MAC = hexstr2bin(MAC0),
4262    case binary_to_integer(Tlen) of
4263        0 ->
4264            parse_rsp(Type, Next, State, [{cmac, Type, Key, Msg, MAC}|Acc]);
4265        I ->
4266            parse_rsp(Type, Next, State, [{cmac, Type, Key, Msg, I, MAC}|Acc])
4267    end.
4268
4269api_errors_ecdh(Config) when is_list(Config) ->
4270    %% Check that we don't segfault when fed garbage.
4271    Test = fun(Others, Curve) ->
4272                   {_Pub, Priv} = crypto:generate_key(ecdh, Curve),
4273                   crypto:compute_key(ecdh, Others, Priv, Curve)
4274           end,
4275    Others = [gurka, 0, <<0>>],
4276    Curves = [gaffel, 0, sect571r1],
4277    [_= (catch Test(O, C)) || O <- Others, C <- Curves],
4278    ok.
4279
4280
4281%%%----- Tests for bad algorithm name as argument
4282-define(chk_api_name(Call, Expect),
4283        %% Check that we don't segfault on bad names
4284        (fun() -> % avoid binding vars
4285                 try
4286                     Call
4287                 catch
4288                     Expect -> ok;
4289
4290                     Class:Reason:Stack ->
4291                         ct:log("~p:~p~n~p", [Class,Reason,Stack]),
4292                         ct:fail("Bad respons for bad name")
4293                 end
4294         end)()
4295       ).
4296
4297bad_combo(_Config) ->
4298    ?chk_api_name(crypto:crypto_dyn_iv_init(des_ede3_cbc, <<>>, []),
4299                  error:_).
4300
4301bad_key_length(_Config) ->
4302    ?chk_api_name(crypto:crypto_dyn_iv_init(des_ede3_cbc, <<1>>, true),
4303                  error:{error,{"api_ng.c",_},"Can't initialize context, key_length"}).
4304
4305bad_cipher_name(_Config) ->
4306    ?chk_api_name(crypto:crypto_init(foobar, <<1:128>>, true),
4307                  error:{badarg,{"api_ng.c",_Line},"Unknown cipher"}).
4308
4309bad_generate_key_name(_Config) ->
4310    ?chk_api_name(crypto:generate_key(foobar, [1024]),
4311                  error:function_clause).
4312
4313bad_hash_name(_Config) ->
4314    ?chk_api_name(crypto:hash_init(foobar),
4315                  error:badarg).
4316
4317bad_mac_name(_Config) ->
4318    ?chk_api_name(crypto:mac(foobar, <<1:1024>>, "nothing"),
4319                  error:function_clause).
4320
4321bad_sign_name(_Config) ->
4322    ?chk_api_name(crypto:sign(rsa, foobar, "nothing", <<1:1024>>),
4323                  error:badarg),
4324    ?chk_api_name(crypto:sign(foobar, sha, "nothing", <<1:1024>>),
4325                  error:badarg).
4326
4327bad_verify_name(_Config) ->
4328    ?chk_api_name(crypto:verify(rsa, foobar, "nothing","nothing",  <<1:1024>>),
4329                  error:badarg),
4330    ?chk_api_name(crypto:verify(foobar, sha, "nothing", "nothing", <<1:1024>>),
4331                  error:badarg).
4332
4333
4334%%%----------------------------------------------------------------
4335try_enable_fips_mode(Config) ->
4336    FIPSConfig = [{fips, true} | Config],
4337    case crypto:info_fips() of
4338        enabled ->
4339            FIPSConfig;
4340        not_enabled ->
4341            %% Erlang/crypto configured with --enable-fips
4342            case crypto:enable_fips_mode(true) of
4343		true ->
4344                    %% and also the cryptolib is fips enabled
4345		    enabled = crypto:info_fips(),
4346		    FIPSConfig;
4347		false ->
4348                    try
4349                        [{_,_,Inf}] = crypto:info_lib(),
4350                        re:run(Inf, "(F|f)(I|i)(P|p)(S|s)")
4351                    of
4352                        nomatch ->
4353                            {skip, "FIPS mode not supported in cryptolib"};
4354                        {match,_} ->
4355                            {fail, "Failed to enable FIPS mode"}
4356                    catch
4357                        _:_ ->
4358                            {fail, "Failed to check cryptolib info"}
4359                    end,
4360		    {skip, "FIPS mode not supported in cryptolib"}
4361	    end;
4362        not_supported ->
4363            {skip, "FIPS mode not supported"}
4364    end.
4365