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%% Unless required by applicable law or agreed to in writing, software
13%% distributed under the License is distributed on an "AS IS" BASIS,
14%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15%% See the License for the specific language governing permissions and
16%% limitations under the License.
17%%
18%% %CopyrightEnd%
19%%
20
21%% Purpose : Main Crypto API module.
22
23-module(crypto).
24
25-export([start/0, stop/0, info_lib/0, info_fips/0, supports/0, enable_fips_mode/1,
26         version/0, bytes_to_integer/1]).
27-export([equal_const_time/2]).
28-export([cipher_info/1, hash_info/1]).
29-export([hash/2, hash_init/1, hash_update/2, hash_final/1]).
30-export([sign/4, sign/5, verify/5, verify/6]).
31-export([generate_key/2, generate_key/3, compute_key/4]).
32-export([exor/2, strong_rand_bytes/1, mod_pow/3]).
33-export([rand_seed/0, rand_seed_alg/1, rand_seed_alg/2]).
34-export([rand_seed_s/0, rand_seed_alg_s/1, rand_seed_alg_s/2]).
35-export([rand_plugin_next/1]).
36-export([rand_plugin_aes_next/1, rand_plugin_aes_jump/1]).
37-export([rand_plugin_uniform/1]).
38-export([rand_plugin_uniform/2]).
39-export([rand_cache_plugin_next/1]).
40-export([rand_uniform/2]).
41-export([public_encrypt/4, private_decrypt/4]).
42-export([private_encrypt/4, public_decrypt/4]).
43-export([privkey_to_pubkey/2]).
44-export([ec_curve/1, ec_curves/0]).
45-export([rand_seed/1]).
46
47%%%----------------------------------------------------------------
48%% Removed functions.
49%%
50-removed([{rand_bytes,1,"use crypto:strong_rand_bytes/1 instead"}]).
51
52-removed([{md4,1,"use crypto:hash/2 instead"}]).
53-removed([{md5,1,"use crypto:hash/2 instead"}]).
54-removed([{sha,1,"use crypto:hash/2 instead"}]).
55
56-removed([{md4_init,0,"use crypto:hash_init/1 instead"}]).
57-removed([{md5_init,0,"use crypto:hash_init/1 instead"}]).
58-removed([{sha_init,0,"use crypto:hash_init/1 instead"}]).
59
60-removed([{md4_update,2,"use crypto:hash_update/2 instead"}]).
61-removed([{md5_update,2,"use crypto:hash_update/2 instead"}]).
62-removed([{sha_update,2,"use crypto:hash_update/2 instead"}]).
63
64-removed([{md4_final,1,"use crypto:hash_final/1 instead"}]).
65-removed([{md5_final,1,"use crypto:hash_final/1 instead"}]).
66-removed([{sha_final,1,"use crypto:hash_final/1 instead"}]).
67
68-removed([{md5_mac,2,"use crypto:hmac/3 instead"}]).
69-removed([{md5_mac_96,2,"use crypto:hmac/4 instead"}]).
70
71-removed([{sha_mac,2,"use crypto:hmac/3 instead"}]).
72-removed([{sha_mac,3,"use crypto:hmac/4 instead"}]).
73-removed([{sha_mac_96,2,"use crypto:hmac/4 instead"}]).
74
75-removed([{rsa_sign,'_',"use crypto:sign/4 instead"}]).
76-removed([{rsa_verify,'_',"use crypto:verify/5 instead"}]).
77
78-removed([{dss_sign,'_',"use crypto:sign/4 instead"}]).
79-removed([{dss_verify,'_',"use crypto:verify/5 instead"}]).
80
81-removed([{mod_exp,3,"use crypto:mod_pow/3 instead"}]).
82
83-removed([{dh_compute_key,3,"use crypto:compute_key/4 instead"}]).
84-removed([{dh_generate_key,1,"use crypto:generate_key/2 instead"}]).
85-removed([{dh_generate_key,2,"use crypto:generate_key/3 instead"}]).
86
87%% DES
88
89-removed([{des_cfb_ivec,2,"use crypto:next_iv/3 instead"}]).
90-removed([{des_cbc_ivec,2,"use crypto:next_iv/2 instead"}]).
91
92-removed([{des_ecb_encrypt,2,"use crypto:block_encrypt/3 instead"}]).
93-removed([{des_cbc_encrypt,3,"use crypto:block_encrypt/4 instead"}]).
94-removed([{des_ede3_cbc_encrypt,5,"use crypto:block_encrypt/4 instead"}]).
95-removed([{des_cfb_encrypt,3,"use crypto:block_encrypt/4 instead"}]).
96
97-removed([{des_ecb_decrypt,2,"use crypto:block_decrypt/3 instead"}]).
98-removed([{des_cbc_decrypt,3,"use crypto:block_decrypt/4 instead"}]).
99-removed([{des_cfb_decrypt,3,"use crypto:block_decrypt/4 instead"}]).
100
101%% Triple-DES
102
103-removed([{des3_cbc_encrypt,5,"use crypto:block_encrypt/4 instead"}]).
104-removed([{des3_cfb_encrypt,5,"use crypto:block_encrypt/4 instead"}]).
105
106-removed([{des3_cbc_decrypt,5,"use crypto:block_decrypt/4 instead"}]).
107-removed([{des3_cfb_decrypt,5,"use crypto:block_decrypt/4 instead"}]).
108-removed([{des3_ede3_cbc_decrypt,5,"use crypto:block_decrypt/4 instead"}]).
109
110%% Blowfish
111
112-removed([{blowfish_ecb_encrypt,2,"use crypto:block_encrypt/3 instead"}]).
113-removed([{blowfish_cbc_encrypt,3,"use crypto:block_encrypt/4 instead"}]).
114-removed([{blowfish_cfb64_encrypt,3,"use crypto:block_encrypt/4 instead"}]).
115-removed([{blowfish_ofb64_encrypt,3,"use crypto:block_encrypt/4 instead"}]).
116
117-removed([{blowfish_ecb_decrypt,2,"use crypto:block_decrypt/3 instead"}]).
118-removed([{blowfish_cbc_decrypt,3,"use crypto:block_decrypt/4 instead"}]).
119-removed([{blowfish_cfb64_decrypt,3,"use crypto:block_decrypt/4 instead"}]).
120-removed([{blowfish_ofb64_decrypt,3,"use crypto:block_decrypt/4 instead"}]).
121
122%% AES
123
124-removed([{aes_cfb_128_encrypt,3,"use crypto:block_encrypt/4 instead"}]).
125-removed([{aes_cbc_128_encrypt,3,"use crypto:block_encrypt/4 instead"}]).
126-removed([{aes_cbc_256_encrypt,3,"use crypto:block_encrypt/4 instead"}]).
127
128-removed([{aes_cfb_128_decrypt,3,"use crypto:block_decrypt/4 instead"}]).
129-removed([{aes_cbc_128_decrypt,3,"use crypto:block_decrypt/4 instead"}]).
130-removed([{aes_cbc_256_decrypt,3,"use crypto:block_decrypt/4 instead"}]).
131
132-removed([{aes_ctr_stream_init,2,"use crypto:stream_init/3 instead"}]).
133-removed([{aes_ctr_stream_encrypt,2,"use crypto:stream_encrypt/2 instead"}]).
134-removed([{aes_ctr_encrypt,3,"use crypto:stream_encrypt/2 instead"}]).
135-removed([{aes_ctr_stream_decrypt,2,"use crypto:stream_decrypt/2 instead"}]).
136-removed([{aes_ctr_decrypt,3,"use crypto:stream_decrypt/2 instead"}]).
137
138-removed([{aes_cbc_ivec,2,"use crypto:next_iv/2 instead"}]).
139
140%% RC2
141
142-removed([{rc2_cbc_encrypt,3,"use crypto:block_encrypt/4 instead"}]).
143-removed([{rc2_40_cbc_encrypt,3,"use crypto:block_encrypt/4 instead"}]).
144
145-removed([{rc2_cbc_decrypt,3,"use crypto:block_decrypt/4 instead"}]).
146-removed([{rc2_40_cbc_decrypt,3,"use crypto:block_decrypt/4 instead"}]).
147
148%% RC4
149
150-removed([{rc4_set_key,2,"use crypto:stream_init/2 instead"}]).
151-removed([{rc4_encrypt,2,"use crypto:stream_encrypt/2 instead"}]).
152-removed([{rc4_encrypt_with_state,2,"use crypto:stream_encrypt/2 instead"}]).
153
154%% Other
155
156-removed([{info,0,"use crypto:module_info/0 instead"}]).
157
158-removed([{strong_rand_mpint,3,"only needed by other removed functions"}]).
159-removed([{erlint,1,"only needed by other removed functions"}]).
160-removed([{mpint,1,"only needed by other removed functions"}]).
161
162%%%----------------------------------------------------------------
163%% Old interface. Now implemented with the New interface.
164%% Remove in OTP-24.0 See OTP-16232
165
166-deprecated([{next_iv, '_',
167              "see the 'New and Old API' chapter of the CRYPTO User's guide"}]).
168-export([next_iv/2, next_iv/3]).
169
170-deprecated([{hmac, 3, "use crypto:mac/4 instead"},
171             {hmac, 4, "use crypto:macN/5 instead"},
172             {hmac_init, 2, "use crypto:mac_init/3 instead"},
173             {hmac_update, 2, "use crypto:mac_update/2 instead"},
174             {hmac_final, 1, "use crypto:mac_final/1 instead"},
175             {hmac_final_n, 2, "use crypto:mac_finalN/2 instead"}]).
176
177-export([hmac/3, hmac/4, hmac_init/2, hmac_update/2, hmac_final/1, hmac_final_n/2]).
178
179-deprecated([{cmac, 3, "use crypto:mac/4 instead"},
180             {cmac, 4, "use crypto:macN/5 instead"}]).
181-export([cmac/3, cmac/4]).
182
183-deprecated([{poly1305, 2, "use crypto:mac/3 instead"}]).
184-export([poly1305/2]).
185
186-deprecated([{stream_init, '_',
187              "use crypto:crypto_init/3 + crypto:crypto_update/2 + "
188              "crypto:crypto_final/1 or crypto:crypto_one_time/4 instead"},
189             {stream_encrypt, 2, "use crypto:crypto_update/2 instead"},
190             {stream_decrypt, 2, "use crypto:crypto_update/2 instead"},
191             {block_encrypt, 3,
192              "use crypto:crypto_one_time/4 or crypto:crypto_init/3 + "
193              "crypto:crypto_update/2 + crypto:crypto_final/1 instead"},
194             {block_encrypt, 4,
195              "use crypto:crypto_one_time/5, crypto:crypto_one_time_aead/6,7 "
196              "or crypto:crypto_(dyn_iv)?_init + "
197              "crypto:crypto_(dyn_iv)?_update + crypto:crypto_final instead"},
198             {block_decrypt, 3,
199              "use crypto:crypto_one_time/4 or crypto:crypto_init/3 + "
200              "crypto:crypto_update/2 + crypto:crypto_final/1 instead"},
201             {block_decrypt, 4,
202              "use crypto:crypto_one_time/5, crypto:crypto_one_time_aead/6,7 "
203              "or crypto:crypto_(dyn_iv)?_init + "
204              "crypto:crypto_(dyn_iv)?_update + crypto:crypto_final instead"}
205            ]).
206-export([stream_init/2, stream_init/3,
207         stream_encrypt/2,
208         stream_decrypt/2,
209         block_encrypt/3, block_encrypt/4,
210         block_decrypt/3, block_decrypt/4
211        ]).
212-deprecated_type([{retired_cbc_cipher_aliases, 0, "Use aes_*_cbc or des_ede3_cbc"},
213                  {retired_cfb_cipher_aliases, 0, "Use aes_*_cfb8, aes_*_cfb128 or des_ede3_cfb"},
214                  {retired_ctr_cipher_aliases, 0, "Use aes_*_ctr"},
215                  {retired_ecb_cipher_aliases, 0, "Use aes_*_ecb"}
216                 ]).
217
218%%%----------------------------------------------------------------
219%% New interface
220-export([crypto_init/4, crypto_init/3,
221         crypto_update/2,
222
223         crypto_one_time/4, crypto_one_time/5,
224         crypto_one_time_aead/6, crypto_one_time_aead/7,
225
226         crypto_dyn_iv_init/3,
227         crypto_dyn_iv_update/3,
228         crypto_final/1,
229         crypto_get_data/1,
230
231         supports/1,
232         mac/3, mac/4, macN/4, macN/5,
233         mac_init/2, mac_init/3, mac_update/2, mac_final/1, mac_finalN/2
234        ]).
235
236%%%----------------------------------------------------------------
237%% Engine
238-export([
239         engine_get_all_methods/0,
240         engine_load/3,
241         engine_load/4,
242         engine_unload/1,
243         engine_by_id/1,
244         engine_list/0,
245         engine_ctrl_cmd_string/3,
246         engine_ctrl_cmd_string/4,
247         engine_add/1,
248         engine_remove/1,
249         engine_get_id/1,
250         engine_get_name/1,
251         ensure_engine_loaded/2,
252         ensure_engine_loaded/3,
253         ensure_engine_unloaded/1,
254         ensure_engine_unloaded/2
255        ]).
256
257-export_type([ %% A minimum exported: only what public_key needs.
258               dh_private/0,
259               dh_public/0,
260               dss_digest_type/0,
261               ec_named_curve/0,
262               ecdsa_digest_type/0,
263               pk_encrypt_decrypt_opts/0,
264               pk_sign_verify_opts/0,
265               rsa_digest_type/0,
266               sha1/0,
267               sha2/0
268             ]).
269
270-export_type([engine_ref/0,
271              key_id/0,
272              password/0
273             ]).
274
275%%% Opaque types must be exported :(
276-export_type([
277              stream_state/0,
278              hmac_state/0,
279              hash_state/0,
280              crypto_state/0,
281              mac_state/0
282             ]).
283
284%% Private. For tests.
285-export([packed_openssl_version/4, engine_methods_convert_to_bitmask/2,
286	 get_test_engine/0]).
287-export([rand_plugin_aes_jump_2pow20/1]).
288
289-deprecated({rand_uniform, 2, "use rand:uniform/1 instead"}).
290
291%% This should correspond to the similar macro in crypto.c
292-define(MAX_BYTES_TO_NIF, 20000). %%  Current value is: erlang:system_info(context_reductions) * 10
293
294%% Used by strong_rand_float/0
295-define(HALF_DBL_EPSILON, 1.1102230246251565e-16). % math:pow(2, -53)
296
297
298%%% ===== BEGIN NEW TYPING ====
299
300%%% Basic
301-type key_integer() :: integer() | binary(). % Always binary() when used as return value
302
303%%% Keys
304-type rsa_public() :: [key_integer()] . % [E, N]
305-type rsa_private() :: [key_integer()] . % [E, N, D] | [E, N, D, P1, P2, E1, E2, C]
306-type rsa_params() :: {ModulusSizeInBits::integer(), PublicExponent::key_integer()} .
307
308-type dss_public() :: [key_integer()] . % [P, Q, G, Y]
309-type dss_private() :: [key_integer()] . % [P, Q, G, X]
310
311-type ecdsa_public()  :: key_integer() .
312-type ecdsa_private() :: key_integer() .
313-type ecdsa_params()  :: ec_named_curve() | ec_explicit_curve() .
314
315-type eddsa_public()  :: key_integer() .
316-type eddsa_private() :: key_integer() .
317-type eddsa_params()  :: edwards_curve_ed() .
318
319-type srp_public() :: key_integer() .
320-type srp_private() :: key_integer() .
321-type srp_gen_params()  :: {user,srp_user_gen_params()}  | {host,srp_host_gen_params()}.
322-type srp_comp_params() :: {user,srp_user_comp_params()} | {host,srp_host_comp_params()}.
323-type srp_user_gen_params() :: list(binary() | atom() | list()) .
324-type srp_host_gen_params() :: list(binary() | atom() | list()) .
325-type srp_user_comp_params() :: list(binary() | atom()) .
326-type srp_host_comp_params() :: list(binary() | atom()) .
327
328-type dh_public() :: key_integer() .
329-type dh_private() :: key_integer() .
330-type dh_params() :: [key_integer()] . % [P, G] | [P, G, PrivateKeyBitLength]
331
332-type ecdh_public()  :: key_integer() .
333-type ecdh_private() :: key_integer() .
334-type ecdh_params()  :: ec_named_curve() | edwards_curve_dh() | ec_explicit_curve() .
335
336
337%%% Curves
338
339-type ec_explicit_curve() :: {Field :: ec_field(),
340                              Curve :: ec_curve(),
341                              BasePoint :: binary(),
342                              Order :: binary(),
343                              CoFactor :: none | % FIXME: Really?
344                                          binary()
345                             } .
346
347-type ec_curve() :: {A :: binary(),
348                     B :: binary(),
349                     Seed :: none | binary()
350                    } .
351
352-type ec_field() ::  ec_prime_field() | ec_characteristic_two_field() .
353
354-type ec_prime_field()              :: {prime_field, Prime :: integer()} .
355-type ec_characteristic_two_field() :: {characteristic_two_field, M :: integer(), Basis :: ec_basis()} .
356
357-type ec_basis() :: {tpbasis, K :: non_neg_integer()}
358                  | {ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()}
359                  |  onbasis .
360
361-type ec_named_curve() :: brainpoolP160r1
362                        | brainpoolP160t1
363                        | brainpoolP192r1
364                        | brainpoolP192t1
365                        | brainpoolP224r1
366                        | brainpoolP224t1
367                        | brainpoolP256r1
368                        | brainpoolP256t1
369                        | brainpoolP320r1
370                        | brainpoolP320t1
371                        | brainpoolP384r1
372                        | brainpoolP384t1
373                        | brainpoolP512r1
374                        | brainpoolP512t1
375                        | c2pnb163v1
376                        | c2pnb163v2
377                        | c2pnb163v3
378                        | c2pnb176v1
379                        | c2pnb208w1
380                        | c2pnb272w1
381                        | c2pnb304w1
382                        | c2pnb368w1
383                        | c2tnb191v1
384                        | c2tnb191v2
385                        | c2tnb191v3
386                        | c2tnb239v1
387                        | c2tnb239v2
388                        | c2tnb239v3
389                        | c2tnb359v1
390                        | c2tnb431r1
391                        | ipsec3
392                        | ipsec4
393                        | prime192v1
394                        | prime192v2
395                        | prime192v3
396                        | prime239v1
397                        | prime239v2
398                        | prime239v3
399                        | prime256v1
400                        | secp112r1
401                        | secp112r2
402                        | secp128r1
403                        | secp128r2
404                        | secp160k1
405                        | secp160r1
406                        | secp160r2
407                        | secp192k1
408                        | secp192r1
409                        | secp224k1
410                        | secp224r1
411                        | secp256k1
412                        | secp256r1
413                        | secp384r1
414                        | secp521r1
415                        | sect113r1
416                        | sect113r2
417                        | sect131r1
418                        | sect131r2
419                        | sect163k1
420                        | sect163r1
421                        | sect163r2
422                        | sect193r1
423                        | sect193r2
424                        | sect233k1
425                        | sect233r1
426                        | sect239k1
427                        | sect283k1
428                        | sect283r1
429                        | sect409k1
430                        | sect409r1
431                        | sect571k1
432                        | sect571r1
433                        | wtls1
434                        | wtls10
435                        | wtls11
436                        | wtls12
437                        | wtls3
438                        | wtls4
439                        | wtls5
440                        | wtls6
441                        | wtls7
442                        | wtls8
443                        | wtls9
444                          .
445
446-type edwards_curve_dh() :: x25519 | x448 .
447
448-type edwards_curve_ed() :: ed25519 | ed448 .
449
450%%%----------------------------------------------------------------
451%%% New cipher schema
452%%%
453-type cipher() :: cipher_no_iv()
454                | cipher_iv()
455                | cipher_aead() .
456
457-type cipher_no_iv() :: aes_128_ecb
458                      | aes_192_ecb
459                      | aes_256_ecb
460
461                      | blowfish_ecb
462                      | des_ecb
463                      | rc4 .
464
465-type cipher_iv() :: aes_128_cbc
466                   | aes_192_cbc
467                   | aes_256_cbc
468
469                   | aes_128_cfb128
470                   | aes_192_cfb128
471                   | aes_256_cfb128
472
473                   | aes_128_cfb8
474                   | aes_192_cfb8
475                   | aes_256_cfb8
476
477                   | aes_128_ctr
478                   | aes_192_ctr
479                   | aes_256_ctr
480
481                   | aes_ige256
482
483                   | blowfish_cbc
484                   | blowfish_cfb64
485                   | blowfish_ofb64
486                   | chacha20
487                   | des_ede3_cbc
488                   | des_ede3_cfb
489
490                   | des_cbc
491                   | des_cfb
492                   | rc2_cbc .
493
494
495-type cipher_aead() :: aes_128_ccm
496                     | aes_192_ccm
497                     | aes_256_ccm
498
499                     | aes_128_gcm
500                     | aes_192_gcm
501                     | aes_256_gcm
502
503                     | chacha20_poly1305 .
504
505
506%%%----------------------------------------------------------------
507%%% Old cipher scheme
508%%%
509%%%
510-type block_cipher_without_iv() :: ecb_cipher() .
511
512-type block_cipher_with_iv() :: cbc_cipher()
513                              | cfb_cipher()
514                              | blowfish_ofb64
515                              | aes_ige256 .
516
517-type stream_cipher() :: ctr_cipher()
518                       | chacha20
519                       | rc4 .
520
521
522%%%----
523-type cbc_cipher()  :: aes_128_cbc
524                     | aes_192_cbc
525                     | aes_256_cbc
526                     | blowfish_cbc
527                     | des_cbc
528                     | des_ede3_cbc
529                     | rc2_cbc
530                     | retired_cbc_cipher_aliases() .
531
532-type retired_cbc_cipher_aliases() :: aes_cbc      % aes_*_cbc
533                                    | aes_cbc128   % aes_128_cbc
534                                    | aes_cbc256   % aes_256_cbc
535                                    | des3_cbc     % des_ede3_cbc
536                                    | des_ede3 .   % des_ede3_cbc
537
538%%%----
539-type cfb_cipher() :: aes_128_cfb128
540                    | aes_192_cfb128
541                    | aes_256_cfb128
542                    | aes_128_cfb8
543                    | aes_192_cfb8
544                    | aes_256_cfb8
545                    | blowfish_cfb64
546                    | des_cfb
547                    | des_ede3_cfb
548                    | retired_cfb_cipher_aliases() .
549
550-type retired_cfb_cipher_aliases() :: aes_cfb8      % aes_*_cfb8
551                                    | aes_cfb128    % aes_*_cfb128
552                                    | des3_cbf      % des_ede3_cfb, cfb misspelled
553                                    | des3_cfb      % des_ede3_cfb
554                                    | des_ede3_cbf .% cfb misspelled
555
556
557%%%----
558-type ctr_cipher() :: aes_128_ctr
559                    | aes_192_ctr
560                    | aes_256_ctr
561                    | retired_ctr_cipher_aliases() .
562
563-type retired_ctr_cipher_aliases() :: aes_ctr .  % aes_*_ctr
564
565%%%----
566-type ecb_cipher() :: aes_128_ecb
567                    | aes_192_ecb
568                    | aes_256_ecb
569                    | blowfish_ecb
570                    | retired_ecb_cipher_aliases() .
571
572-type retired_ecb_cipher_aliases() :: aes_ecb .
573
574%%%----
575-type aead_cipher() :: aes_gcm | aes_ccm | chacha20_poly1305 .
576
577
578%%%----- end old cipher schema ------------------------------------
579%%%----------------------------------------------------------------
580
581-type key() :: iodata().
582-type des3_key() :: [key()].
583
584%%%
585-type rsa_digest_type()   :: sha1() | sha2() | md5 | ripemd160 .
586-type dss_digest_type()   :: sha1() | sha2() .
587-type ecdsa_digest_type() :: sha1() | sha2() .
588
589-type sha1() :: sha .
590-type sha2() :: sha224 | sha256 | sha384 | sha512 .
591-type sha3() :: sha3_224 | sha3_256 | sha3_384 | sha3_512 .
592-type blake2() :: blake2b | blake2s .
593
594-type compatibility_only_hash() :: md5 | md4 .
595
596-type crypto_integer() :: binary() | integer().
597
598%%%
599%% Exceptions
600%%   error:badarg
601%%   error:notsup
602-type run_time_error() :: any().
603
604%% Exceptions
605%%   error:{badarg,Reason::term()}
606%%   error:{notsup,Reason::term()}
607%%   error:{error,Reason::term()}
608-type descriptive_error() :: any() .
609
610
611%%--------------------------------------------------------------------
612%%
613%% Make the new descriptive_error() look like the old run_time_error()
614%%
615-define(COMPAT(CALL),
616        try begin CALL end
617        catch
618            error:{error, {_File,_Line}, _Reason} ->
619                error(badarg);
620            error:{E, {_File,_Line}, _Reason} when E==notsup ; E==badarg ->
621                error(E)
622        end).
623
624%%--------------------------------------------------------------------
625-compile(no_native).
626-on_load(on_load/0).
627-define(CRYPTO_NIF_VSN,302).
628
629-define(nif_stub,nif_stub_error(?LINE)).
630nif_stub_error(Line) ->
631    erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}).
632
633%%--------------------------------------------------------------------
634%%% API
635%%--------------------------------------------------------------------
636%% Crypto app version history:
637%% (no version): Driver implementation
638%% 2.0         : NIF implementation, requires OTP R14
639
640%% When generating documentation from crypto.erl, the macro ?CRYPTO_VSN is not defined.
641%% That causes the doc generation to stop...
642-ifndef(CRYPTO_VSN).
643-define(CRYPTO_VSN, "??").
644-endif.
645version() -> ?CRYPTO_VSN.
646
647-spec start() -> ok | {error, Reason::term()}.
648start() ->
649    application:start(crypto).
650
651-spec stop() -> ok | {error, Reason::term()}.
652stop() ->
653    application:stop(crypto).
654
655-spec supports() -> [Support]
656                        when Support :: {hashs,   Hashs}
657                                      | {ciphers, Ciphers}
658                                      | {public_keys, PKs}
659                                      | {macs,    Macs}
660                                      | {curves,  Curves}
661                                      | {rsa_opts, RSAopts},
662                             Hashs :: [sha1() | sha2() | sha3() | blake2() | ripemd160 | compatibility_only_hash()],
663                             Ciphers :: [cipher()],
664                             PKs :: [rsa | dss | ecdsa | dh | ecdh | eddh | ec_gf2m],
665                             Macs :: [hmac | cmac | poly1305],
666                             Curves :: [ec_named_curve() | edwards_curve_dh() | edwards_curve_ed()],
667                             RSAopts :: [rsa_sign_verify_opt() | rsa_opt()] .
668supports() ->
669     [{hashs,       supports(hashs)},
670      {ciphers,     prepend_old_aliases(supports(ciphers))}
671      | [{T,supports(T)} || T <- [public_keys,
672                                  macs,
673                                  curves,
674                                  rsa_opts]
675        ]
676     ].
677
678
679-spec supports(Type) -> Support
680                        when Type :: hashs
681			           | ciphers
682                                   | public_keys
683                                   | macs
684                                   | curves
685                                   | rsa_opts,
686			     Support :: Hashs
687                                      | Ciphers
688                                      | PKs
689                                      | Macs
690                                      | Curves
691                                      | RSAopts,
692                             Hashs :: [sha1() | sha2() | sha3() | blake2() | ripemd160 | compatibility_only_hash()],
693                             Ciphers :: [cipher()],
694                             PKs :: [rsa | dss | ecdsa | dh | ecdh | eddh | ec_gf2m],
695                             Macs :: [hmac | cmac | poly1305],
696                             Curves :: [ec_named_curve() | edwards_curve_dh() | edwards_curve_ed()],
697                             RSAopts :: [rsa_sign_verify_opt() | rsa_opt()] .
698
699-define(CURVES, '$curves$').
700
701supports(hashs)       -> hash_algorithms();
702supports(public_keys) -> pubkey_algorithms();
703supports(ciphers)     -> cipher_algorithms();
704supports(macs)        -> mac_algorithms();
705supports(curves)      -> curve_algorithms();
706supports(rsa_opts)    -> rsa_opts_algorithms().
707
708
709-spec info_lib() -> [{Name,VerNum,VerStr}] when Name :: binary(),
710                                                VerNum :: integer(),
711                                                VerStr :: binary() .
712info_lib() -> ?nif_stub.
713
714-spec info_fips() -> not_supported | not_enabled | enabled.
715
716info_fips() -> ?nif_stub.
717
718-spec enable_fips_mode(Enable) -> Result when Enable :: boolean(),
719                                              Result :: boolean().
720enable_fips_mode(Enable) ->
721    enable_fips_mode_nif(Enable).
722
723enable_fips_mode_nif(_) -> ?nif_stub.
724
725%%%================================================================
726%%%
727%%% Compare in constant time
728%%%
729%%%================================================================
730
731%%% Candidate for a NIF
732
733equal_const_time(X1, X2) ->
734    equal_const_time(X1, X2, true).
735
736
737equal_const_time(<<B1,R1/binary>>, <<B2,R2/binary>>, Truth) ->
738    equal_const_time(R1, R2, Truth and (B1 == B2));
739equal_const_time(<<_,R1/binary>>, <<>>, Truth) ->
740    equal_const_time(R1, <<>>, Truth and false);
741equal_const_time(<<>>, <<>>, Truth) ->
742    Truth;
743
744equal_const_time([H1|T1], [H2|T2], Truth) ->
745    equal_const_time(T1, T2, Truth and (H1 == H2));
746equal_const_time([_|T1], [], Truth) ->
747    equal_const_time(T1, [], Truth and false);
748equal_const_time([], [], Truth) ->
749    Truth;
750
751equal_const_time(_, _, _) ->
752    false.
753
754%%%================================================================
755%%%
756%%% Hashing
757%%%
758%%%================================================================
759
760-type hash_algorithm() :: sha1() | sha2() | sha3() | blake2() | ripemd160 | compatibility_only_hash() .
761
762-spec hash_info(Type) -> Result | run_time_error()
763                             when Type :: hash_algorithm(),
764                                  Result :: #{size := integer(),
765                                              block_size := integer(),
766                                              type := integer()
767                                             } .
768hash_info(Type) ->
769    notsup_to_error(hash_info_nif(Type)).
770
771-spec hash(Type, Data) -> Digest when Type :: hash_algorithm(),
772                                      Data :: iodata(),
773                                      Digest :: binary().
774hash(Type, Data) ->
775    Data1 = iolist_to_binary(Data),
776    MaxBytes = max_bytes(),
777    hash(Type, Data1, erlang:byte_size(Data1), MaxBytes).
778
779-opaque hash_state() :: reference().
780
781-spec hash_init(Type) -> State when Type :: hash_algorithm(),
782                                    State :: hash_state().
783hash_init(Type) ->
784    notsup_to_error(hash_init_nif(Type)).
785
786-spec hash_update(State, Data) -> NewState when State :: hash_state(),
787                                                NewState :: hash_state(),
788                                                Data :: iodata() .
789hash_update(Context, Data) ->
790    Data1 = iolist_to_binary(Data),
791    MaxBytes = max_bytes(),
792    hash_update(Context, Data1, erlang:byte_size(Data1), MaxBytes).
793
794-spec hash_final(State) -> Digest when  State :: hash_state(),
795                                        Digest :: binary().
796hash_final(Context) ->
797    notsup_to_error(hash_final_nif(Context)).
798
799%%%================================================================
800%%%
801%%% MACs (Message Authentication Codes)
802%%%
803%%%================================================================
804
805-type hmac_hash_algorithm() ::  sha1() | sha2() | sha3() | compatibility_only_hash().
806
807-type cmac_cipher_algorithm() :: aes_128_cbc | aes_192_cbc | aes_256_cbc | blowfish_cbc
808                               | des_cbc | des_ede3_cbc | rc2_cbc
809                               | aes_128_cfb128 | aes_192_cfb128 | aes_256_cfb128
810                               | aes_128_cfb8 | aes_192_cfb8 | aes_256_cfb8
811                                 .
812
813%%%----------------------------------------------------------------
814%%% Calculate MAC for the whole text at once
815
816-spec mac(Type :: poly1305, Key, Data) -> Mac | descriptive_error()
817                     when Key :: iodata(),
818                          Data :: iodata(),
819                          Mac :: binary().
820
821mac(poly1305, Key, Data) -> mac(poly1305, undefined, Key, Data).
822
823
824-spec mac(Type, SubType, Key, Data) -> Mac | descriptive_error()
825                     when Type :: hmac | cmac | poly1305,
826                          SubType :: hmac_hash_algorithm() | cmac_cipher_algorithm() | undefined,
827                          Key :: iodata(),
828                          Data :: iodata(),
829                          Mac :: binary().
830
831mac(Type, SubType, Key, Data) -> mac_nif(Type, SubType, Key, Data).
832
833
834
835-spec macN(Type :: poly1305, Key, Data, MacLength) -> Mac | descriptive_error()
836                     when Key :: iodata(),
837                          Data :: iodata(),
838                          Mac :: binary(),
839                          MacLength :: pos_integer().
840
841macN(Type, Key, Data, MacLength) ->
842    macN(Type, undefined, Key, Data, MacLength).
843
844
845-spec macN(Type, SubType, Key, Data, MacLength) -> Mac | descriptive_error()
846                     when Type :: hmac | cmac | poly1305,
847                          SubType :: hmac_hash_algorithm() | cmac_cipher_algorithm() | undefined,
848                          Key :: iodata(),
849                          Data :: iodata(),
850                          Mac :: binary(),
851                          MacLength :: pos_integer().
852
853macN(Type, SubType, Key, Data, MacLength) ->
854    erlang:binary_part(mac(Type,SubType,Key,Data), 0, MacLength).
855
856
857%%%----------------------------------------------------------------
858%%% Calculate the MAC by uppdating by pieces of the text
859
860-opaque mac_state() :: reference() .
861
862-spec mac_init(Type :: poly1305, Key) -> State | descriptive_error()
863                          when Key :: iodata(),
864                               State :: mac_state() .
865mac_init(poly1305, Key) ->
866    mac_init_nif(poly1305, undefined, Key).
867
868
869-spec mac_init(Type, SubType, Key) -> State | descriptive_error()
870                          when Type :: hmac | cmac | poly1305,
871                               SubType :: hmac_hash_algorithm() | cmac_cipher_algorithm() | undefined,
872                               Key :: iodata(),
873                               State :: mac_state() .
874mac_init(Type, SubType, Key) ->
875    mac_init_nif(Type, SubType, Key).
876
877
878-spec mac_update(State0, Data) -> State | descriptive_error()
879                     when Data :: iodata(),
880                          State0 :: mac_state(),
881                          State :: mac_state().
882mac_update(Ref, Data) ->
883    mac_update_nif(Ref, Data).
884
885
886
887-spec mac_final(State) -> Mac | descriptive_error()
888                              when State :: mac_state(),
889                                   Mac :: binary().
890mac_final(Ref) ->
891    mac_final_nif(Ref).
892
893
894-spec mac_finalN(State, MacLength) -> Mac | descriptive_error()
895                              when State :: mac_state(),
896                                   MacLength :: pos_integer(),
897                                   Mac :: binary().
898mac_finalN(Ref, MacLength) ->
899    erlang:binary_part(mac_final(Ref), 0, MacLength).
900
901
902%%%----------------------------------------------------------------
903%%% NIFs for the functions above
904
905mac_nif(_Type, _SubType, _Key, _Data) -> ?nif_stub.
906
907mac_init_nif(_Type, _SubType, _Key) -> ?nif_stub.
908mac_update_nif(_Ref, _Data) -> ?nif_stub.
909mac_final_nif(_Ref) -> ?nif_stub.
910
911%%%================================================================
912%%%
913%%% The "Old API", kept for compatibility
914%%%
915%%%================================================================
916
917%%%----------------------------------------------------------------
918%%%----------------------------------------------------------------
919%%% Message Authentication Codes, MAC
920%%%
921
922%%%---- HMAC
923
924%%%---- hmac/3,4
925
926-spec hmac(Type, Key, Data) ->
927                  Mac when Type :: hmac_hash_algorithm(),
928                           Key :: iodata(),
929                           Data :: iodata(),
930                           Mac :: binary() .
931hmac(Type, Key, Data) ->
932    ?COMPAT(mac(hmac, Type, Key, Data)).
933
934-spec hmac(Type, Key, Data, MacLength) ->
935                  Mac when Type :: hmac_hash_algorithm(),
936                           Key :: iodata(),
937                           Data :: iodata(),
938                           MacLength :: integer(),
939                           Mac :: binary() .
940
941hmac(Type, Key, Data, MacLength) ->
942    ?COMPAT(macN(hmac, Type, Key, Data, MacLength)).
943
944%%%---- hmac_init, hamc_update, hmac_final
945
946-opaque hmac_state() :: mac_state(). % Was: binary().
947
948-spec hmac_init(Type, Key) ->
949                       State when Type :: hmac_hash_algorithm(),
950                                  Key :: iodata(),
951                                  State :: hmac_state() .
952hmac_init(Type, Key) ->
953    ?COMPAT(mac_init(hmac, Type, Key)).
954
955%%%---- hmac_update
956
957-spec hmac_update(State, Data) -> NewState when Data :: iodata(),
958                                                State :: hmac_state(),
959                                                NewState :: hmac_state().
960hmac_update(State, Data) ->
961    ?COMPAT(mac_update(State, Data)).
962
963%%%---- hmac_final
964
965-spec hmac_final(State) -> Mac when State :: hmac_state(),
966                                    Mac :: binary().
967hmac_final(Context) ->
968    ?COMPAT(mac_final(Context)).
969
970-spec hmac_final_n(State, HashLen) -> Mac when State :: hmac_state(),
971                                               HashLen :: integer(),
972                                               Mac :: binary().
973hmac_final_n(Context, HashLen) ->
974    ?COMPAT(mac_finalN(Context, HashLen)).
975
976%%%---- CMAC
977
978-define(CMAC_CIPHER_ALGORITHM, cbc_cipher() | cfb_cipher() | blowfish_cbc | des_ede3 | rc2_cbc ).
979
980-spec cmac(Type, Key, Data) ->
981                  Mac when Type :: ?CMAC_CIPHER_ALGORITHM,
982                           Key :: iodata(),
983                           Data :: iodata(),
984                           Mac :: binary().
985cmac(Type, Key, Data) ->
986    ?COMPAT(mac(cmac, alias(Type), Key, Data)).
987
988-spec cmac(Type, Key, Data, MacLength) ->
989                  Mac when Type :: ?CMAC_CIPHER_ALGORITHM,
990                           Key :: iodata(),
991                           Data :: iodata(),
992                           MacLength :: integer(),
993                           Mac :: binary().
994
995cmac(Type, Key, Data, MacLength) ->
996    ?COMPAT(macN(cmac, alias(Type), Key, Data, MacLength)).
997
998%%%---- POLY1305
999
1000-spec poly1305(iodata(), iodata()) -> Mac when Mac ::  binary().
1001
1002poly1305(Key, Data) ->
1003    ?COMPAT(mac(poly1305, Key, Data)).
1004
1005%%%----------------------------------------------------------------
1006%%%----------------------------------------------------------------
1007%%% Ciphers
1008
1009
1010%%%---- Cipher info
1011-spec cipher_info(Type) -> Result | run_time_error()
1012                               when Type :: cipher(),
1013                                    Result :: #{key_length := integer(),
1014                                                iv_length := integer(),
1015                                                block_size := integer(),
1016                                                mode := CipherModes,
1017                                                type := undefined | integer()
1018                                               },
1019                                    CipherModes :: undefined
1020                                                 | cbc_mode
1021                                                 | ccm_mode
1022                                                 | cfb_mode
1023                                                 | ctr_mode
1024                                                 | ecb_mode
1025                                                 | gcm_mode
1026                                                 | ige_mode
1027                                                 | ocb_mode
1028                                                 | ofb_mode
1029                                                 | wrap_mode
1030                                                 | xts_mode
1031                                                   .
1032
1033%% %% These ciphers are not available via the EVP interface on older cryptolibs.
1034cipher_info(aes_ctr) ->
1035    #{block_size => 1,iv_length => 16,key_length => 32,mode => ctr_mode,type => undefined};
1036cipher_info(aes_128_ctr) ->
1037    #{block_size => 1,iv_length => 16,key_length => 16,mode => ctr_mode,type => undefined};
1038cipher_info(aes_192_ctr) ->
1039    #{block_size => 1,iv_length => 16,key_length => 24,mode => ctr_mode,type => undefined};
1040cipher_info(aes_256_ctr) ->
1041    #{block_size => 1,iv_length => 16,key_length => 32,mode => ctr_mode,type => undefined};
1042%% %% This cipher is handled specialy.
1043cipher_info(aes_ige256) ->
1044    #{block_size => 16,iv_length => 32,key_length => 16,mode => ige_mode,type => undefined};
1045%% %% These ciphers belong to the "old" interface:
1046%% cipher_info(aes_cbc) ->
1047%%     #{block_size => 16,iv_length => 16,key_length => 24,mode => cbc_mode,type => 423};
1048%% cipher_info(aes_cbc128) ->
1049%%     #{block_size => 16,iv_length => 16,key_length => 16,mode => cbc_mode,type => 419};
1050%% cipher_info(aes_cbc256) ->
1051%%     #{block_size => 16,iv_length => 16,key_length => 32,mode => cbc_mode,type => 427};
1052%% cipher_info(aes_ccm) ->
1053%%     #{block_size => 1,iv_length => 12,key_length => 24,mode => ccm_mode,type => 899};
1054%% cipher_info(aes_cfb128) ->
1055%%     #{block_size => 1,iv_length => 16,key_length => 32,mode => cfb_mode,type => 429};
1056%% cipher_info(aes_cfb8) ->
1057%%     #{block_size => 1,iv_length => 16,key_length => 32,mode => cfb_mode,type => 429};
1058%% cipher_info(aes_ecb) ->
1059%%     #{block_size => 16,iv_length => 0,key_length => 24,mode => ecb_mode,type => 422};
1060%% cipher_info(aes_gcm) ->
1061%%     #{block_size => 1,iv_length => 12,key_length => 24,mode => gcm_mode,type => 898};
1062%% cipher_info(des3_cbc) ->
1063%%     #{block_size => 8,iv_length => 8,key_length => 24,mode => cbc_mode,type => 44};
1064%% cipher_info(des3_cbf) ->
1065%%     #{block_size => 1,iv_length => 8,key_length => 24,mode => cfb_mode,type => 30};
1066%% cipher_info(des3_cfb) ->
1067%%     #{block_size => 1,iv_length => 8,key_length => 24,mode => cfb_mode,type => 30};
1068%% cipher_info(des_ede3) ->
1069%%     #{block_size => 8,iv_length => 8,key_length => 24,mode => cbc_mode,type => 44};
1070%% cipher_info(des_ede3_cbf) ->
1071%%     #{block_size => 1,iv_length => 8,key_length => 24,mode => cfb_mode,type => 30};
1072cipher_info(Type) ->
1073    cipher_info_nif(alias(Type)).
1074
1075%%%---- Block ciphers
1076%%%----------------------------------------------------------------
1077-spec block_encrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) ->
1078                           binary() | run_time_error();
1079                   (Type::aead_cipher(),  Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata()}) ->
1080                           {binary(), binary()} | run_time_error();
1081                   (aes_gcm | aes_ccm, Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata(), TagLength::1..16}) ->
1082                           {binary(), binary()} | run_time_error().
1083
1084
1085block_encrypt(aes_ige256, Key, Ivec, PlainText) ->
1086    notsup_to_error(aes_ige_crypt_nif(Key, Ivec, PlainText, true));
1087
1088block_encrypt(Type, Key0, Ivec, Data) ->
1089    Key = iolist_to_binary(Key0),
1090    ?COMPAT(
1091       case Data of
1092           {AAD, PlainText} ->
1093               crypto_one_time_aead(alias(Type,Key), Key, Ivec, PlainText, AAD, true);
1094           {AAD, PlainText, TagLength} ->
1095               crypto_one_time_aead(alias(Type,Key), Key, Ivec, PlainText, AAD, TagLength, true);
1096           PlainText ->
1097               block_crypt(alias(Type,Key), Key, Ivec, PlainText, true)
1098       end).
1099
1100-spec block_encrypt(Type::block_cipher_without_iv(), Key::key(), PlainText::iodata()) ->
1101                           binary() | run_time_error().
1102
1103block_encrypt(Type, Key0, PlainText) ->
1104    Key = iolist_to_binary(Key0),
1105    ?COMPAT(block_crypt(alias(Type,Key), Key, undefined, PlainText, true)).
1106
1107
1108%%%----------------------------------------------------------------
1109%%%----------------------------------------------------------------
1110-spec block_decrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), Data::iodata()) ->
1111                           binary() | run_time_error();
1112		   (Type::aead_cipher(), Key::iodata(), Ivec::binary(),
1113		    {AAD::binary(), Data::iodata(), Tag::binary()}) ->
1114                           binary() | error | run_time_error() .
1115
1116block_decrypt(aes_ige256, Key, Ivec, Data) ->
1117    notsup_to_error(aes_ige_crypt_nif(Key, Ivec, Data, false));
1118
1119block_decrypt(Type, Key0, Ivec, Data) ->
1120    Key = iolist_to_binary(Key0),
1121    ?COMPAT(
1122       case Data of
1123           {AAD, CryptoText, Tag} ->
1124               crypto_one_time_aead(alias(Type,Key), Key, Ivec, CryptoText, AAD, Tag, false);
1125           CryptoText ->
1126               block_crypt(alias(Type,Key), Key, Ivec, CryptoText, false)
1127       end).
1128
1129
1130-spec block_decrypt(Type::block_cipher_without_iv(), Key::key(), Data::iodata()) ->
1131                           binary() | run_time_error().
1132
1133block_decrypt(Type, Key0, CryptoText) ->
1134    Key = iolist_to_binary(Key0),
1135    ?COMPAT(block_crypt(alias(Type,Key), Key, undefined, CryptoText, false)).
1136
1137
1138
1139block_crypt(Cipher, Key, IV, Data, EncryptFlag) ->
1140    Ctx = case IV of
1141              undefined -> crypto_init(Cipher, Key, EncryptFlag);
1142              _ -> crypto_init(Cipher, Key, IV, EncryptFlag)
1143          end,
1144    crypto_update(Ctx, Data).
1145
1146%%%-------- Stream ciphers API
1147
1148-opaque stream_state() :: {stream_cipher(),
1149                           crypto_state() | {crypto_state(),flg_undefined}
1150                          }.
1151
1152%%%---- stream_init
1153-spec stream_init(Type, Key, IVec) -> State | run_time_error()
1154                                          when Type :: stream_cipher(),
1155                                               Key :: iodata(),
1156                                               IVec ::binary(),
1157                                               State :: stream_state() .
1158stream_init(Type, Key0, IVec) when is_binary(IVec) ->
1159    Key = iolist_to_binary(Key0),
1160    Ref = ?COMPAT(ng_crypto_init_nif(alias(Type,Key),
1161                                     Key, iolist_to_binary(IVec),
1162                                     get_crypto_opts([{encrypt,undefined}]))
1163                 ),
1164    {Type, {Ref,flg_undefined}}.
1165
1166
1167-spec stream_init(Type, Key) -> State | run_time_error()
1168                                    when Type :: rc4,
1169                                         Key :: iodata(),
1170                                         State :: stream_state() .
1171stream_init(rc4 = Type, Key0) ->
1172    Key = iolist_to_binary(Key0),
1173    Ref = ?COMPAT(ng_crypto_init_nif(alias(Type,Key),
1174                                     Key, <<>>,
1175                                     get_crypto_opts([{encrypt,undefined}]))
1176                 ),
1177    {Type, {Ref,flg_undefined}}.
1178
1179%%%---- stream_encrypt
1180-spec stream_encrypt(State, PlainText) -> {NewState, CipherText} | run_time_error()
1181                                              when State :: stream_state(),
1182                                                   PlainText :: iodata(),
1183                                                   NewState :: stream_state(),
1184                                                   CipherText :: iodata() .
1185stream_encrypt(State, Data) ->
1186    crypto_stream_emulate(State, Data, true).
1187
1188%%%---- stream_decrypt
1189-spec stream_decrypt(State, CipherText) -> {NewState, PlainText} | run_time_error()
1190                                              when State :: stream_state(),
1191                                                   CipherText :: iodata(),
1192                                                   NewState :: stream_state(),
1193                                                   PlainText :: iodata() .
1194stream_decrypt(State, Data) ->
1195    crypto_stream_emulate(State, Data, false).
1196
1197%%%-------- helpers
1198crypto_stream_emulate({Cipher,{Ref0,flg_undefined}}, Data, EncryptFlag) when is_reference(Ref0) ->
1199    ?COMPAT(begin
1200                Ref = ng_crypto_init_nif(Ref0, <<>>, <<>>,
1201                                     get_crypto_opts([{encrypt,EncryptFlag}])),
1202                {{Cipher,Ref}, crypto_update(Ref, Data)}
1203            end);
1204
1205crypto_stream_emulate({Cipher,Ref}, Data, _) when is_reference(Ref) ->
1206    ?COMPAT({{Cipher,Ref}, crypto_update(Ref, Data)}).
1207
1208%%%----------------------------------------------------------------
1209-spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige,
1210                                           Data :: iodata(),
1211                                           NextIVec :: binary().
1212next_iv(Type, Data) when is_binary(Data) ->
1213    IVecSize = case Type of
1214                   des_cbc  -> 8;
1215                   des3_cbc -> 8;
1216                   aes_cbc  -> 16;
1217                   aes_ige  -> 32
1218               end,
1219    {_, IVec} = split_binary(Data, size(Data) - IVecSize),
1220    IVec;
1221next_iv(Type, Data) when is_list(Data) ->
1222    next_iv(Type, list_to_binary(Data)).
1223
1224-spec next_iv(des_cfb, Data, IVec) -> NextIVec when Data :: iodata(),
1225                                                    IVec :: binary(),
1226                                                    NextIVec :: binary().
1227
1228next_iv(des_cfb, Data, IVec) ->
1229    IVecAndData = list_to_binary([IVec, Data]),
1230    {_, NewIVec} = split_binary(IVecAndData, byte_size(IVecAndData) - 8),
1231    NewIVec;
1232next_iv(Type, Data, _Ivec) ->
1233    next_iv(Type, Data).
1234
1235%%%================================================================
1236%%%
1237%%% Encrypt/decrypt, The "New API"
1238%%%
1239%%%================================================================
1240
1241-opaque crypto_state() :: reference() .
1242
1243-type crypto_opts() :: boolean()
1244                     | [ crypto_opt() ] .
1245-type crypto_opt() :: {encrypt,boolean()}
1246                    | {padding, padding()} .
1247-type padding() :: cryptolib_padding() | otp_padding().
1248-type cryptolib_padding() :: none | pkcs_padding .
1249-type otp_padding() :: zero | random .
1250
1251
1252%%%----------------------------------------------------------------
1253%%%
1254%%% Create and initialize a new state for encryption or decryption
1255%%%
1256
1257-spec crypto_init(Cipher, Key, FlagOrOptions) -> State | descriptive_error()
1258                                                   when Cipher :: cipher_no_iv(),
1259                                                        Key :: iodata(),
1260                                                        FlagOrOptions :: crypto_opts() | boolean(),
1261                                                        State :: crypto_state() .
1262crypto_init(Cipher, Key, FlagOrOptions) ->
1263    ng_crypto_init_nif(Cipher,
1264                       iolist_to_binary(Key),
1265                       <<>>,
1266                       get_crypto_opts(FlagOrOptions)).
1267
1268
1269-spec crypto_init(Cipher, Key, IV, FlagOrOptions) -> State | descriptive_error()
1270                                                       when Cipher :: cipher_iv(),
1271                                                            Key :: iodata(),
1272                                                            IV :: iodata(),
1273                                                            FlagOrOptions :: crypto_opts(),
1274                                                            State :: crypto_state() .
1275crypto_init(Cipher, Key, IV, FlagOrOptions) ->
1276    ng_crypto_init_nif(Cipher,
1277                       iolist_to_binary(Key),
1278                       iolist_to_binary(IV),
1279                       get_crypto_opts(FlagOrOptions)).
1280
1281%%%----------------------------------------------------------------
1282get_crypto_opts(Options) when is_list(Options) ->
1283    lists:foldl(fun chk_opt/2,
1284                #{encrypt => true,
1285                  padding => undefined
1286                 },
1287                Options);
1288get_crypto_opts(Flag) when is_boolean(Flag) ->
1289    #{encrypt => Flag,
1290      padding => undefined
1291     };
1292get_crypto_opts(X) ->
1293    error({badarg,{bad_option,X}}).
1294
1295
1296chk_opt({Tag,Val}, A) ->
1297    case ok_opt(Tag,Val) of
1298        true ->
1299            A#{Tag => Val};
1300        false ->
1301            error({badarg,{bad_option,{Tag,Val}}})
1302    end;
1303chk_opt(X, _) ->
1304    error({badarg,{bad_option,X}}).
1305
1306
1307ok_opt(encrypt, V) -> lists:member(V, [true, false, undefined]);
1308ok_opt(padding, V) -> lists:member(V, [none, pkcs_padding, zero, random, undefined]);
1309ok_opt(_, _) -> false.
1310
1311%%%----------------------------------------------------------------
1312-spec crypto_dyn_iv_init(Cipher, Key, FlagOrOptions) -> State | descriptive_error()
1313                                                          when Cipher :: cipher_iv(),
1314                                                               Key :: iodata(),
1315                                                               FlagOrOptions :: crypto_opts() | boolean(),
1316                                                               State :: crypto_state() .
1317crypto_dyn_iv_init(Cipher, Key, FlagOrOptions) ->
1318    %% The IV is supposed to be supplied by calling crypto_update/3
1319    ng_crypto_init_nif(Cipher,
1320                       iolist_to_binary(Key),
1321                       undefined,
1322                       get_crypto_opts(FlagOrOptions)).
1323
1324%%%----------------------------------------------------------------
1325%%%
1326%%% Encrypt/decrypt a sequence of bytes.  The sum of the sizes
1327%%% of all blocks must be an integer multiple of the crypto's
1328%%% blocksize.
1329%%%
1330
1331-spec crypto_update(State, Data) -> Result | descriptive_error()
1332                            when State :: crypto_state(),
1333                                 Data :: iodata(),
1334                                 Result :: binary() .
1335crypto_update(State, Data) ->
1336    ng_crypto_update_nif(State, iolist_to_binary(Data)).
1337
1338%%%----------------------------------------------------------------
1339-spec crypto_dyn_iv_update(State, Data, IV) -> Result | descriptive_error()
1340                                                   when State :: crypto_state(),
1341                                                        Data :: iodata(),
1342                                                        IV :: iodata(),
1343                                                        Result :: binary() .
1344crypto_dyn_iv_update(State, Data, IV) ->
1345    ng_crypto_update_nif(State, iolist_to_binary(Data), iolist_to_binary(IV)).
1346
1347%%%----------------------------------------------------------------
1348%%%
1349%%% Finalize encrypt/decrypt bytes.  If the size of the bytes in
1350%%% to crypto_uptate was not an integer number of blocks, the rest
1351%%% is returned from this function.
1352
1353-spec crypto_final(State) -> FinalResult | descriptive_error()
1354                            when State :: crypto_state(),
1355                                 FinalResult :: binary() .
1356crypto_final(State) ->
1357    ng_crypto_final_nif(State).
1358
1359%%%----------------------------------------------------------------
1360%%%
1361%%% Get result of padding etc
1362
1363-spec crypto_get_data(State) -> Result
1364                            when State :: crypto_state(),
1365                                 Result :: map() .
1366crypto_get_data(State) ->
1367    ng_crypto_get_data_nif(State).
1368
1369%%%----------------------------------------------------------------
1370%%%
1371%%% Encrypt/decrypt one set bytes.
1372%%% The size must be an integer multiple of the crypto's blocksize.
1373%%%
1374
1375-spec crypto_one_time(Cipher, Key, Data, FlagOrOptions) ->
1376                             Result | descriptive_error()
1377                                 when Cipher :: cipher_no_iv(),
1378                                      Key :: iodata(),
1379                                      Data :: iodata(),
1380                                      FlagOrOptions :: crypto_opts() | boolean(),
1381                                      Result :: binary() .
1382
1383crypto_one_time(Cipher, Key, Data, FlagOrOptions) ->
1384    ng_crypto_one_time_nif(Cipher,
1385                           iolist_to_binary(Key),
1386                           <<>>,
1387                           iolist_to_binary(Data),
1388                           get_crypto_opts(FlagOrOptions)).
1389
1390
1391-spec crypto_one_time(Cipher, Key, IV, Data, FlagOrOptions) ->
1392                             Result | descriptive_error()
1393                                 when Cipher :: cipher_iv(),
1394                                      Key :: iodata(),
1395                                      IV :: iodata(),
1396                                      Data :: iodata(),
1397                                      FlagOrOptions :: crypto_opts() | boolean(),
1398                                      Result :: binary() .
1399
1400crypto_one_time(Cipher, Key, IV, Data, FlagOrOptions) ->
1401    ng_crypto_one_time_nif(Cipher,
1402                           iolist_to_binary(Key),
1403                           iolist_to_binary(IV),
1404                           iolist_to_binary(Data),
1405                           get_crypto_opts(FlagOrOptions)).
1406
1407%%%----------------------------------------------------------------
1408-spec crypto_one_time_aead(Cipher, Key, IV, InText, AAD, EncFlag::true) ->
1409                             Result | descriptive_error()
1410                                 when Cipher :: cipher_aead(),
1411                                      Key :: iodata(),
1412                                      IV :: iodata(),
1413                                      InText :: iodata(),
1414                                      AAD :: iodata(),
1415                                      Result :: EncryptResult,
1416                                      EncryptResult :: {OutCryptoText, OutTag},
1417                                      OutCryptoText :: binary(),
1418                                      OutTag :: binary().
1419
1420crypto_one_time_aead(Cipher, Key, IV, PlainText, AAD, true) ->
1421    crypto_one_time_aead(Cipher, Key, IV, PlainText, AAD, aead_tag_len(Cipher), true).
1422
1423
1424-spec crypto_one_time_aead(Cipher, Key, IV, InText, AAD, TagOrTagLength, EncFlag) ->
1425                             Result | descriptive_error()
1426                                 when Cipher :: cipher_aead(),
1427                                      Key :: iodata(),
1428                                      IV :: iodata(),
1429                                      InText :: iodata(),
1430                                      AAD :: iodata(),
1431                                      TagOrTagLength :: EncryptTagLength | DecryptTag,
1432                                      EncryptTagLength :: non_neg_integer(), % or pos_integer() 1..
1433                                      DecryptTag :: iodata(),
1434                                      EncFlag :: boolean(),
1435                                      Result :: EncryptResult | DecryptResult,
1436                                      EncryptResult :: {OutCryptoText, OutTag},
1437                                      DecryptResult :: OutPlainText | error,
1438                                      OutCryptoText :: binary(),
1439                                      OutTag :: binary(),
1440                                      OutPlainText :: binary().
1441
1442crypto_one_time_aead(Cipher, Key, IV, TextIn, AAD, TagOrTagLength, EncFlg) ->
1443    aead_cipher(Cipher, Key, IV, TextIn, AAD, TagOrTagLength, EncFlg).
1444
1445
1446aead_tag_len(chacha20_poly1305) -> 16;
1447aead_tag_len(aes_ccm    ) -> 12;
1448aead_tag_len(aes_128_ccm) -> 12;
1449aead_tag_len(aes_192_ccm) -> 12;
1450aead_tag_len(aes_256_ccm) -> 12;
1451aead_tag_len(aes_gcm    ) -> 16;
1452aead_tag_len(aes_128_gcm) -> 16;
1453aead_tag_len(aes_192_gcm) -> 16;
1454aead_tag_len(aes_256_gcm) -> 16;
1455aead_tag_len(_) -> error({badarg, "Not an AEAD cipher"}).
1456
1457%%%----------------------------------------------------------------
1458%%% NIFs
1459
1460ng_crypto_init_nif(Cipher, Key, IVec, #{encrypt := EncryptFlag,
1461                                        padding := Padding}) ->
1462    ng_crypto_init_nif(Cipher, Key, IVec, EncryptFlag, Padding).
1463
1464ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlag, _Padding) -> ?nif_stub.
1465
1466
1467ng_crypto_update_nif(_State, _Data) -> ?nif_stub.
1468ng_crypto_update_nif(_State, _Data, _IV) -> ?nif_stub.
1469
1470ng_crypto_final_nif(_State) -> ?nif_stub.
1471
1472ng_crypto_get_data_nif(_State) -> ?nif_stub.
1473
1474ng_crypto_one_time_nif(Cipher, Key, IVec, Data,  #{encrypt := EncryptFlag,
1475                                                   padding := Padding}) ->
1476    ng_crypto_one_time_nif(Cipher, Key, IVec, Data, EncryptFlag, Padding).
1477
1478ng_crypto_one_time_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlag, _Padding) -> ?nif_stub.
1479
1480%%%----------------------------------------------------------------
1481%%% Cipher aliases
1482%%%
1483-define(if_also(Cipher, Ciphers, AliasCiphers),
1484        case lists:member(Cipher, Ciphers) of
1485            true ->
1486                AliasCiphers;
1487            false ->
1488                Ciphers
1489        end).
1490
1491
1492prepend_old_aliases(L0) ->
1493    L1 = ?if_also(des_ede3_cbc, L0,
1494                  [des3_cbc, des_ede3, des_ede3_cbf, des3_cbf, des3_cfb | L0]),
1495    L2 = ?if_also(aes_128_cbc, L1,
1496                 [aes_cbc, aes_cbc128, aes_cbc256 | L1]),
1497    L3 = ?if_also(aes_128_ctr, L2,
1498                  [aes_ctr | L2]),
1499    L4 = ?if_also(aes_128_ccm, L3,
1500                  [aes_ccm | L3]),
1501    L5 = ?if_also(aes_128_gcm, L4,
1502                  [aes_gcm | L4]),
1503    L6 = ?if_also(aes_128_cfb8, L5,
1504                  [aes_cfb8 | L5]),
1505    L7 = ?if_also(aes_128_cfb128, L6,
1506                  [aes_cfb128 | L6]),
1507    L8 = ?if_also(aes_128_ecb, L7,
1508                  [aes_ecb | L7]),
1509    L8.
1510
1511
1512
1513%%%---- des_ede3_cbc
1514alias(des3_cbc)     -> des_ede3_cbc;
1515alias(des_ede3)     -> des_ede3_cbc;
1516%%%---- des_ede3_cfb
1517alias(des_ede3_cbf) -> des_ede3_cfb;
1518alias(des3_cbf)     -> des_ede3_cfb;
1519alias(des3_cfb)     -> des_ede3_cfb;
1520%%%---- aes_*_cbc
1521alias(aes_cbc128)   -> aes_128_cbc;
1522alias(aes_cbc256)   -> aes_256_cbc;
1523
1524alias(Alg) -> Alg.
1525
1526
1527alias(Ciph, Key) -> alias2(alias(Ciph), Key).
1528
1529alias2(aes_cbc, Key) when size(Key)==16  -> aes_128_cbc;
1530alias2(aes_cbc, Key) when size(Key)==24  -> aes_192_cbc;
1531alias2(aes_cbc, Key) when size(Key)==32  -> aes_256_cbc;
1532
1533alias2(aes_cfb8, Key) when size(Key)==16  -> aes_128_cfb8;
1534alias2(aes_cfb8, Key) when size(Key)==24  -> aes_192_cfb8;
1535alias2(aes_cfb8, Key) when size(Key)==32  -> aes_256_cfb8;
1536
1537alias2(aes_cfb128, Key) when size(Key)==16  -> aes_128_cfb128;
1538alias2(aes_cfb128, Key) when size(Key)==24  -> aes_192_cfb128;
1539alias2(aes_cfb128, Key) when size(Key)==32  -> aes_256_cfb128;
1540
1541alias2(aes_ctr, Key) when size(Key)==16  -> aes_128_ctr;
1542alias2(aes_ctr, Key) when size(Key)==24  -> aes_192_ctr;
1543alias2(aes_ctr, Key) when size(Key)==32  -> aes_256_ctr;
1544
1545alias2(aes_ecb, Key) when size(Key)==16  -> aes_128_ecb;
1546alias2(aes_ecb, Key) when size(Key)==24  -> aes_192_ecb;
1547alias2(aes_ecb, Key) when size(Key)==32  -> aes_256_ecb;
1548
1549alias2(aes_gcm, Key) when size(Key)==16  -> aes_128_gcm;
1550alias2(aes_gcm, Key) when size(Key)==24  -> aes_192_gcm;
1551alias2(aes_gcm, Key) when size(Key)==32  -> aes_256_gcm;
1552
1553alias2(aes_ccm, Key) when size(Key)==16  -> aes_128_ccm;
1554alias2(aes_ccm, Key) when size(Key)==24  -> aes_192_ccm;
1555alias2(aes_ccm, Key) when size(Key)==32  -> aes_256_ccm;
1556
1557alias2(Alg, _) -> Alg.
1558
1559%%%================================================================
1560%%%
1561%%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib
1562%%%
1563%%%================================================================
1564-type rand_cache_seed() ::
1565        nonempty_improper_list(non_neg_integer(), binary()).
1566
1567-spec strong_rand_bytes(N::non_neg_integer()) -> binary().
1568strong_rand_bytes(Bytes) ->
1569    case strong_rand_bytes_nif(Bytes) of
1570        false -> erlang:error(low_entropy);
1571        Bin -> Bin
1572    end.
1573strong_rand_bytes_nif(_Bytes) -> ?nif_stub.
1574
1575
1576-spec rand_seed() -> rand:state().
1577rand_seed() ->
1578    rand:seed(rand_seed_s()).
1579
1580-spec rand_seed_s() -> rand:state().
1581rand_seed_s() ->
1582    rand_seed_alg_s(?MODULE).
1583
1584-spec rand_seed_alg(Alg :: atom()) ->
1585                           {rand:alg_handler(),
1586                            atom() | rand_cache_seed()}.
1587rand_seed_alg(Alg) ->
1588    rand:seed(rand_seed_alg_s(Alg)).
1589
1590-spec rand_seed_alg(Alg :: atom(), Seed :: term()) ->
1591                           {rand:alg_handler(),
1592                            atom() | rand_cache_seed()}.
1593rand_seed_alg(Alg, Seed) ->
1594    rand:seed(rand_seed_alg_s(Alg, Seed)).
1595
1596-define(CRYPTO_CACHE_BITS, 56).
1597-define(CRYPTO_AES_BITS, 58).
1598
1599-spec rand_seed_alg_s(Alg :: atom()) ->
1600                             {rand:alg_handler(),
1601                              atom() | rand_cache_seed()}.
1602rand_seed_alg_s({AlgHandler, _AlgState} = State) when is_map(AlgHandler) ->
1603    State;
1604rand_seed_alg_s({Alg, AlgState}) when is_atom(Alg) ->
1605    {mk_alg_handler(Alg),AlgState};
1606 rand_seed_alg_s(Alg) when is_atom(Alg) ->
1607    {mk_alg_handler(Alg),mk_alg_state(Alg)}.
1608%%
1609-spec rand_seed_alg_s(Alg :: atom(), Seed :: term()) ->
1610                             {rand:alg_handler(),
1611                              atom() | rand_cache_seed()}.
1612rand_seed_alg_s(Alg, Seed) when is_atom(Alg) ->
1613    {mk_alg_handler(Alg),mk_alg_state({Alg,Seed})}.
1614
1615mk_alg_handler(?MODULE = Alg) ->
1616    #{ type => Alg,
1617       bits => 64,
1618       next => fun ?MODULE:rand_plugin_next/1,
1619       uniform => fun ?MODULE:rand_plugin_uniform/1,
1620       uniform_n => fun ?MODULE:rand_plugin_uniform/2};
1621mk_alg_handler(crypto_cache = Alg) ->
1622    #{ type => Alg,
1623       bits => ?CRYPTO_CACHE_BITS,
1624       next => fun ?MODULE:rand_cache_plugin_next/1};
1625mk_alg_handler(crypto_aes = Alg) ->
1626    #{ type => Alg,
1627       bits => ?CRYPTO_AES_BITS,
1628       next => fun ?MODULE:rand_plugin_aes_next/1,
1629       jump => fun ?MODULE:rand_plugin_aes_jump/1}.
1630
1631mk_alg_state(?MODULE) ->
1632    no_seed;
1633mk_alg_state(crypto_cache) ->
1634    CacheBits = ?CRYPTO_CACHE_BITS,
1635    BytesPerWord = (CacheBits + 7) div 8,
1636    GenBytes =
1637        ((rand_cache_size() + (2*BytesPerWord - 1)) div BytesPerWord)
1638        * BytesPerWord,
1639    {CacheBits, GenBytes, <<>>};
1640mk_alg_state({crypto_aes,Seed}) ->
1641    %% 16 byte words (128 bit crypto blocks)
1642    GenWords = (rand_cache_size() + 31) div 16,
1643    Key = crypto:hash(sha256, Seed),
1644    {F,Count} = longcount_seed(Seed),
1645    {Key,GenWords,F,Count}.
1646
1647rand_cache_size() ->
1648    DefaultCacheSize = 1024,
1649    CacheSize =
1650        application:get_env(crypto, rand_cache_size, DefaultCacheSize),
1651    if
1652        is_integer(CacheSize), 0 =< CacheSize ->
1653            CacheSize;
1654        true ->
1655            DefaultCacheSize
1656    end.
1657
1658rand_plugin_next(Seed) ->
1659    {bytes_to_integer(strong_rand_range(1 bsl 64)), Seed}.
1660
1661rand_plugin_uniform(State) ->
1662    {strong_rand_float(), State}.
1663
1664rand_plugin_uniform(Max, State) ->
1665    {bytes_to_integer(strong_rand_range(Max)) + 1, State}.
1666
1667
1668rand_cache_plugin_next({CacheBits, GenBytes, <<>>}) ->
1669    rand_cache_plugin_next(
1670      {CacheBits, GenBytes, strong_rand_bytes(GenBytes)});
1671rand_cache_plugin_next({CacheBits, GenBytes, Cache}) ->
1672    <<I:CacheBits, NewCache/binary>> = Cache,
1673    {I, {CacheBits, GenBytes, NewCache}}.
1674
1675
1676%% Encrypt 128 bit counter values and use the 58 lowest
1677%% encrypted bits as random numbers.
1678%%
1679%% The 128 bit counter is handled as 4 32 bit words
1680%% to avoid bignums.  Generate a bunch of numbers
1681%% at the time and cache them.
1682%%
1683-dialyzer({no_improper_lists, rand_plugin_aes_next/1}).
1684rand_plugin_aes_next([V|Cache]) ->
1685    {V,Cache};
1686rand_plugin_aes_next({Key,GenWords,F,Count}) ->
1687    rand_plugin_aes_next(Key, GenWords, F, Count);
1688rand_plugin_aes_next({Key,GenWords,F,_JumpBase,Count}) ->
1689    rand_plugin_aes_next(Key, GenWords, F, Count).
1690%%
1691rand_plugin_aes_next(Key, GenWords, F, Count) ->
1692    {Cleartext,NewCount} = aes_cleartext(<<>>, F, Count, GenWords),
1693    Encrypted = block_encrypt(aes_ecb, Key, Cleartext),
1694    [V|Cache] = aes_cache(Encrypted, {Key,GenWords,F,Count,NewCount}),
1695    {V,Cache}.
1696
1697%% A jump advances the counter 2^512 steps; the jump function
1698%% is applied to the jump base and then the number of used
1699%% numbers from the cache has to be wasted for the jump to be correct
1700%%
1701rand_plugin_aes_jump({#{type := crypto_aes} = Alg, Cache}) ->
1702    {Alg,rand_plugin_aes_jump(fun longcount_jump/1, 0, Cache)}.
1703%% Count cached words and subtract their number from jump
1704-dialyzer({no_improper_lists, rand_plugin_aes_jump/3}).
1705rand_plugin_aes_jump(Jump, J, [_|Cache]) ->
1706    rand_plugin_aes_jump(Jump, J + 1, Cache);
1707rand_plugin_aes_jump(Jump, J, {Key,GenWords,F,JumpBase, _Count}) ->
1708    rand_plugin_aes_jump(Jump, GenWords - J, Key, GenWords, F, JumpBase);
1709rand_plugin_aes_jump(Jump, 0, {Key,GenWords,F,JumpBase}) ->
1710    rand_plugin_aes_jump(Jump, 0, Key, GenWords, F, JumpBase).
1711%%
1712rand_plugin_aes_jump(Jump, Skip, Key, GenWords, F, JumpBase) ->
1713    Count = longcount_next_count(Skip, Jump(JumpBase)),
1714    {Key,GenWords,F,Count}.
1715
1716rand_plugin_aes_jump_2pow20(Cache) ->
1717    rand_plugin_aes_jump(fun longcount_jump_2pow20/1, 0, Cache).
1718
1719
1720longcount_seed(Seed) ->
1721    <<X:64, _:6, F:12, S2:58, S1:58, S0:58>> =
1722        crypto:hash(sha256, [Seed,<<"Xoroshiro928">>]),
1723    {F,rand:exro928_seed([S0,S1,S2|rand:seed58(13, X)])}.
1724
1725longcount_next_count(0, Count) ->
1726    Count;
1727longcount_next_count(N, Count) ->
1728    longcount_next_count(N - 1, rand:exro928_next_state(Count)).
1729
1730longcount_next(Count) ->
1731    rand:exro928_next(Count).
1732
1733longcount_jump(Count) ->
1734    rand:exro928_jump_2pow512(Count).
1735
1736longcount_jump_2pow20(Count) ->
1737    rand:exro928_jump_2pow20(Count).
1738
1739
1740%% Build binary with counter values to cache
1741aes_cleartext(Cleartext, _F, Count, 0) ->
1742    {Cleartext,Count};
1743aes_cleartext(Cleartext, F, Count, GenWords) ->
1744    {{S0,S1}, NewCount} = longcount_next(Count),
1745    aes_cleartext(
1746      <<Cleartext/binary, F:12, S1:58, S0:58>>,
1747      F, NewCount, GenWords - 1).
1748
1749%% Parse and cache encrypted counter values aka random numbers
1750-dialyzer({no_improper_lists, aes_cache/2}).
1751aes_cache(<<>>, Cache) ->
1752    Cache;
1753aes_cache(
1754  <<_:(128 - ?CRYPTO_AES_BITS), V:?CRYPTO_AES_BITS, Encrypted/binary>>,
1755  Cache) ->
1756    [V|aes_cache(Encrypted, Cache)].
1757
1758
1759strong_rand_range(Range) when is_integer(Range), Range > 0 ->
1760    BinRange = int_to_bin(Range),
1761    strong_rand_range(BinRange);
1762strong_rand_range(BinRange) when is_binary(BinRange) ->
1763    case strong_rand_range_nif(BinRange) of
1764        false ->
1765            erlang:error(low_entropy);
1766        <<BinResult/binary>> ->
1767            BinResult
1768    end.
1769strong_rand_range_nif(_BinRange) -> ?nif_stub.
1770
1771strong_rand_float() ->
1772    WholeRange = strong_rand_range(1 bsl 53),
1773    ?HALF_DBL_EPSILON * bytes_to_integer(WholeRange).
1774
1775-spec rand_uniform(crypto_integer(), crypto_integer()) ->
1776			  crypto_integer().
1777rand_uniform(From, To) when is_binary(From), is_binary(To) ->
1778    case rand_uniform_nif(From,To) of
1779	<<Len:32/integer, MSB, Rest/binary>> when MSB > 127 ->
1780	    <<(Len + 1):32/integer, 0, MSB, Rest/binary>>;
1781	Whatever ->
1782	    Whatever
1783    end;
1784rand_uniform(From,To) when is_integer(From),is_integer(To) ->
1785    if From < 0 ->
1786	    rand_uniform_pos(0, To - From) + From;
1787       true ->
1788	    rand_uniform_pos(From, To)
1789    end.
1790
1791rand_uniform_pos(From,To) when From < To ->
1792    BinFrom = mpint(From),
1793    BinTo = mpint(To),
1794    case rand_uniform(BinFrom, BinTo) of
1795        Result when is_binary(Result) ->
1796            erlint(Result);
1797        Other ->
1798            Other
1799    end;
1800rand_uniform_pos(_,_) ->
1801    error(badarg).
1802
1803rand_uniform_nif(_From,_To) -> ?nif_stub.
1804
1805
1806-spec rand_seed(binary()) -> ok.
1807rand_seed(Seed) when is_binary(Seed) ->
1808    rand_seed_nif(Seed).
1809
1810rand_seed_nif(_Seed) -> ?nif_stub.
1811
1812%%%================================================================
1813%%%
1814%%% Sign/verify
1815%%%
1816%%%================================================================
1817-type pk_sign_verify_algs() :: rsa | dss | ecdsa | eddsa .
1818
1819-type pk_sign_verify_opts() :: [ rsa_sign_verify_opt() ] .
1820
1821-type rsa_sign_verify_opt() :: {rsa_padding, rsa_sign_verify_padding()}
1822                             | {rsa_pss_saltlen, integer()}
1823                             | {rsa_mgf1_md, sha2()}.
1824
1825-type rsa_sign_verify_padding() :: rsa_pkcs1_padding | rsa_pkcs1_pss_padding
1826                                 | rsa_x931_padding | rsa_no_padding
1827                                   .
1828
1829
1830%%%----------------------------------------------------------------
1831%%% Sign
1832
1833-spec sign(Algorithm, DigestType, Msg, Key)
1834          -> Signature
1835                 when Algorithm :: pk_sign_verify_algs(),
1836                      DigestType :: rsa_digest_type()
1837                                  | dss_digest_type()
1838                                  | ecdsa_digest_type(),
1839                      Msg :: iodata() | {digest,iodata()},
1840                      Key :: rsa_private()
1841                           | dss_private()
1842                           | [ecdsa_private() | ecdsa_params()]
1843                           | [eddsa_private() | eddsa_params()]
1844                           | engine_key_ref(),
1845                      Signature :: binary() .
1846
1847sign(Algorithm, Type, Data, Key) ->
1848    sign(Algorithm, Type, Data, Key, []).
1849
1850
1851-spec sign(Algorithm, DigestType, Msg, Key, Options)
1852          -> Signature
1853                 when Algorithm :: pk_sign_verify_algs(),
1854                      DigestType :: rsa_digest_type()
1855                                  | dss_digest_type()
1856                                  | ecdsa_digest_type()
1857                                  | none,
1858                      Msg :: iodata() | {digest,iodata()},
1859                      Key :: rsa_private()
1860                           | dss_private()
1861                           | [ecdsa_private() | ecdsa_params()]
1862                           | [eddsa_private() | eddsa_params()]
1863                           | engine_key_ref(),
1864                      Options :: pk_sign_verify_opts(),
1865                      Signature :: binary() .
1866
1867sign(Algorithm0, Type0, Data, Key, Options) ->
1868    {Algorithm, Type} = sign_verify_compatibility(Algorithm0, Type0, Data),
1869    case pkey_sign_nif(Algorithm, Type, Data, format_pkey(Algorithm, Key), Options) of
1870	error -> erlang:error(badkey, [Algorithm, Type, Data, Key, Options]);
1871	notsup -> erlang:error(notsup);
1872	Signature -> Signature
1873    end.
1874
1875pkey_sign_nif(_Algorithm, _Type, _Digest, _Key, _Options) -> ?nif_stub.
1876
1877%%%----------------------------------------------------------------
1878%%% Verify
1879
1880-spec verify(Algorithm, DigestType, Msg, Signature, Key)
1881            -> Result
1882                   when Algorithm :: pk_sign_verify_algs(),
1883                        DigestType :: rsa_digest_type()
1884                                    | dss_digest_type()
1885                                    | ecdsa_digest_type()
1886                                    | none,
1887                        Msg :: iodata() | {digest,iodata()},
1888                        Signature :: binary(),
1889                        Key :: rsa_public()
1890                             | dss_public()
1891                             | [ecdsa_public() | ecdsa_params()]
1892                             | [eddsa_public() | eddsa_params()]
1893                             | engine_key_ref(),
1894                        Result :: boolean().
1895
1896verify(Algorithm, Type, Data, Signature, Key) ->
1897    verify(Algorithm, Type, Data, Signature, Key, []).
1898
1899-spec verify(Algorithm, DigestType, Msg, Signature, Key, Options)
1900            -> Result
1901                   when Algorithm :: pk_sign_verify_algs(),
1902                        DigestType :: rsa_digest_type()
1903                                    | dss_digest_type()
1904                                    | ecdsa_digest_type(),
1905                        Msg :: iodata() | {digest,iodata()},
1906                        Signature :: binary(),
1907                        Key :: rsa_public()
1908                             | dss_public()
1909                             | [ecdsa_public() | ecdsa_params()]
1910                             | [eddsa_public() | eddsa_params()]
1911                             | engine_key_ref(),
1912                        Options :: pk_sign_verify_opts(),
1913                        Result :: boolean().
1914
1915verify(Algorithm0, Type0, Data, Signature, Key, Options) ->
1916    {Algorithm, Type} = sign_verify_compatibility(Algorithm0, Type0, Data),
1917    case pkey_verify_nif(Algorithm, Type, Data, Signature, format_pkey(Algorithm, Key), Options) of
1918	notsup -> erlang:error(notsup);
1919	Boolean -> Boolean
1920    end.
1921
1922pkey_verify_nif(_Algorithm, _Type, _Data, _Signature, _Key, _Options) -> ?nif_stub.
1923
1924%% Backwards compatible:
1925sign_verify_compatibility(dss, none, Digest) ->
1926    {sha, {digest, Digest}};
1927sign_verify_compatibility(Algorithm0, Type0, _Digest) ->
1928    {Algorithm0, Type0}.
1929
1930%%%================================================================
1931%%%
1932%%% Public/private encrypt/decrypt
1933%%%
1934%%% Only rsa works so far (although ecdsa | dss should do it)
1935%%%================================================================
1936-type pk_encrypt_decrypt_algs() :: rsa .
1937
1938-type pk_encrypt_decrypt_opts() ::  [rsa_opt()] | rsa_compat_opts().
1939
1940-type rsa_compat_opts() :: [{rsa_pad, rsa_padding()}]
1941                         | rsa_padding() .
1942
1943-type rsa_padding() :: rsa_pkcs1_padding
1944                     | rsa_pkcs1_oaep_padding
1945                     | rsa_sslv23_padding
1946                     | rsa_x931_padding
1947                     | rsa_no_padding.
1948
1949-type rsa_opt() :: {rsa_padding, rsa_padding()}
1950                 | {signature_md, atom()}
1951                 | {rsa_mgf1_md, sha}
1952                 | {rsa_oaep_label, binary()}
1953                 | {rsa_oaep_md, sha} .
1954
1955%%%---- Encrypt with public key
1956
1957-spec public_encrypt(Algorithm, PlainText, PublicKey, Options) ->
1958                            CipherText when Algorithm :: pk_encrypt_decrypt_algs(),
1959                                            PlainText :: binary(),
1960                                            PublicKey :: rsa_public() | engine_key_ref(),
1961                                            Options :: pk_encrypt_decrypt_opts(),
1962                                            CipherText :: binary().
1963public_encrypt(Algorithm, PlainText, PublicKey, Options) ->
1964    pkey_crypt(Algorithm, PlainText, PublicKey, Options, false, true).
1965
1966%%%---- Decrypt with private key
1967
1968-spec private_decrypt(Algorithm, CipherText, PrivateKey, Options) ->
1969                             PlainText when Algorithm :: pk_encrypt_decrypt_algs(),
1970                                            CipherText :: binary(),
1971                                            PrivateKey :: rsa_private() | engine_key_ref(),
1972                                            Options :: pk_encrypt_decrypt_opts(),
1973                                            PlainText :: binary() .
1974private_decrypt(Algorithm, CipherText, PrivateKey, Options) ->
1975    pkey_crypt(Algorithm, CipherText,  PrivateKey, Options, true, false).
1976
1977%%%---- Encrypt with private key
1978
1979-spec private_encrypt(Algorithm, PlainText, PrivateKey, Options) ->
1980                            CipherText when Algorithm :: pk_encrypt_decrypt_algs(),
1981                                            PlainText :: binary(),
1982                                            PrivateKey :: rsa_private() | engine_key_ref(),
1983                                            Options :: pk_encrypt_decrypt_opts(),
1984                                            CipherText :: binary().
1985private_encrypt(Algorithm, PlainText, PrivateKey, Options) ->
1986    pkey_crypt(Algorithm, PlainText,  PrivateKey, Options, true, true).
1987
1988%%%---- Decrypt with public key
1989
1990-spec public_decrypt(Algorithm, CipherText, PublicKey, Options) ->
1991                             PlainText when Algorithm :: pk_encrypt_decrypt_algs(),
1992                                            CipherText :: binary(),
1993                                            PublicKey :: rsa_public() | engine_key_ref(),
1994                                            Options :: pk_encrypt_decrypt_opts(),
1995                                            PlainText :: binary() .
1996public_decrypt(Algorithm, CipherText, PublicKey, Options) ->
1997    pkey_crypt(Algorithm, CipherText, PublicKey, Options, false, false).
1998
1999%%%---- Call the nif, but fix a compatibility issue first
2000
2001%% Backwards compatible (rsa_pad -> rsa_padding is handled by the pkey_crypt_nif):
2002pkey_crypt(rsa, Text, Key, Padding, PubPriv, EncDec) when is_atom(Padding) ->
2003    pkey_crypt(rsa, Text, Key, [{rsa_padding, Padding}], PubPriv, EncDec);
2004
2005pkey_crypt(Alg, Text, Key, Options, PubPriv, EncDec) ->
2006    case pkey_crypt_nif(Alg, Text, format_pkey(Alg,Key), Options, PubPriv, EncDec) of
2007	error when EncDec==true  -> erlang:error(encrypt_failed, [Alg, Text, Key, Options]);
2008	error when EncDec==false -> erlang:error(decrypt_failed, [Alg, Text, Key, Options]);
2009	notsup -> erlang:error(notsup);
2010	Out -> Out
2011    end.
2012
2013pkey_crypt_nif(_Algorithm, _In, _Key, _Options, _IsPrivate, _IsEncrypt) -> ?nif_stub.
2014
2015%%%================================================================
2016%%%
2017%%%
2018%%%
2019%%%================================================================
2020
2021-spec generate_key(Type, Params)
2022                 -> {PublicKey, PrivKeyOut}
2023                        when Type :: dh | ecdh | eddh | eddsa | rsa | srp,
2024                             PublicKey :: dh_public() | ecdh_public() | rsa_public() | srp_public(),
2025                             PrivKeyOut :: dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()},
2026                             Params :: dh_params() | ecdh_params() | eddsa_params() | rsa_params() | srp_gen_params()
2027                                       .
2028generate_key(Type, Params) ->
2029    generate_key(Type, Params, undefined).
2030
2031-spec generate_key(Type, Params, PrivKeyIn)
2032                 -> {PublicKey, PrivKeyOut}
2033                        when Type :: dh | ecdh | eddh | eddsa | rsa | srp,
2034                             PublicKey :: dh_public() | ecdh_public() | rsa_public() | srp_public(),
2035                             PrivKeyIn :: undefined | dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()},
2036                             PrivKeyOut :: dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()},
2037                             Params :: dh_params() | ecdh_params() | eddsa_params() | rsa_params() | srp_comp_params()
2038                                       .
2039
2040generate_key(dh, DHParameters0, PrivateKey) ->
2041    {DHParameters, Len} =
2042        case DHParameters0 of
2043            [P,G,L] -> {[P,G], L};
2044            [P,G] -> {[P,G], 0}
2045        end,
2046    dh_generate_key_nif(ensure_int_as_bin(PrivateKey),
2047			map_ensure_int_as_bin(DHParameters),
2048                        0, Len);
2049
2050generate_key(srp, {host, [Verifier, Generator, Prime, Version]}, PrivArg)
2051  when is_binary(Verifier), is_binary(Generator), is_binary(Prime), is_atom(Version) ->
2052    Private = case PrivArg of
2053		  undefined -> strong_rand_bytes(32);
2054		  _ -> ensure_int_as_bin(PrivArg)
2055	      end,
2056    host_srp_gen_key(Private, Verifier, Generator, Prime, Version);
2057
2058generate_key(srp, {user, [Generator, Prime, Version]}, PrivateArg)
2059  when is_binary(Generator), is_binary(Prime), is_atom(Version) ->
2060    Private = case PrivateArg of
2061		  undefined -> strong_rand_bytes(32);
2062		  _ -> PrivateArg
2063	      end,
2064    user_srp_gen_key(Private, Generator, Prime);
2065
2066generate_key(rsa, {ModulusSize, PublicExponent}, undefined) ->
2067    case rsa_generate_key_nif(ModulusSize, ensure_int_as_bin(PublicExponent)) of
2068        error ->
2069            erlang:error(computation_failed,
2070                         [rsa,{ModulusSize,PublicExponent}]);
2071        Private ->
2072            {lists:sublist(Private, 2), Private}
2073    end;
2074
2075generate_key(eddh, Curve, PrivKey) when Curve == x448 ;
2076                                        Curve == x25519 ->
2077    evp_generate_key_nif(Curve, ensure_int_as_bin(PrivKey));
2078generate_key(ecdh, Curve, PrivKey) when Curve == x448 ;
2079                                        Curve == x25519 ->
2080    %% This was here before the eddh was added as an own Type
2081    evp_generate_key_nif(Curve, ensure_int_as_bin(PrivKey));
2082generate_key(ecdh, Curve, PrivKey) ->
2083    ec_key_generate(nif_curve_params(Curve), ensure_int_as_bin(PrivKey));
2084
2085generate_key(eddsa, Curve, PrivKey) when Curve == ed448 ;
2086                                         Curve == ed25519 ->
2087    evp_generate_key_nif(Curve, ensure_int_as_bin(PrivKey)).
2088
2089evp_generate_key_nif(_Curve, _PrivKey) -> ?nif_stub.
2090
2091
2092-spec compute_key(Type, OthersPublicKey, MyPrivateKey, Params)
2093                 -> SharedSecret
2094                        when Type :: dh | ecdh | eddh |  srp,
2095                             SharedSecret :: binary(),
2096                             OthersPublicKey :: dh_public() | ecdh_public() | srp_public(),
2097                             MyPrivateKey :: dh_private() | ecdh_private() | {srp_public(),srp_private()},
2098                             Params :: dh_params() | ecdh_params() | srp_comp_params()
2099                                       .
2100
2101compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) ->
2102    case dh_compute_key_nif(ensure_int_as_bin(OthersPublicKey),
2103			    ensure_int_as_bin(MyPrivateKey),
2104			    map_ensure_int_as_bin(DHParameters)) of
2105	error -> erlang:error(computation_failed,
2106			      [dh,OthersPublicKey,MyPrivateKey,DHParameters]);
2107	Ret -> Ret
2108    end;
2109
2110compute_key(srp, HostPublic, {UserPublic, UserPrivate},
2111	    {user, [DerivedKey, Prime, Generator, Version | ScramblerArg]}) when
2112      is_binary(Prime),
2113      is_binary(Generator),
2114      is_atom(Version) ->
2115    HostPubBin = ensure_int_as_bin(HostPublic),
2116    Multiplier = srp_multiplier(Version, Generator, Prime),
2117    Scrambler = case ScramblerArg of
2118		    [] -> srp_scrambler(Version, ensure_int_as_bin(UserPublic),
2119					HostPubBin, Prime);
2120		    [S] -> S
2121		end,
2122    notsup_to_error(
2123    srp_user_secret_nif(ensure_int_as_bin(UserPrivate), Scrambler, HostPubBin,
2124                          Multiplier, Generator, DerivedKey, Prime));
2125
2126compute_key(srp, UserPublic, {HostPublic, HostPrivate},
2127	    {host,[Verifier, Prime, Version | ScramblerArg]}) when
2128      is_binary(Verifier),
2129      is_binary(Prime),
2130      is_atom(Version) ->
2131    UserPubBin = ensure_int_as_bin(UserPublic),
2132    Scrambler = case ScramblerArg of
2133		    [] -> srp_scrambler(Version, UserPubBin, ensure_int_as_bin(HostPublic), Prime);
2134		    [S] -> S
2135		end,
2136    notsup_to_error(
2137    srp_host_secret_nif(Verifier, ensure_int_as_bin(HostPrivate), Scrambler,
2138                          UserPubBin, Prime));
2139
2140compute_key(ecdh, Others, My, Curve) when Curve == x448 ;
2141                                          Curve == x25519 ->
2142    evp_compute_key_nif(Curve, ensure_int_as_bin(Others), ensure_int_as_bin(My));
2143
2144compute_key(eddh, Others, My, Curve) when Curve == x448 ;
2145                                          Curve == x25519 ->
2146    evp_compute_key_nif(Curve, ensure_int_as_bin(Others), ensure_int_as_bin(My));
2147
2148compute_key(ecdh, Others, My, Curve) ->
2149    ecdh_compute_key_nif(ensure_int_as_bin(Others),
2150			 nif_curve_params(Curve),
2151			 ensure_int_as_bin(My)).
2152
2153
2154evp_compute_key_nif(_Curve, _OthersBin, _MyBin) -> ?nif_stub.
2155
2156
2157%%%================================================================
2158%%%
2159%%% XOR - xor to iolists and return a binary
2160%%% NB doesn't check that they are the same size, just concatenates
2161%%% them and sends them to the driver
2162%%%
2163%%%================================================================
2164
2165-spec exor(iodata(), iodata()) -> binary().
2166
2167exor(Bin1, Bin2) ->
2168    Data1 = iolist_to_binary(Bin1),
2169    Data2 = iolist_to_binary(Bin2),
2170    MaxBytes = max_bytes(),
2171    exor(Data1, Data2, erlang:byte_size(Data1), MaxBytes, []).
2172
2173
2174%%%================================================================
2175%%%
2176%%% Exponentiation modulo
2177%%%
2178%%%================================================================
2179
2180-spec mod_pow(N, P, M) -> Result when N :: binary() | integer(),
2181                                      P :: binary() | integer(),
2182                                      M :: binary() | integer(),
2183                                      Result :: binary() | error .
2184mod_pow(Base, Exponent, Prime) ->
2185    case mod_exp_nif(ensure_int_as_bin(Base), ensure_int_as_bin(Exponent), ensure_int_as_bin(Prime), 0) of
2186	<<0>> -> error;
2187	R -> R
2188    end.
2189
2190%%%======================================================================
2191%%%
2192%%% Engine functions
2193%%%
2194%%%======================================================================
2195
2196%%%---- Refering to keys stored in an engine:
2197-type key_id()   :: string() | binary() .
2198-type password() :: string() | binary() .
2199
2200-type engine_key_ref() :: #{engine :=   engine_ref(),
2201                            key_id :=   key_id(),
2202                            password => password(),
2203                            term() => term()
2204                           }.
2205
2206%%%---- Commands:
2207-type engine_cmnd() :: {unicode:chardata(), unicode:chardata()}.
2208
2209%%----------------------------------------------------------------------
2210%% Function: engine_get_all_methods/0
2211%%----------------------------------------------------------------------
2212-type engine_method_type() :: engine_method_rsa | engine_method_dsa | engine_method_dh |
2213                              engine_method_rand | engine_method_ecdh | engine_method_ecdsa |
2214                              engine_method_ciphers | engine_method_digests | engine_method_store |
2215                              engine_method_pkey_meths | engine_method_pkey_asn1_meths |
2216                              engine_method_ec.
2217
2218-type engine_ref() :: term().
2219
2220-spec engine_get_all_methods() -> Result when Result :: [engine_method_type()].
2221engine_get_all_methods() ->
2222     notsup_to_error(engine_get_all_methods_nif()).
2223
2224%%----------------------------------------------------------------------
2225%% Function: engine_load/3
2226%%----------------------------------------------------------------------
2227-spec engine_load(EngineId, PreCmds, PostCmds) ->
2228                         Result when EngineId::unicode:chardata(),
2229                                     PreCmds::[engine_cmnd()],
2230                                     PostCmds::[engine_cmnd()],
2231                                     Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
2232engine_load(EngineId, PreCmds, PostCmds) when is_list(PreCmds),
2233                                              is_list(PostCmds) ->
2234    engine_load(EngineId, PreCmds, PostCmds, engine_get_all_methods()).
2235
2236%%----------------------------------------------------------------------
2237%% Function: engine_load/4
2238%%----------------------------------------------------------------------
2239-spec engine_load(EngineId, PreCmds, PostCmds, EngineMethods) ->
2240                         Result when EngineId::unicode:chardata(),
2241                                     PreCmds::[engine_cmnd()],
2242                                     PostCmds::[engine_cmnd()],
2243                                     EngineMethods::[engine_method_type()],
2244                                     Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
2245engine_load(EngineId, PreCmds, PostCmds, EngineMethods) when is_list(PreCmds),
2246                                                             is_list(PostCmds) ->
2247    try
2248        ok = notsup_to_error(engine_load_dynamic_nif()),
2249        case notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId))) of
2250            {ok, Engine} ->
2251                engine_load_1(Engine, PreCmds, PostCmds, EngineMethods);
2252            {error, Error1} ->
2253                {error, Error1}
2254        end
2255    catch
2256        throw:Error2 ->
2257            Error2
2258    end.
2259
2260engine_load_1(Engine, PreCmds, PostCmds, EngineMethods) ->
2261    try
2262        ok = engine_nif_wrapper(engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds(PreCmds), 0)),
2263        ok = engine_nif_wrapper(engine_init_nif(Engine)),
2264        engine_load_2(Engine, PostCmds, EngineMethods),
2265        {ok, Engine}
2266    catch
2267        throw:Error ->
2268            %% The engine couldn't initialise, release the structural reference
2269            ok = engine_free_nif(Engine),
2270            throw(Error);
2271        error:badarg ->
2272            %% For example bad argument list, release the structural reference
2273            ok = engine_free_nif(Engine),
2274            error(badarg)
2275    end.
2276
2277engine_load_2(Engine, PostCmds, EngineMethods) ->
2278    try
2279        ok = engine_nif_wrapper(engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds(PostCmds), 0)),
2280        [ok = engine_nif_wrapper(engine_register_nif(Engine, engine_method_atom_to_int(Method))) ||
2281            Method <- EngineMethods],
2282        ok
2283    catch
2284       throw:Error ->
2285          %% The engine registration failed, release the functional reference
2286          ok = engine_finish_nif(Engine),
2287          throw(Error)
2288    end.
2289
2290%%----------------------------------------------------------------------
2291%% Function: engine_unload/1
2292%%----------------------------------------------------------------------
2293-spec engine_unload(Engine) -> Result when Engine :: engine_ref(),
2294                                           Result :: ok | {error, Reason::term()}.
2295engine_unload(Engine) ->
2296    engine_unload(Engine, engine_get_all_methods()).
2297
2298-spec engine_unload(Engine, EngineMethods) -> Result when Engine :: engine_ref(),
2299                                                          EngineMethods :: [engine_method_type()],
2300                                                          Result :: ok | {error, Reason::term()}.
2301engine_unload(Engine, EngineMethods) ->
2302    try
2303        [ok = engine_nif_wrapper(engine_unregister_nif(Engine, engine_method_atom_to_int(Method))) ||
2304            Method <- EngineMethods],
2305        %% Release the functional reference from engine_init_nif
2306        ok = engine_nif_wrapper(engine_finish_nif(Engine)),
2307        %% Release the structural reference from engine_by_id_nif
2308        ok = engine_nif_wrapper(engine_free_nif(Engine))
2309    catch
2310       throw:Error ->
2311          Error
2312    end.
2313
2314%%----------------------------------------------------------------------
2315%% Function: engine_by_id/1
2316%%----------------------------------------------------------------------
2317-spec engine_by_id(EngineId) -> Result when EngineId :: unicode:chardata(),
2318                                            Result :: {ok, Engine::engine_ref()} | {error, Reason::term()} .
2319engine_by_id(EngineId) ->
2320    try
2321        notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId)))
2322    catch
2323       throw:Error ->
2324          Error
2325    end.
2326
2327%%----------------------------------------------------------------------
2328%% Function: engine_add/1
2329%%----------------------------------------------------------------------
2330-spec engine_add(Engine) -> Result when Engine :: engine_ref(),
2331                                        Result ::  ok | {error, Reason::term()} .
2332engine_add(Engine) ->
2333    notsup_to_error(engine_add_nif(Engine)).
2334
2335%%----------------------------------------------------------------------
2336%% Function: engine_remove/1
2337%%----------------------------------------------------------------------
2338-spec engine_remove(Engine) -> Result when Engine :: engine_ref(),
2339                                           Result ::  ok | {error, Reason::term()} .
2340engine_remove(Engine) ->
2341    notsup_to_error(engine_remove_nif(Engine)).
2342
2343%%----------------------------------------------------------------------
2344%% Function: engine_get_id/1
2345%%----------------------------------------------------------------------
2346-spec engine_get_id(Engine) -> EngineId when Engine :: engine_ref(),
2347                                             EngineId :: unicode:chardata().
2348engine_get_id(Engine) ->
2349    notsup_to_error(engine_get_id_nif(Engine)).
2350
2351%%----------------------------------------------------------------------
2352%% Function: engine_get_name/1
2353%%----------------------------------------------------------------------
2354-spec engine_get_name(Engine) -> EngineName when Engine :: engine_ref(),
2355                                                 EngineName :: unicode:chardata().
2356engine_get_name(Engine) ->
2357    notsup_to_error(engine_get_name_nif(Engine)).
2358
2359%%----------------------------------------------------------------------
2360%% Function: engine_list/0
2361%%----------------------------------------------------------------------
2362-spec engine_list() -> Result when Result :: [EngineId::unicode:chardata()].
2363engine_list() ->
2364    case notsup_to_error(engine_get_first_nif()) of
2365        {ok, <<>>} ->
2366            [];
2367        {ok, Engine} ->
2368            case notsup_to_error(engine_get_id_nif(Engine)) of
2369                <<>> ->
2370                    engine_list(Engine, []);
2371                EngineId ->
2372                    engine_list(Engine, [EngineId])
2373            end
2374    end.
2375
2376engine_list(Engine0, IdList) ->
2377    case notsup_to_error(engine_get_next_nif(Engine0)) of
2378        {ok, <<>>} ->
2379            lists:reverse(IdList);
2380        {ok, Engine1} ->
2381            case notsup_to_error(engine_get_id_nif(Engine1)) of
2382                <<>> ->
2383                    engine_list(Engine1, IdList);
2384                EngineId ->
2385                    engine_list(Engine1, [EngineId |IdList])
2386            end
2387    end.
2388
2389%%----------------------------------------------------------------------
2390%% Function: engine_ctrl_cmd_string/3
2391%%----------------------------------------------------------------------
2392-spec engine_ctrl_cmd_string(Engine, CmdName, CmdArg) ->
2393                                    Result when Engine::term(),
2394                                                CmdName::unicode:chardata(),
2395                                                CmdArg::unicode:chardata(),
2396                                                Result :: ok | {error, Reason::term()}.
2397engine_ctrl_cmd_string(Engine, CmdName, CmdArg) ->
2398    engine_ctrl_cmd_string(Engine, CmdName, CmdArg, false).
2399
2400%%----------------------------------------------------------------------
2401%% Function: engine_ctrl_cmd_string/4
2402%%----------------------------------------------------------------------
2403-spec engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) ->
2404                                    Result when Engine::term(),
2405                                                CmdName::unicode:chardata(),
2406                                                CmdArg::unicode:chardata(),
2407                                                Optional::boolean(),
2408                                                Result :: ok | {error, Reason::term()}.
2409engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) ->
2410    case engine_ctrl_cmd_strings_nif(Engine,
2411                                     ensure_bin_cmds([{CmdName, CmdArg}]),
2412                                     bool_to_int(Optional)) of
2413        ok ->
2414            ok;
2415        notsup ->
2416            erlang:error(notsup);
2417        {error, Error} ->
2418            {error, Error}
2419    end.
2420
2421%%----------------------------------------------------------------------
2422%% Function: ensure_engine_loaded/2
2423%% Special version of load that only uses dynamic engine to load
2424%%----------------------------------------------------------------------
2425-spec ensure_engine_loaded(EngineId, LibPath) ->
2426                                  Result when EngineId :: unicode:chardata(),
2427                                              LibPath :: unicode:chardata(),
2428                                              Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
2429ensure_engine_loaded(EngineId, LibPath) ->
2430    ensure_engine_loaded(EngineId, LibPath, engine_get_all_methods()).
2431
2432%%----------------------------------------------------------------------
2433%% Function: ensure_engine_loaded/3
2434%% Special version of load that only uses dynamic engine to load
2435%%----------------------------------------------------------------------
2436-spec ensure_engine_loaded(EngineId, LibPath, EngineMethods) ->
2437                                  Result when EngineId :: unicode:chardata(),
2438                                              LibPath :: unicode:chardata(),
2439                                              EngineMethods :: [engine_method_type()],
2440                                              Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
2441ensure_engine_loaded(EngineId, LibPath, EngineMethods) ->
2442    try
2443        List = crypto:engine_list(),
2444        case lists:member(EngineId, List) of
2445            true ->
2446                notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId)));
2447            false ->
2448                ok = notsup_to_error(engine_load_dynamic_nif()),
2449                case notsup_to_error(engine_by_id_nif(ensure_bin_chardata(<<"dynamic">>))) of
2450                    {ok, Engine} ->
2451                        PreCommands = [{<<"SO_PATH">>, ensure_bin_chardata(LibPath)},
2452                                       {<<"ID">>, ensure_bin_chardata(EngineId)},
2453                                       <<"LOAD">>],
2454                        ensure_engine_loaded_1(Engine, PreCommands, EngineMethods);
2455                    {error, Error1} ->
2456                        {error, Error1}
2457                end
2458        end
2459    catch
2460        throw:Error2 ->
2461            Error2
2462    end.
2463
2464ensure_engine_loaded_1(Engine, PreCmds, Methods) ->
2465    try
2466        ok = engine_nif_wrapper(engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds(PreCmds), 0)),
2467        ok = engine_nif_wrapper(engine_add_nif(Engine)),
2468        ok = engine_nif_wrapper(engine_init_nif(Engine)),
2469        ensure_engine_loaded_2(Engine, Methods),
2470        {ok, Engine}
2471    catch
2472        throw:Error ->
2473            %% The engine couldn't initialise, release the structural reference
2474            ok = engine_free_nif(Engine),
2475            throw(Error)
2476    end.
2477
2478ensure_engine_loaded_2(Engine, Methods) ->
2479    try
2480        [ok = engine_nif_wrapper(engine_register_nif(Engine, engine_method_atom_to_int(Method))) ||
2481            Method <- Methods],
2482        ok
2483    catch
2484       throw:Error ->
2485          %% The engine registration failed, release the functional reference
2486          ok = engine_finish_nif(Engine),
2487          throw(Error)
2488    end.
2489%%----------------------------------------------------------------------
2490%% Function: ensure_engine_unloaded/1
2491%%----------------------------------------------------------------------
2492-spec ensure_engine_unloaded(Engine) -> Result when Engine :: engine_ref(),
2493                                                    Result :: ok | {error, Reason::term()}.
2494ensure_engine_unloaded(Engine) ->
2495    ensure_engine_unloaded(Engine, engine_get_all_methods()).
2496
2497%%----------------------------------------------------------------------
2498%% Function: ensure_engine_unloaded/2
2499%%----------------------------------------------------------------------
2500-spec ensure_engine_unloaded(Engine, EngineMethods) ->
2501                                    Result when Engine :: engine_ref(),
2502                                                EngineMethods :: [engine_method_type()],
2503                                                Result :: ok | {error, Reason::term()}.
2504ensure_engine_unloaded(Engine, EngineMethods) ->
2505    case engine_remove(Engine) of
2506        ok ->
2507            engine_unload(Engine, EngineMethods);
2508        {error, E} ->
2509            {error, E}
2510    end.
2511
2512%%--------------------------------------------------------------------
2513%%% On load
2514%%--------------------------------------------------------------------
2515on_load() ->
2516    LibBaseName = "crypto",
2517    PrivDir = code:priv_dir(crypto),
2518    LibName = case erlang:system_info(build_type) of
2519		  opt ->
2520		      LibBaseName;
2521		  Type ->
2522		      LibTypeName = LibBaseName ++ "."  ++ atom_to_list(Type),
2523		      case (filelib:wildcard(
2524			      filename:join(
2525				[PrivDir,
2526				 "lib",
2527				 LibTypeName ++ "*"])) /= []) orelse
2528			  (filelib:wildcard(
2529			     filename:join(
2530			       [PrivDir,
2531				"lib",
2532				erlang:system_info(system_architecture),
2533				LibTypeName ++ "*"])) /= []) of
2534			  true -> LibTypeName;
2535			  false -> LibBaseName
2536		      end
2537	      end,
2538    Lib = filename:join([PrivDir, "lib", LibName]),
2539    LibBin   = path2bin(Lib),
2540    FipsMode = application:get_env(crypto, fips_mode, false) == true,
2541    Status = case erlang:load_nif(Lib, {?CRYPTO_NIF_VSN,LibBin,FipsMode}) of
2542		 ok -> ok;
2543		 {error, {load_failed, _}}=Error1 ->
2544		     ArchLibDir =
2545			 filename:join([PrivDir, "lib",
2546					erlang:system_info(system_architecture)]),
2547		     Candidate =
2548			 filelib:wildcard(filename:join([ArchLibDir,LibName ++ "*" ]),erl_prim_loader),
2549		     case Candidate of
2550			 [] -> Error1;
2551			 _ ->
2552			     ArchLib = filename:join([ArchLibDir, LibName]),
2553                             ArchBin = path2bin(ArchLib),
2554			     erlang:load_nif(ArchLib, {?CRYPTO_NIF_VSN,ArchBin,FipsMode})
2555		     end;
2556		 Error1 -> Error1
2557	     end,
2558    case Status of
2559	ok -> ok;
2560	{error, {E, Str}} ->
2561            Fmt = "Unable to load crypto library. Failed with error:~n\"~p, ~s\"~n~s",
2562            Extra = case E of
2563                        load_failed ->
2564                            "OpenSSL might not be installed on this system.\n";
2565                        _ -> ""
2566                    end,
2567	    error_logger:error_msg(Fmt, [E,Str,Extra]),
2568	    Status
2569    end.
2570
2571path2bin(Path) when is_list(Path) ->
2572    Encoding = file:native_name_encoding(),
2573    case unicode:characters_to_binary(Path,Encoding,Encoding) of
2574	Bin when is_binary(Bin) ->
2575	    Bin
2576    end.
2577
2578%%%================================================================
2579%%%================================================================
2580%%%
2581%%% Internal functions
2582%%%
2583%%%================================================================
2584
2585max_bytes() ->
2586    ?MAX_BYTES_TO_NIF.
2587
2588notsup_to_error(notsup) ->
2589    erlang:error(notsup);
2590notsup_to_error(Other) ->
2591    Other.
2592
2593%% HASH --------------------------------------------------------------------
2594hash(Hash, Data, Size, Max) when Size =< Max ->
2595    notsup_to_error(hash_nif(Hash, Data));
2596hash(Hash, Data, Size, Max) ->
2597    State0 = hash_init(Hash),
2598    State1 = hash_update(State0, Data, Size, Max),
2599    hash_final(State1).
2600
2601hash_update(State, Data, Size, MaxBytes)  when Size =< MaxBytes ->
2602    notsup_to_error(hash_update_nif(State, Data));
2603hash_update(State0, Data, _, MaxBytes) ->
2604    <<Increment:MaxBytes/binary, Rest/binary>> = Data,
2605    State = notsup_to_error(hash_update_nif(State0, Increment)),
2606    hash_update(State, Rest, erlang:byte_size(Rest), MaxBytes).
2607
2608hash_info_nif(_Hash) -> ?nif_stub.
2609hash_nif(_Hash, _Data) -> ?nif_stub.
2610hash_init_nif(_Hash) -> ?nif_stub.
2611hash_update_nif(_State, _Data) -> ?nif_stub.
2612hash_final_nif(_State) -> ?nif_stub.
2613
2614%% CIPHERS --------------------------------------------------------------------
2615
2616cipher_info_nif(_Type) -> ?nif_stub.
2617
2618%%
2619%% AES - in Galois/Counter Mode (GCM)
2620%%
2621%% The default tag length is EVP_GCM_TLS_TAG_LEN(16),
2622aead_cipher(_Type, _Key, _Ivec, _AAD, _In, _TagOrTagLength, _EncFlg) -> ?nif_stub.
2623
2624%%
2625%% AES - with 256 bit key in infinite garble extension mode (IGE)
2626%%
2627
2628aes_ige_crypt_nif(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub.
2629
2630%%%================================================================
2631
2632%% Secure remote password  -------------------------------------------------------------------
2633
2634user_srp_gen_key(Private, Generator, Prime) ->
2635    %% Ensure the SRP algorithm is disabled in FIPS mode
2636    case info_fips() of
2637        enabled -> erlang:error(notsup);
2638        _       -> ok
2639    end,
2640    case mod_pow(Generator, Private, Prime) of
2641	error ->
2642	    error;
2643	Public ->
2644	    {Public, Private}
2645    end.
2646
2647host_srp_gen_key(Private, Verifier, Generator, Prime, Version) ->
2648 Multiplier = srp_multiplier(Version, Generator, Prime),
2649   case srp_value_B_nif(Multiplier, Verifier, Generator, Private, Prime) of
2650   error ->
2651       error;
2652   notsup ->
2653       erlang:error(notsup);
2654   Public ->
2655       {Public, Private}
2656   end.
2657
2658srp_multiplier('6a', Generator, Prime) ->
2659    %% k = SHA1(N | PAD(g)) from http://srp.stanford.edu/design.html
2660    C0 = hash_init(sha),
2661    C1 = hash_update(C0, Prime),
2662    C2 = hash_update(C1, srp_pad_to(erlang:byte_size(Prime), Generator)),
2663    hash_final(C2);
2664srp_multiplier('6', _, _) ->
2665    <<3/integer>>;
2666srp_multiplier('3', _, _) ->
2667    <<1/integer>>.
2668
2669srp_scrambler(Version, UserPublic, HostPublic, Prime) when Version == '6'; Version == '6a'->
2670    %% SHA1(PAD(A) | PAD(B)) from http://srp.stanford.edu/design.html
2671    PadLength = erlang:byte_size(Prime),
2672    C0 = hash_init(sha),
2673    C1 = hash_update(C0, srp_pad_to(PadLength, UserPublic)),
2674    C2 = hash_update(C1, srp_pad_to(PadLength, HostPublic)),
2675    hash_final(C2);
2676srp_scrambler('3', _, HostPublic, _Prime) ->
2677    %% The parameter u is a 32-bit unsigned integer which takes its value
2678    %% from the first 32 bits of the SHA1 hash of B, MSB first.
2679    <<U:32/bits, _/binary>> = hash(sha, HostPublic),
2680    U.
2681
2682srp_pad_length(Width, Length) ->
2683    (Width - Length rem Width) rem Width.
2684
2685srp_pad_to(Width, Binary) ->
2686    case srp_pad_length(Width, size(Binary)) of
2687        0 -> Binary;
2688        N -> << 0:(N*8), Binary/binary>>
2689    end.
2690
2691srp_host_secret_nif(_Verifier, _B, _U, _A, _Prime) -> ?nif_stub.
2692
2693srp_user_secret_nif(_A, _U, _B, _Multiplier, _Generator, _Exponent, _Prime) -> ?nif_stub.
2694
2695srp_value_B_nif(_Multiplier, _Verifier, _Generator, _Exponent, _Prime) -> ?nif_stub.
2696
2697
2698%% Public Keys  --------------------------------------------------------------------
2699%% RSA Rivest-Shamir-Adleman functions
2700%%
2701
2702rsa_generate_key_nif(_Bits, _Exp) -> ?nif_stub.
2703
2704%% DH Diffie-Hellman functions
2705%%
2706
2707%% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()]
2708%% PrivKey = mpint()
2709dh_generate_key_nif(_PrivateKey, _DHParameters, _Mpint, _Length) -> ?nif_stub.
2710
2711%% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()]
2712%% MyPrivKey, OthersPublicKey = mpint()
2713dh_compute_key_nif(_OthersPublicKey, _MyPrivateKey, _DHParameters) -> ?nif_stub.
2714
2715ec_key_generate(_Curve, _Key) -> ?nif_stub.
2716
2717ecdh_compute_key_nif(_Others, _Curve, _My) -> ?nif_stub.
2718
2719-spec ec_curves() -> [EllipticCurve] when EllipticCurve :: ec_named_curve()
2720                                                         | edwards_curve_dh()
2721                                                         | edwards_curve_ed() .
2722
2723ec_curves() ->
2724    crypto_ec_curves:curves().
2725
2726-spec ec_curve(CurveName) -> ExplicitCurve when CurveName :: ec_named_curve(),
2727                                                ExplicitCurve :: ec_explicit_curve() .
2728ec_curve(X) ->
2729    crypto_ec_curves:curve(X).
2730
2731
2732-spec privkey_to_pubkey(Type, EnginePrivateKeyRef) -> PublicKey when Type :: rsa | dss,
2733                                                                     EnginePrivateKeyRef :: engine_key_ref(),
2734                                                                     PublicKey ::  rsa_public() | dss_public() .
2735privkey_to_pubkey(Alg, EngineMap) when Alg == rsa; Alg == dss; Alg == ecdsa ->
2736    try privkey_to_pubkey_nif(Alg, format_pkey(Alg,EngineMap))
2737    of
2738        [_|_]=L -> map_ensure_bin_as_int(L);
2739        X -> X
2740    catch
2741        error:badarg when Alg==ecdsa ->
2742            {error, notsup};
2743        error:badarg ->
2744            {error, not_found};
2745        error:notsup ->
2746            {error, notsup}
2747    end.
2748
2749privkey_to_pubkey_nif(_Alg, _EngineMap) -> ?nif_stub.
2750
2751
2752%%
2753%% EC
2754%%
2755
2756term_to_nif_prime({prime_field, Prime}) ->
2757    {prime_field, ensure_int_as_bin(Prime)};
2758term_to_nif_prime(PrimeField) ->
2759    PrimeField.
2760
2761term_to_nif_curve({A, B, Seed}) ->
2762    {ensure_int_as_bin(A), ensure_int_as_bin(B), Seed}.
2763
2764nif_curve_params({PrimeField, Curve, BasePoint, Order, CoFactor}) ->
2765    {term_to_nif_prime(PrimeField),
2766     term_to_nif_curve(Curve),
2767     ensure_int_as_bin(BasePoint),
2768     ensure_int_as_bin(Order),
2769     ensure_int_as_bin(CoFactor)};
2770nif_curve_params(Curve) when is_atom(Curve) ->
2771    %% named curve
2772    case Curve of
2773        x448 -> {evp,Curve};
2774        x25519 -> {evp,Curve};
2775        _ -> crypto_ec_curves:curve(Curve)
2776    end.
2777
2778
2779%% MISC --------------------------------------------------------------------
2780
2781exor(Data1, Data2, Size, MaxByts, [])  when Size =< MaxByts ->
2782    do_exor(Data1, Data2);
2783exor(Data1, Data2, Size, MaxByts, Acc) when Size =< MaxByts ->
2784    Result = do_exor(Data1, Data2),
2785    list_to_binary(lists:reverse([Result | Acc]));
2786exor(Data1, Data2, _Size, MaxByts, Acc) ->
2787     <<Increment1:MaxByts/binary, Rest1/binary>> = Data1,
2788     <<Increment2:MaxByts/binary, Rest2/binary>> = Data2,
2789    Result = do_exor(Increment1, Increment2),
2790    exor(Rest1, Rest2, erlang:byte_size(Rest1), MaxByts, [Result | Acc]).
2791
2792do_exor(_A, _B) -> ?nif_stub.
2793
2794hash_algorithms() -> ?nif_stub.
2795pubkey_algorithms() -> ?nif_stub.
2796cipher_algorithms() -> ?nif_stub.
2797mac_algorithms() -> ?nif_stub.
2798curve_algorithms() -> ?nif_stub.
2799rsa_opts_algorithms() -> ?nif_stub.
2800
2801
2802int_to_bin(X) when X < 0 -> int_to_bin_neg(X, []);
2803int_to_bin(X) -> int_to_bin_pos(X, []).
2804
2805int_to_bin_pos(0,Ds=[_|_]) ->
2806    list_to_binary(Ds);
2807int_to_bin_pos(X,Ds) ->
2808    int_to_bin_pos(X bsr 8, [(X band 255)|Ds]).
2809
2810int_to_bin_neg(-1, Ds=[MSB|_]) when MSB >= 16#80 ->
2811    list_to_binary(Ds);
2812int_to_bin_neg(X,Ds) ->
2813    int_to_bin_neg(X bsr 8, [(X band 255)|Ds]).
2814
2815-spec bytes_to_integer(binary()) -> integer() .
2816bytes_to_integer(Bin) ->
2817    bin_to_int(Bin).
2818
2819bin_to_int(Bin) when is_binary(Bin) ->
2820    Bits = bit_size(Bin),
2821    <<Integer:Bits/integer>> = Bin,
2822    Integer;
2823bin_to_int(undefined) ->
2824    undefined.
2825
2826map_ensure_int_as_bin([H|_]=List) when is_integer(H) ->
2827    lists:map(fun(E) -> int_to_bin(E) end, List);
2828map_ensure_int_as_bin(List) ->
2829    List.
2830
2831ensure_int_as_bin(Int) when is_integer(Int) ->
2832    int_to_bin(Int);
2833ensure_int_as_bin(Bin) ->
2834    Bin.
2835
2836map_ensure_bin_as_int(List) when is_list(List) ->
2837    lists:map(fun ensure_bin_as_int/1, List).
2838
2839ensure_bin_as_int(Bin) when is_binary(Bin) ->
2840    bin_to_int(Bin);
2841ensure_bin_as_int(E) ->
2842    E.
2843
2844format_pkey(_Alg, #{engine:=_, key_id:=T}=M) when is_binary(T) -> format_pwd(M);
2845format_pkey(_Alg, #{engine:=_, key_id:=T}=M) when is_list(T) -> format_pwd(M#{key_id:=list_to_binary(T)});
2846format_pkey(_Alg, #{engine:=_           }=M) -> error({bad_key_id, M});
2847format_pkey(_Alg, #{}=M) -> error({bad_engine_map, M});
2848%%%
2849format_pkey(rsa, Key) ->
2850    map_ensure_int_as_bin(Key);
2851format_pkey(ecdsa, [Key, Curve]) ->
2852    {nif_curve_params(Curve), ensure_int_as_bin(Key)};
2853format_pkey(dss, Key) ->
2854    map_ensure_int_as_bin(Key);
2855format_pkey(_, Key) ->
2856    Key.
2857
2858format_pwd(#{password := Pwd}=M) when is_list(Pwd) -> M#{password := list_to_binary(Pwd)};
2859format_pwd(M) -> M.
2860
2861%%--------------------------------------------------------------------
2862%%
2863
2864%% large integer in a binary with 32bit length
2865%% MP representaion  (SSH2)
2866mpint(X) when X < 0 -> mpint_neg(X);
2867mpint(X) -> mpint_pos(X).
2868
2869-define(UINT32(X),   X:32/unsigned-big-integer).
2870
2871
2872mpint_neg(X) ->
2873    Bin = int_to_bin_neg(X, []),
2874    Sz = byte_size(Bin),
2875    <<?UINT32(Sz), Bin/binary>>.
2876
2877mpint_pos(X) ->
2878    Bin = int_to_bin_pos(X, []),
2879    <<MSB,_/binary>> = Bin,
2880    Sz = byte_size(Bin),
2881    if MSB band 16#80 == 16#80 ->
2882	    <<?UINT32((Sz+1)), 0, Bin/binary>>;
2883       true ->
2884	    <<?UINT32(Sz), Bin/binary>>
2885    end.
2886
2887%% int from integer in a binary with 32bit length
2888erlint(<<MPIntSize:32/integer,MPIntValue/binary>>) ->
2889    Bits= MPIntSize * 8,
2890    <<Integer:Bits/integer>> = MPIntValue,
2891    Integer.
2892
2893%%
2894%% mod_exp - utility for rsa generation and SRP
2895%%
2896mod_exp_nif(_Base,_Exp,_Mod,_bin_hdr) -> ?nif_stub.
2897
2898%%%----------------------------------------------------------------
2899%% 9470495 == V(0,9,8,zh).
2900%% 268435615 == V(1,0,0,i).
2901%% 268439663 == V(1,0,1,f).
2902
2903packed_openssl_version(MAJ, MIN, FIX, P0) ->
2904    %% crypto.c
2905    P1 = atom_to_list(P0),
2906    P = lists:sum([C-$a||C<-P1]),
2907    ((((((((MAJ bsl 8) bor MIN) bsl 8 ) bor FIX) bsl 8) bor (P+1)) bsl 4) bor 16#f).
2908
2909%%--------------------------------------------------------------------
2910%% Engine nifs
2911engine_by_id_nif(_EngineId) -> ?nif_stub.
2912engine_init_nif(_Engine) -> ?nif_stub.
2913engine_finish_nif(_Engine) -> ?nif_stub.
2914engine_free_nif(_Engine) -> ?nif_stub.
2915engine_load_dynamic_nif() -> ?nif_stub.
2916engine_ctrl_cmd_strings_nif(_Engine, _Cmds, _Optional) -> ?nif_stub.
2917engine_add_nif(_Engine)  -> ?nif_stub.
2918engine_remove_nif(_Engine)  -> ?nif_stub.
2919engine_register_nif(_Engine, _EngineMethod) -> ?nif_stub.
2920engine_unregister_nif(_Engine, _EngineMethod) -> ?nif_stub.
2921engine_get_first_nif() -> ?nif_stub.
2922engine_get_next_nif(_Engine) -> ?nif_stub.
2923engine_get_id_nif(_Engine) -> ?nif_stub.
2924engine_get_name_nif(_Engine) -> ?nif_stub.
2925engine_get_all_methods_nif() -> ?nif_stub.
2926
2927%%--------------------------------------------------------------------
2928%% Engine internals
2929engine_nif_wrapper(ok) ->
2930    ok;
2931engine_nif_wrapper(notsup) ->
2932    erlang:error(notsup);
2933engine_nif_wrapper({error, Error}) ->
2934    throw({error, Error}).
2935
2936ensure_bin_chardata(CharData) when is_binary(CharData) ->
2937    CharData;
2938ensure_bin_chardata(CharData) ->
2939    unicode:characters_to_binary(CharData).
2940
2941ensure_bin_cmds(CMDs) ->
2942    ensure_bin_cmds(CMDs, []).
2943
2944ensure_bin_cmds([], Acc) ->
2945    lists:reverse(Acc);
2946ensure_bin_cmds([{Key, Value} |CMDs], Acc) ->
2947    ensure_bin_cmds(CMDs, [{ensure_bin_chardata(Key), ensure_bin_chardata(Value)} | Acc]);
2948ensure_bin_cmds([Key | CMDs], Acc) ->
2949    ensure_bin_cmds(CMDs, [{ensure_bin_chardata(Key), <<"">>} | Acc]).
2950
2951engine_methods_convert_to_bitmask([], BitMask) ->
2952    BitMask;
2953engine_methods_convert_to_bitmask(engine_method_all, _BitMask) ->
2954    16#FFFF;
2955engine_methods_convert_to_bitmask(engine_method_none, _BitMask) ->
2956    16#0000;
2957engine_methods_convert_to_bitmask([M |Ms], BitMask) ->
2958    engine_methods_convert_to_bitmask(Ms, BitMask bor engine_method_atom_to_int(M)).
2959
2960bool_to_int(true) -> 1;
2961bool_to_int(false) -> 0.
2962
2963engine_method_atom_to_int(engine_method_rsa) -> 16#0001;
2964engine_method_atom_to_int(engine_method_dsa) -> 16#0002;
2965engine_method_atom_to_int(engine_method_dh) -> 16#0004;
2966engine_method_atom_to_int(engine_method_rand) -> 16#0008;
2967engine_method_atom_to_int(engine_method_ecdh) -> 16#0010;
2968engine_method_atom_to_int(engine_method_ecdsa) -> 16#0020;
2969engine_method_atom_to_int(engine_method_ciphers) -> 16#0040;
2970engine_method_atom_to_int(engine_method_digests) -> 16#0080;
2971engine_method_atom_to_int(engine_method_store) -> 16#0100;
2972engine_method_atom_to_int(engine_method_pkey_meths) -> 16#0200;
2973engine_method_atom_to_int(engine_method_pkey_asn1_meths) -> 16#0400;
2974engine_method_atom_to_int(engine_method_ec) -> 16#0800;
2975engine_method_atom_to_int(X) ->
2976    erlang:error(badarg, [X]).
2977
2978get_test_engine() ->
2979    Type = erlang:system_info(system_architecture),
2980    LibDir = filename:join([code:priv_dir(crypto), "lib"]),
2981    ArchDir = filename:join([LibDir, Type]),
2982    case filelib:is_dir(ArchDir) of
2983	true  -> check_otp_test_engine(ArchDir);
2984	false -> check_otp_test_engine(LibDir)
2985    end.
2986
2987check_otp_test_engine(LibDir) ->
2988    case choose_otp_test_engine(LibDir) of
2989        false ->
2990            {error, notexist};
2991        LibName ->
2992            LibPath = filename:join(LibDir,LibName),
2993            case filelib:is_file(LibPath) of
2994                true ->
2995                    {ok, unicode:characters_to_binary(LibPath)};
2996                false ->
2997                    {error, notexist}
2998            end
2999    end.
3000
3001
3002choose_otp_test_engine(LibDir) ->
3003    LibNames = filelib:wildcard("otp_test_engine.*", LibDir),
3004    Type = atom_to_list(erlang:system_info(build_type)),
3005    choose_otp_test_engine(LibNames, Type, false).
3006
3007choose_otp_test_engine([LibName | T], Type, Acc) ->
3008    case string:lexemes(LibName, ".") of
3009        [_, Type, _SO] ->
3010            LibName;  %% Choose typed if exists (valgrind,asan)
3011        [_, _SO] ->
3012            %% Fallback on typeless (opt)
3013            choose_otp_test_engine(T, Type, LibName);
3014        _ ->
3015            choose_otp_test_engine(T, Type, Acc)
3016    end;
3017choose_otp_test_engine([], _, Acc) ->
3018    Acc.
3019