1%%
2%% %CopyrightBegin%
3%%
4%% Copyright Ericsson AB 1999-2018. 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([hash/2, hash_init/1, hash_update/2, hash_final/1]).
29-export([sign/4, sign/5, verify/5, verify/6]).
30-export([generate_key/2, generate_key/3, compute_key/4]).
31-export([hmac/3, hmac/4, hmac_init/2, hmac_update/2, hmac_final/1, hmac_final_n/2]).
32-export([cmac/3, cmac/4]).
33-export([poly1305/2]).
34-export([exor/2, strong_rand_bytes/1, mod_pow/3]).
35-export([rand_seed/0, rand_seed_alg/1]).
36-export([rand_seed_s/0, rand_seed_alg_s/1]).
37-export([rand_plugin_next/1]).
38-export([rand_plugin_uniform/1]).
39-export([rand_plugin_uniform/2]).
40-export([rand_cache_plugin_next/1]).
41-export([rand_uniform/2]).
42-export([block_encrypt/3, block_decrypt/3, block_encrypt/4, block_decrypt/4]).
43-export([next_iv/2, next_iv/3]).
44-export([stream_init/2, stream_init/3, stream_encrypt/2, stream_decrypt/2]).
45-export([public_encrypt/4, private_decrypt/4]).
46-export([private_encrypt/4, public_decrypt/4]).
47-export([privkey_to_pubkey/2]).
48-export([ec_curve/1, ec_curves/0]).
49-export([rand_seed/1]).
50%% Engine
51-export([
52         engine_get_all_methods/0,
53         engine_load/3,
54         engine_load/4,
55         engine_unload/1,
56         engine_by_id/1,
57         engine_list/0,
58         engine_ctrl_cmd_string/3,
59         engine_ctrl_cmd_string/4,
60         engine_add/1,
61         engine_remove/1,
62         engine_get_id/1,
63         engine_get_name/1,
64         ensure_engine_loaded/2,
65         ensure_engine_loaded/3,
66         ensure_engine_unloaded/1,
67         ensure_engine_unloaded/2
68        ]).
69
70-export_type([ %% A minimum exported: only what public_key needs.
71               dh_private/0,
72               dh_public/0,
73               dss_digest_type/0,
74               ec_named_curve/0,
75               ecdsa_digest_type/0,
76               pk_encrypt_decrypt_opts/0,
77               pk_sign_verify_opts/0,
78               rsa_digest_type/0,
79               sha1/0,
80               sha2/0
81             ]).
82
83-export_type([engine_ref/0,
84              key_id/0,
85              password/0
86             ]).
87
88%%% Opaque types must be exported :(
89-export_type([
90              stream_state/0,
91              hmac_state/0,
92              hash_state/0
93             ]).
94
95%% Private. For tests.
96-export([packed_openssl_version/4, engine_methods_convert_to_bitmask/2, get_test_engine/0]).
97
98-deprecated({rand_uniform, 2, next_major_release}).
99
100%% This should correspond to the similar macro in crypto.c
101-define(MAX_BYTES_TO_NIF, 20000). %%  Current value is: erlang:system_info(context_reductions) * 10
102
103%% Used by strong_rand_float/0
104-define(HALF_DBL_EPSILON, 1.1102230246251565e-16). % math:pow(2, -53)
105
106
107%%% ===== BEGIN NEW TYPING ====
108
109%%% Basic
110-type key_integer() :: integer() | binary(). % Always binary() when used as return value
111
112%%% Keys
113-type rsa_public() :: [key_integer()] . % [E, N]
114-type rsa_private() :: [key_integer()] . % [E, N, D] | [E, N, D, P1, P2, E1, E2, C]
115-type rsa_params() :: {ModulusSizeInBits::integer(), PublicExponent::key_integer()} .
116
117-type dss_public() :: [key_integer()] . % [P, Q, G, Y]
118-type dss_private() :: [key_integer()] . % [P, Q, G, X]
119
120-type ecdsa_public()  :: key_integer() .
121-type ecdsa_private() :: key_integer() .
122-type ecdsa_params()  :: ec_named_curve() | ec_explicit_curve() .
123
124-type eddsa_public()  :: key_integer() .
125-type eddsa_private() :: key_integer() .
126-type eddsa_params()  :: edwards_curve_ed() .
127
128-type srp_public() :: key_integer() .
129-type srp_private() :: key_integer() .
130-type srp_gen_params()  :: {user,srp_user_gen_params()}  | {host,srp_host_gen_params()}.
131-type srp_comp_params() :: {user,srp_user_comp_params()} | {host,srp_host_comp_params()}.
132-type srp_user_gen_params() :: list(binary() | atom() | list()) .
133-type srp_host_gen_params() :: list(binary() | atom() | list()) .
134-type srp_user_comp_params() :: list(binary() | atom()) .
135-type srp_host_comp_params() :: list(binary() | atom()) .
136
137-type dh_public() :: key_integer() .
138-type dh_private() :: key_integer() .
139-type dh_params() :: [key_integer()] . % [P, G] | [P, G, PrivateKeyBitLength]
140
141-type ecdh_public()  :: key_integer() .
142-type ecdh_private() :: key_integer() .
143-type ecdh_params()  :: ec_named_curve() | edwards_curve_dh() | ec_explicit_curve() .
144
145
146%%% Curves
147
148-type ec_explicit_curve() :: {Field :: ec_field(),
149                              Curve :: ec_curve(),
150                              BasePoint :: binary(),
151                              Order :: binary(),
152                              CoFactor :: none | % FIXME: Really?
153                                          binary()
154                             } .
155
156-type ec_curve() :: {A :: binary(),
157                     B :: binary(),
158                     Seed :: none | binary()
159                    } .
160
161-type ec_field() ::  ec_prime_field() | ec_characteristic_two_field() .
162
163-type ec_prime_field()              :: {prime_field, Prime :: integer()} .
164-type ec_characteristic_two_field() :: {characteristic_two_field, M :: integer(), Basis :: ec_basis()} .
165
166-type ec_basis() :: {tpbasis, K :: non_neg_integer()}
167                  | {ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()}
168                  |  onbasis .
169
170-type ec_named_curve() :: brainpoolP160r1
171                        | brainpoolP160t1
172                        | brainpoolP192r1
173                        | brainpoolP192t1
174                        | brainpoolP224r1
175                        | brainpoolP224t1
176                        | brainpoolP256r1
177                        | brainpoolP256t1
178                        | brainpoolP320r1
179                        | brainpoolP320t1
180                        | brainpoolP384r1
181                        | brainpoolP384t1
182                        | brainpoolP512r1
183                        | brainpoolP512t1
184                        | c2pnb163v1
185                        | c2pnb163v2
186                        | c2pnb163v3
187                        | c2pnb176v1
188                        | c2pnb208w1
189                        | c2pnb272w1
190                        | c2pnb304w1
191                        | c2pnb368w1
192                        | c2tnb191v1
193                        | c2tnb191v2
194                        | c2tnb191v3
195                        | c2tnb239v1
196                        | c2tnb239v2
197                        | c2tnb239v3
198                        | c2tnb359v1
199                        | c2tnb431r1
200                        | ipsec3
201                        | ipsec4
202                        | prime192v1
203                        | prime192v2
204                        | prime192v3
205                        | prime239v1
206                        | prime239v2
207                        | prime239v3
208                        | prime256v1
209                        | secp112r1
210                        | secp112r2
211                        | secp128r1
212                        | secp128r2
213                        | secp160k1
214                        | secp160r1
215                        | secp160r2
216                        | secp192k1
217                        | secp192r1
218                        | secp224k1
219                        | secp224r1
220                        | secp256k1
221                        | secp256r1
222                        | secp384r1
223                        | secp521r1
224                        | sect113r1
225                        | sect113r2
226                        | sect131r1
227                        | sect131r2
228                        | sect163k1
229                        | sect163r1
230                        | sect163r2
231                        | sect193r1
232                        | sect193r2
233                        | sect233k1
234                        | sect233r1
235                        | sect239k1
236                        | sect283k1
237                        | sect283r1
238                        | sect409k1
239                        | sect409r1
240                        | sect571k1
241                        | sect571r1
242                        | wtls1
243                        | wtls10
244                        | wtls11
245                        | wtls12
246                        | wtls3
247                        | wtls4
248                        | wtls5
249                        | wtls6
250                        | wtls7
251                        | wtls8
252                        | wtls9
253                          .
254
255-type edwards_curve_dh() :: x25519 | x448 .
256
257-type edwards_curve_ed() :: ed25519 | ed448 .
258
259%%%
260-type block_cipher_with_iv() :: cbc_cipher()
261                              | cfb_cipher()
262                              | aes_cbc128
263                              | aes_cbc256
264                              | aes_ige256
265                              | blowfish_ofb64
266                              | des3_cbf % cfb misspelled
267                              | des_ede3
268                              | rc2_cbc .
269
270-type cbc_cipher()  :: des_cbc | des3_cbc | aes_cbc | blowfish_cbc .
271-type aead_cipher() :: aes_gcm | aes_ccm | chacha20_poly1305 .
272-type cfb_cipher()  :: aes_cfb128 | aes_cfb8 | blowfish_cfb64 | des3_cfb | des_cfb .
273
274-type block_cipher_without_iv() :: ecb_cipher() .
275-type ecb_cipher()  :: des_ecb | blowfish_ecb | aes_ecb .
276
277-type key() :: iodata().
278-type des3_key() :: [key()].
279
280%%%
281-type rsa_digest_type()   :: sha1() | sha2() | md5 | ripemd160 .
282-type dss_digest_type()   :: sha1() | sha2() .
283-type ecdsa_digest_type() :: sha1() | sha2() .
284
285-type sha1() :: sha .
286-type sha2() :: sha224 | sha256 | sha384 | sha512 .
287-type sha3() :: sha3_224 | sha3_256 | sha3_384 | sha3_512 .
288
289-type compatibility_only_hash() :: md5 | md4 .
290
291-type crypto_integer() :: binary() | integer().
292
293-compile(no_native).
294-on_load(on_load/0).
295-define(CRYPTO_NIF_VSN,302).
296
297-define(nif_stub,nif_stub_error(?LINE)).
298nif_stub_error(Line) ->
299    erlang:nif_error({nif_not_loaded,module,?MODULE,line,Line}).
300
301%%--------------------------------------------------------------------
302%%% API
303%%--------------------------------------------------------------------
304%% Crypto app version history:
305%% (no version): Driver implementation
306%% 2.0         : NIF implementation, requires OTP R14
307
308%% When generating documentation from crypto.erl, the macro ?CRYPTO_VSN is not defined.
309%% That causes the doc generation to stop...
310-ifndef(CRYPTO_VSN).
311-define(CRYPTO_VSN, "??").
312-endif.
313version() -> ?CRYPTO_VSN.
314
315-spec start() -> ok | {error, Reason::term()}.
316start() ->
317    application:start(crypto).
318
319-spec stop() -> ok | {error, Reason::term()}.
320stop() ->
321    application:stop(crypto).
322
323-spec supports() -> [Support]
324                        when Support :: {hashs,   Hashs}
325                                      | {ciphers, Ciphers}
326                                      | {public_keys, PKs}
327                                      | {macs,    Macs}
328                                      | {curves,  Curves}
329                                      | {rsa_opts, RSAopts},
330                             Hashs :: [sha1() | sha2() | sha3() | ripemd160 | compatibility_only_hash()],
331                             Ciphers :: [stream_cipher()
332                                         | block_cipher_with_iv() | block_cipher_without_iv()
333                                         | aead_cipher()
334                                        ],
335                             PKs :: [rsa | dss | ecdsa | dh | ecdh | ec_gf2m],
336                             Macs :: [hmac | cmac | poly1305],
337                             Curves :: [ec_named_curve() | edwards_curve_dh() | edwards_curve_ed()],
338                             RSAopts :: [rsa_sign_verify_opt() | rsa_opt()] .
339supports()->
340    {Hashs, PubKeys, Ciphers, Macs, Curves, RsaOpts} = algorithms(),
341    [{hashs, Hashs},
342     {ciphers, Ciphers},
343     {public_keys, PubKeys},
344     {macs, Macs},
345     {curves, Curves},
346     {rsa_opts, RsaOpts}
347    ].
348
349-spec info_lib() -> [{Name,VerNum,VerStr}] when Name :: binary(),
350                                                VerNum :: integer(),
351                                                VerStr :: binary() .
352info_lib() -> ?nif_stub.
353
354-spec info_fips() -> not_supported | not_enabled | enabled.
355
356info_fips() -> ?nif_stub.
357
358-spec enable_fips_mode(Enable) -> Result when Enable :: boolean(),
359                                              Result :: boolean().
360enable_fips_mode(_) -> ?nif_stub.
361
362%%%================================================================
363%%%
364%%% Compare in constant time
365%%%
366%%%================================================================
367
368%%% Candidate for a NIF
369
370equal_const_time(X1, X2) ->
371    equal_const_time(X1, X2, true).
372
373
374equal_const_time(<<B1,R1/binary>>, <<B2,R2/binary>>, Truth) ->
375    equal_const_time(R1, R2, Truth and (B1 == B2));
376equal_const_time(<<_,R1/binary>>, <<>>, Truth) ->
377    equal_const_time(R1, <<>>, Truth and false);
378equal_const_time(<<>>, <<>>, Truth) ->
379    Truth;
380
381equal_const_time([H1|T1], [H2|T2], Truth) ->
382    equal_const_time(T1, T2, Truth and (H1 == H2));
383equal_const_time([_|T1], [], Truth) ->
384    equal_const_time(T1, [], Truth and false);
385equal_const_time([], [], Truth) ->
386    Truth;
387
388equal_const_time(_, _, _) ->
389    false.
390
391%%%================================================================
392%%%
393%%% Hashing
394%%%
395%%%================================================================
396
397-define(HASH_HASH_ALGORITHM, sha1() | sha2() | sha3() | ripemd160 | compatibility_only_hash() ).
398
399-spec hash(Type, Data) -> Digest when Type :: ?HASH_HASH_ALGORITHM,
400                                      Data :: iodata(),
401                                      Digest :: binary().
402hash(Type, Data) ->
403    Data1 = iolist_to_binary(Data),
404    MaxBytes = max_bytes(),
405    hash(Type, Data1, erlang:byte_size(Data1), MaxBytes).
406
407-opaque hash_state() :: reference().
408
409-spec hash_init(Type) -> State when Type :: ?HASH_HASH_ALGORITHM,
410                                    State :: hash_state().
411hash_init(Type) ->
412    notsup_to_error(hash_init_nif(Type)).
413
414-spec hash_update(State, Data) -> NewState when State :: hash_state(),
415                                                NewState :: hash_state(),
416                                                Data :: iodata() .
417hash_update(Context, Data) ->
418    Data1 = iolist_to_binary(Data),
419    MaxBytes = max_bytes(),
420    hash_update(Context, Data1, erlang:byte_size(Data1), MaxBytes).
421
422-spec hash_final(State) -> Digest when  State :: hash_state(),
423                                        Digest :: binary().
424hash_final(Context) ->
425    notsup_to_error(hash_final_nif(Context)).
426
427%%%================================================================
428%%%
429%%% MACs (Message Authentication Codes)
430%%%
431%%%================================================================
432
433%%%---- HMAC
434
435-define(HMAC_HASH_ALGORITHM,  sha1() | sha2() | sha3() | compatibility_only_hash()).
436
437%%%---- hmac/3,4
438
439-spec hmac(Type, Key, Data) ->
440                  Mac when Type :: ?HMAC_HASH_ALGORITHM,
441                           Key :: iodata(),
442                           Data :: iodata(),
443                           Mac :: binary() .
444hmac(Type, Key, Data) ->
445    Data1 = iolist_to_binary(Data),
446    hmac(Type, Key, Data1, undefined, erlang:byte_size(Data1), max_bytes()).
447
448-spec hmac(Type, Key, Data, MacLength) ->
449                  Mac when Type :: ?HMAC_HASH_ALGORITHM,
450                           Key :: iodata(),
451                           Data :: iodata(),
452                           MacLength :: integer(),
453                           Mac :: binary() .
454
455hmac(Type, Key, Data, MacLength) ->
456    Data1 = iolist_to_binary(Data),
457    hmac(Type, Key, Data1, MacLength, erlang:byte_size(Data1), max_bytes()).
458
459%%%---- hmac_init, hamc_update, hmac_final
460
461-opaque hmac_state() :: binary().
462
463-spec hmac_init(Type, Key) ->
464                       State when Type :: ?HMAC_HASH_ALGORITHM,
465                                  Key :: iodata(),
466                                  State :: hmac_state() .
467hmac_init(Type, Key) ->
468    notsup_to_error(hmac_init_nif(Type, Key)).
469
470%%%---- hmac_update
471
472-spec hmac_update(State, Data) -> NewState when Data :: iodata(),
473                                                State :: hmac_state(),
474                                                NewState :: hmac_state().
475hmac_update(State, Data0) ->
476    Data = iolist_to_binary(Data0),
477    hmac_update(State, Data, erlang:byte_size(Data), max_bytes()).
478
479%%%---- hmac_final
480
481-spec hmac_final(State) -> Mac when State :: hmac_state(),
482                                    Mac :: binary().
483hmac_final(Context) ->
484    notsup_to_error(hmac_final_nif(Context)).
485
486-spec hmac_final_n(State, HashLen) -> Mac when State :: hmac_state(),
487                                               HashLen :: integer(),
488                                               Mac :: binary().
489hmac_final_n(Context, HashLen) ->
490    notsup_to_error(hmac_final_nif(Context, HashLen)).
491
492%%%---- CMAC
493
494-define(CMAC_CIPHER_ALGORITHM, cbc_cipher() | cfb_cipher() | blowfish_cbc | des_ede3 | rc2_cbc  ).
495
496-spec cmac(Type, Key, Data) ->
497                  Mac when Type :: ?CMAC_CIPHER_ALGORITHM,
498                           Key :: iodata(),
499                           Data :: iodata(),
500                           Mac :: binary().
501cmac(Type, Key, Data) ->
502    notsup_to_error(cmac_nif(Type, Key, Data)).
503
504-spec cmac(Type, Key, Data, MacLength) ->
505                  Mac when Type :: ?CMAC_CIPHER_ALGORITHM,
506                           Key :: iodata(),
507                           Data :: iodata(),
508                           MacLength :: integer(),
509                           Mac :: binary().
510cmac(Type, Key, Data, MacLength) ->
511    erlang:binary_part(cmac(Type, Key, Data), 0, MacLength).
512
513%%%---- POLY1305
514
515-spec poly1305(iodata(), iodata()) -> Mac when Mac ::  binary().
516
517poly1305(Key, Data) ->
518    poly1305_nif(Key, Data).
519
520%%%================================================================
521%%%
522%%% Encrypt/decrypt
523%%%
524%%%================================================================
525
526%%%---- Block ciphers
527
528-spec block_encrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) -> binary();
529                   (Type::aead_cipher(),  Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata()}) ->
530                           {binary(), binary()};
531                   (aes_gcm | aes_ccm, Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata(), TagLength::1..16}) ->
532                           {binary(), binary()}.
533
534block_encrypt(Type, Key, Ivec, PlainText) when Type =:= des_cbc;
535                                               Type =:= des_cfb;
536                                               Type =:= blowfish_cbc;
537                                               Type =:= blowfish_cfb64;
538                                               Type =:= blowfish_ofb64;
539                                               Type =:= aes_cbc128;
540                                               Type =:= aes_cfb8;
541                                               Type =:= aes_cfb128;
542                                               Type =:= aes_cbc256;
543                                               Type =:= aes_cbc;
544                                               Type =:= rc2_cbc ->
545    notsup_to_error(block_crypt_nif(Type, Key, Ivec, PlainText, true));
546block_encrypt(Type, Key0, Ivec, PlainText) when Type =:= des3_cbc;
547                                                Type =:= des_ede3 ->
548    Key = check_des3_key(Key0),
549    notsup_to_error(block_crypt_nif(des_ede3_cbc, Key, Ivec, PlainText, true));
550block_encrypt(des3_cbf, Key0, Ivec, PlainText) -> % cfb misspelled
551    Key = check_des3_key(Key0),
552    notsup_to_error(block_crypt_nif(des_ede3_cbf, Key, Ivec, PlainText, true));
553block_encrypt(des3_cfb, Key0, Ivec, PlainText) ->
554    Key = check_des3_key(Key0),
555    notsup_to_error(block_crypt_nif(des_ede3_cfb, Key, Ivec, PlainText, true));
556block_encrypt(aes_ige256, Key, Ivec, PlainText) ->
557    notsup_to_error(aes_ige_crypt_nif(Key, Ivec, PlainText, true));
558block_encrypt(Type, Key, Ivec, {AAD, PlainText}) when Type =:= aes_gcm;
559                                                      Type =:= aes_ccm ->
560    aead_encrypt(Type, Key, Ivec, AAD, PlainText);
561block_encrypt(Type, Key, Ivec, {AAD, PlainText, TagLength}) when Type =:= aes_gcm;
562                                                                 Type =:= aes_ccm ->
563    aead_encrypt(Type, Key, Ivec, AAD, PlainText, TagLength);
564block_encrypt(chacha20_poly1305=Type, Key, Ivec, {AAD, PlainText}) ->
565    aead_encrypt(Type, Key, Ivec, AAD, PlainText, 16).
566
567
568-spec block_decrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), Data::iodata()) -> binary();
569		   (Type::aead_cipher(), Key::iodata(), Ivec::binary(),
570		    {AAD::binary(), Data::iodata(), Tag::binary()}) -> binary() | error.
571block_decrypt(Type, Key, Ivec, Data) when Type =:= des_cbc;
572                                          Type =:= des_cfb;
573                                          Type =:= blowfish_cbc;
574                                          Type =:= blowfish_cfb64;
575                                          Type =:= blowfish_ofb64;
576					  Type =:= aes_cbc;
577                                          Type =:= aes_cbc128;
578                                          Type =:= aes_cfb8;
579                                          Type =:= aes_cfb128;
580                                          Type =:= aes_cbc256;
581                                          Type =:= rc2_cbc ->
582    notsup_to_error(block_crypt_nif(Type, Key, Ivec, Data, false));
583block_decrypt(Type, Key0, Ivec, Data) when Type =:= des3_cbc;
584                                           Type =:= des_ede3 ->
585    Key = check_des3_key(Key0),
586    notsup_to_error(block_crypt_nif(des_ede3_cbc, Key, Ivec, Data, false));
587block_decrypt(des3_cbf, Key0, Ivec, Data) -> % cfb misspelled
588    Key = check_des3_key(Key0),
589    notsup_to_error(block_crypt_nif(des_ede3_cbf, Key, Ivec, Data, false));
590block_decrypt(des3_cfb, Key0, Ivec, Data) ->
591    Key = check_des3_key(Key0),
592    notsup_to_error(block_crypt_nif(des_ede3_cfb, Key, Ivec, Data, false));
593block_decrypt(aes_ige256, Key, Ivec, Data) ->
594    notsup_to_error(aes_ige_crypt_nif(Key, Ivec, Data, false));
595block_decrypt(Type, Key, Ivec, {AAD, Data, Tag}) when Type =:= aes_gcm;
596                                                      Type =:= aes_ccm;
597                                                      Type =:= chacha20_poly1305 ->
598    aead_decrypt(Type, Key, Ivec, AAD, Data, Tag).
599
600
601-spec block_encrypt(Type::block_cipher_without_iv(), Key::key(), PlainText::iodata()) -> binary().
602
603block_encrypt(Type, Key, PlainText) ->
604    notsup_to_error(block_crypt_nif(Type, Key, PlainText, true)).
605
606
607-spec block_decrypt(Type::block_cipher_without_iv(), Key::key(), Data::iodata()) -> binary().
608
609block_decrypt(Type, Key, Data) ->
610    notsup_to_error(block_crypt_nif(Type, Key, Data, false)).
611
612
613-spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige,
614                                           Data :: iodata(),
615                                           NextIVec :: binary().
616next_iv(Type, Data) when is_binary(Data) ->
617    IVecSize = case Type of
618                   des_cbc  -> 8;
619                   des3_cbc -> 8;
620                   aes_cbc  -> 16;
621                   aes_ige  -> 32
622               end,
623    {_, IVec} = split_binary(Data, size(Data) - IVecSize),
624    IVec;
625next_iv(Type, Data) when is_list(Data) ->
626    next_iv(Type, list_to_binary(Data)).
627
628-spec next_iv(des_cfb, Data, IVec) -> NextIVec when Data :: iodata(),
629                                                    IVec :: binary(),
630                                                    NextIVec :: binary().
631
632next_iv(des_cfb, Data, IVec) ->
633    IVecAndData = list_to_binary([IVec, Data]),
634    {_, NewIVec} = split_binary(IVecAndData, byte_size(IVecAndData) - 8),
635    NewIVec;
636next_iv(Type, Data, _Ivec) ->
637    next_iv(Type, Data).
638
639%%%---- Stream ciphers
640
641-opaque stream_state() :: {stream_cipher(), reference()}.
642
643-type stream_cipher() :: rc4 | aes_ctr | chacha20 .
644
645-spec stream_init(Type, Key, IVec) -> State when Type :: aes_ctr | chacha20,
646                                                 Key :: iodata(),
647                                                 IVec :: binary(),
648                                                 State :: stream_state() .
649stream_init(aes_ctr, Key, Ivec) ->
650    {aes_ctr, aes_ctr_stream_init(Key, Ivec)};
651stream_init(chacha20, Key, Ivec) ->
652    {chacha20, chacha20_stream_init(Key,Ivec)}.
653
654-spec stream_init(Type, Key) -> State when Type :: rc4,
655                                           Key :: iodata(),
656                                           State :: stream_state() .
657stream_init(rc4, Key) ->
658    {rc4, notsup_to_error(rc4_set_key(Key))}.
659
660-spec stream_encrypt(State, PlainText) -> {NewState, CipherText}
661                                              when State :: stream_state(),
662                                                   PlainText :: iodata(),
663                                                   NewState :: stream_state(),
664                                                   CipherText :: iodata() .
665stream_encrypt(State, Data0) ->
666    Data = iolist_to_binary(Data0),
667    MaxByts = max_bytes(),
668    stream_crypt(fun do_stream_encrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []).
669
670-spec stream_decrypt(State, CipherText) -> {NewState, PlainText}
671                                              when State :: stream_state(),
672                                                   CipherText :: iodata(),
673                                                   NewState :: stream_state(),
674                                                   PlainText :: iodata() .
675stream_decrypt(State, Data0) ->
676    Data = iolist_to_binary(Data0),
677    MaxByts = max_bytes(),
678    stream_crypt(fun do_stream_decrypt/2, State, Data, erlang:byte_size(Data), MaxByts, []).
679
680
681%%%================================================================
682%%%
683%%% RAND - pseudo random numbers using RN_ and BN_ functions in crypto lib
684%%%
685%%%================================================================
686-type rand_cache_seed() ::
687        nonempty_improper_list(non_neg_integer(), binary()).
688
689-spec strong_rand_bytes(N::non_neg_integer()) -> binary().
690strong_rand_bytes(Bytes) ->
691    case strong_rand_bytes_nif(Bytes) of
692        false -> erlang:error(low_entropy);
693        Bin -> Bin
694    end.
695strong_rand_bytes_nif(_Bytes) -> ?nif_stub.
696
697
698-spec rand_seed() -> rand:state().
699rand_seed() ->
700    rand:seed(rand_seed_s()).
701
702-spec rand_seed_s() -> rand:state().
703rand_seed_s() ->
704    rand_seed_alg_s(?MODULE).
705
706-spec rand_seed_alg(Alg :: atom()) ->
707                           {rand:alg_handler(),
708                            atom() | rand_cache_seed()}.
709rand_seed_alg(Alg) ->
710    rand:seed(rand_seed_alg_s(Alg)).
711
712-define(CRYPTO_CACHE_BITS, 56).
713-spec rand_seed_alg_s(Alg :: atom()) ->
714                             {rand:alg_handler(),
715                              atom() | rand_cache_seed()}.
716rand_seed_alg_s(?MODULE) ->
717    {#{ type => ?MODULE,
718        bits => 64,
719        next => fun ?MODULE:rand_plugin_next/1,
720        uniform => fun ?MODULE:rand_plugin_uniform/1,
721        uniform_n => fun ?MODULE:rand_plugin_uniform/2},
722     no_seed};
723rand_seed_alg_s(crypto_cache) ->
724    CacheBits = ?CRYPTO_CACHE_BITS,
725    EnvCacheSize =
726        application:get_env(
727          crypto, rand_cache_size, CacheBits * 16), % Cache 16 * 8 words
728    Bytes = (CacheBits + 7) div 8,
729    CacheSize =
730        case ((EnvCacheSize + (Bytes - 1)) div Bytes) * Bytes of
731            Sz when is_integer(Sz), Bytes =< Sz ->
732                Sz;
733            _ ->
734                Bytes
735        end,
736    {#{ type => crypto_cache,
737        bits => CacheBits,
738        next => fun ?MODULE:rand_cache_plugin_next/1},
739     {CacheBits, CacheSize, <<>>}}.
740
741rand_plugin_next(Seed) ->
742    {bytes_to_integer(strong_rand_range(1 bsl 64)), Seed}.
743
744rand_plugin_uniform(State) ->
745    {strong_rand_float(), State}.
746
747rand_plugin_uniform(Max, State) ->
748    {bytes_to_integer(strong_rand_range(Max)) + 1, State}.
749
750rand_cache_plugin_next({CacheBits, CacheSize, <<>>}) ->
751    rand_cache_plugin_next(
752      {CacheBits, CacheSize, strong_rand_bytes(CacheSize)});
753rand_cache_plugin_next({CacheBits, CacheSize, Cache}) ->
754    <<I:CacheBits, NewCache/binary>> = Cache,
755    {I, {CacheBits, CacheSize, NewCache}}.
756
757strong_rand_range(Range) when is_integer(Range), Range > 0 ->
758    BinRange = int_to_bin(Range),
759    strong_rand_range(BinRange);
760strong_rand_range(BinRange) when is_binary(BinRange) ->
761    case strong_rand_range_nif(BinRange) of
762        false ->
763            erlang:error(low_entropy);
764        <<BinResult/binary>> ->
765            BinResult
766    end.
767strong_rand_range_nif(_BinRange) -> ?nif_stub.
768
769strong_rand_float() ->
770    WholeRange = strong_rand_range(1 bsl 53),
771    ?HALF_DBL_EPSILON * bytes_to_integer(WholeRange).
772
773-spec rand_uniform(crypto_integer(), crypto_integer()) ->
774			  crypto_integer().
775rand_uniform(From, To) when is_binary(From), is_binary(To) ->
776    case rand_uniform_nif(From,To) of
777	<<Len:32/integer, MSB, Rest/binary>> when MSB > 127 ->
778	    <<(Len + 1):32/integer, 0, MSB, Rest/binary>>;
779	Whatever ->
780	    Whatever
781    end;
782rand_uniform(From,To) when is_integer(From),is_integer(To) ->
783    if From < 0 ->
784	    rand_uniform_pos(0, To - From) + From;
785       true ->
786	    rand_uniform_pos(From, To)
787    end.
788
789rand_uniform_pos(From,To) when From < To ->
790    BinFrom = mpint(From),
791    BinTo = mpint(To),
792    case rand_uniform(BinFrom, BinTo) of
793        Result when is_binary(Result) ->
794            erlint(Result);
795        Other ->
796            Other
797    end;
798rand_uniform_pos(_,_) ->
799    error(badarg).
800
801rand_uniform_nif(_From,_To) -> ?nif_stub.
802
803
804-spec rand_seed(binary()) -> ok.
805rand_seed(Seed) when is_binary(Seed) ->
806    rand_seed_nif(Seed).
807
808rand_seed_nif(_Seed) -> ?nif_stub.
809
810%%%================================================================
811%%%
812%%% Sign/verify
813%%%
814%%%================================================================
815-type pk_sign_verify_algs() :: rsa | dss | ecdsa | eddsa .
816
817-type pk_sign_verify_opts() :: [ rsa_sign_verify_opt() ] .
818
819-type rsa_sign_verify_opt() :: {rsa_padding, rsa_sign_verify_padding()}
820                             | {rsa_pss_saltlen, integer()} .
821
822-type rsa_sign_verify_padding() :: rsa_pkcs1_padding | rsa_pkcs1_pss_padding
823                                 | rsa_x931_padding | rsa_no_padding
824                                   .
825
826
827%%%----------------------------------------------------------------
828%%% Sign
829
830-spec sign(Algorithm, DigestType, Msg, Key)
831          -> Signature
832                 when Algorithm :: pk_sign_verify_algs(),
833                      DigestType :: rsa_digest_type()
834                                  | dss_digest_type()
835                                  | ecdsa_digest_type(),
836                      Msg :: binary() | {digest,binary()},
837                      Key :: rsa_private()
838                           | dss_private()
839                           | [ecdsa_private() | ecdsa_params()]
840                           | [eddsa_private() | eddsa_params()]
841                           | engine_key_ref(),
842                      Signature :: binary() .
843
844sign(Algorithm, Type, Data, Key) ->
845    sign(Algorithm, Type, Data, Key, []).
846
847
848-spec sign(Algorithm, DigestType, Msg, Key, Options)
849          -> Signature
850                 when Algorithm :: pk_sign_verify_algs(),
851                      DigestType :: rsa_digest_type()
852                                  | dss_digest_type()
853                                  | ecdsa_digest_type()
854                                  | none,
855                      Msg :: binary() | {digest,binary()},
856                      Key :: rsa_private()
857                           | dss_private()
858                           | [ecdsa_private() | ecdsa_params()]
859                           | [eddsa_private() | eddsa_params()]
860                           | engine_key_ref(),
861                      Options :: pk_sign_verify_opts(),
862                      Signature :: binary() .
863
864sign(Algorithm0, Type0, Data, Key, Options) ->
865    {Algorithm, Type} = sign_verify_compatibility(Algorithm0, Type0, Data),
866    case pkey_sign_nif(Algorithm, Type, Data, format_pkey(Algorithm, Key), Options) of
867	error -> erlang:error(badkey, [Algorithm, Type, Data, Key, Options]);
868	notsup -> erlang:error(notsup);
869	Signature -> Signature
870    end.
871
872pkey_sign_nif(_Algorithm, _Type, _Digest, _Key, _Options) -> ?nif_stub.
873
874%%%----------------------------------------------------------------
875%%% Verify
876
877-spec verify(Algorithm, DigestType, Msg, Signature, Key)
878            -> Result
879                   when Algorithm :: pk_sign_verify_algs(),
880                        DigestType :: rsa_digest_type()
881                                    | dss_digest_type()
882                                    | ecdsa_digest_type()
883                                    | none,
884                        Msg :: binary() | {digest,binary()},
885                        Signature :: binary(),
886                        Key :: rsa_public()
887                             | dss_public()
888                             | [ecdsa_public() | ecdsa_params()]
889                             | [eddsa_public() | eddsa_params()]
890                             | engine_key_ref(),
891                        Result :: boolean().
892
893verify(Algorithm, Type, Data, Signature, Key) ->
894    verify(Algorithm, Type, Data, Signature, Key, []).
895
896-spec verify(Algorithm, DigestType, Msg, Signature, Key, Options)
897            -> Result
898                   when Algorithm :: pk_sign_verify_algs(),
899                        DigestType :: rsa_digest_type()
900                                    | dss_digest_type()
901                                    | ecdsa_digest_type(),
902                        Msg :: binary() | {digest,binary()},
903                        Signature :: binary(),
904                        Key :: rsa_public()
905                             | dss_public()
906                             | [ecdsa_public() | ecdsa_params()]
907                             | [eddsa_public() | eddsa_params()]
908                             | engine_key_ref(),
909                        Options :: pk_sign_verify_opts(),
910                        Result :: boolean().
911
912verify(Algorithm0, Type0, Data, Signature, Key, Options) ->
913    {Algorithm, Type} = sign_verify_compatibility(Algorithm0, Type0, Data),
914    case pkey_verify_nif(Algorithm, Type, Data, Signature, format_pkey(Algorithm, Key), Options) of
915	notsup -> erlang:error(notsup);
916	Boolean -> Boolean
917    end.
918
919pkey_verify_nif(_Algorithm, _Type, _Data, _Signature, _Key, _Options) -> ?nif_stub.
920
921%% Backwards compatible:
922sign_verify_compatibility(dss, none, Digest) ->
923    {sha, {digest, Digest}};
924sign_verify_compatibility(Algorithm0, Type0, _Digest) ->
925    {Algorithm0, Type0}.
926
927%%%================================================================
928%%%
929%%% Public/private encrypt/decrypt
930%%%
931%%% Only rsa works so far (although ecdsa | dss should do it)
932%%%================================================================
933-type pk_encrypt_decrypt_algs() :: rsa .
934
935-type pk_encrypt_decrypt_opts() ::  [rsa_opt()] | rsa_compat_opts().
936
937-type rsa_compat_opts() :: [{rsa_pad, rsa_padding()}]
938                         | rsa_padding() .
939
940-type rsa_padding() :: rsa_pkcs1_padding
941                     | rsa_pkcs1_oaep_padding
942                     | rsa_sslv23_padding
943                     | rsa_x931_padding
944                     | rsa_no_padding.
945
946-type rsa_opt() :: {rsa_padding, rsa_padding()}
947                 | {signature_md, atom()}
948                 | {rsa_mgf1_md, sha}
949                 | {rsa_oaep_label, binary()}
950                 | {rsa_oaep_md, sha} .
951
952%%%---- Encrypt with public key
953
954-spec public_encrypt(Algorithm, PlainText, PublicKey, Options) ->
955                            CipherText when Algorithm :: pk_encrypt_decrypt_algs(),
956                                            PlainText :: binary(),
957                                            PublicKey :: rsa_public() | engine_key_ref(),
958                                            Options :: pk_encrypt_decrypt_opts(),
959                                            CipherText :: binary().
960public_encrypt(Algorithm, PlainText, PublicKey, Options) ->
961    pkey_crypt(Algorithm, PlainText, PublicKey, Options, false, true).
962
963%%%---- Decrypt with private key
964
965-spec private_decrypt(Algorithm, CipherText, PrivateKey, Options) ->
966                             PlainText when Algorithm :: pk_encrypt_decrypt_algs(),
967                                            CipherText :: binary(),
968                                            PrivateKey :: rsa_private() | engine_key_ref(),
969                                            Options :: pk_encrypt_decrypt_opts(),
970                                            PlainText :: binary() .
971private_decrypt(Algorithm, CipherText, PrivateKey, Options) ->
972    pkey_crypt(Algorithm, CipherText,  PrivateKey, Options, true, false).
973
974%%%---- Encrypt with private key
975
976-spec private_encrypt(Algorithm, PlainText, PrivateKey, Options) ->
977                            CipherText when Algorithm :: pk_encrypt_decrypt_algs(),
978                                            PlainText :: binary(),
979                                            PrivateKey :: rsa_private() | engine_key_ref(),
980                                            Options :: pk_encrypt_decrypt_opts(),
981                                            CipherText :: binary().
982private_encrypt(Algorithm, PlainText, PrivateKey, Options) ->
983    pkey_crypt(Algorithm, PlainText,  PrivateKey, Options, true, true).
984
985%%%---- Decrypt with public key
986
987-spec public_decrypt(Algorithm, CipherText, PublicKey, Options) ->
988                             PlainText when Algorithm :: pk_encrypt_decrypt_algs(),
989                                            CipherText :: binary(),
990                                            PublicKey :: rsa_public() | engine_key_ref(),
991                                            Options :: pk_encrypt_decrypt_opts(),
992                                            PlainText :: binary() .
993public_decrypt(Algorithm, CipherText, PublicKey, Options) ->
994    pkey_crypt(Algorithm, CipherText, PublicKey, Options, false, false).
995
996%%%---- Call the nif, but fix a compatibility issue first
997
998%% Backwards compatible (rsa_pad -> rsa_padding is handled by the pkey_crypt_nif):
999pkey_crypt(rsa, Text, Key, Padding, PubPriv, EncDec) when is_atom(Padding) ->
1000    pkey_crypt(rsa, Text, Key, [{rsa_padding, Padding}], PubPriv, EncDec);
1001
1002pkey_crypt(Alg, Text, Key, Options, PubPriv, EncDec) ->
1003    case pkey_crypt_nif(Alg, Text, format_pkey(Alg,Key), Options, PubPriv, EncDec) of
1004	error when EncDec==true  -> erlang:error(encrypt_failed, [Alg, Text, Key, Options]);
1005	error when EncDec==false -> erlang:error(decrypt_failed, [Alg, Text, Key, Options]);
1006	notsup -> erlang:error(notsup);
1007	Out -> Out
1008    end.
1009
1010pkey_crypt_nif(_Algorithm, _In, _Key, _Options, _IsPrivate, _IsEncrypt) -> ?nif_stub.
1011
1012%%%================================================================
1013%%%
1014%%%
1015%%%
1016%%%================================================================
1017
1018-spec generate_key(Type, Params)
1019                 -> {PublicKey, PrivKeyOut}
1020                        when Type :: dh | ecdh | rsa | srp,
1021                             PublicKey :: dh_public() | ecdh_public() | rsa_public() | srp_public(),
1022                             PrivKeyOut :: dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()},
1023                             Params :: dh_params() | ecdh_params() | rsa_params() | srp_gen_params()
1024                                       .
1025generate_key(Type, Params) ->
1026    generate_key(Type, Params, undefined).
1027
1028-spec generate_key(Type, Params, PrivKeyIn)
1029                 -> {PublicKey, PrivKeyOut}
1030                        when Type :: dh | ecdh | rsa | srp,
1031                             PublicKey :: dh_public() | ecdh_public() | rsa_public() | srp_public(),
1032                             PrivKeyIn :: undefined | dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()},
1033                             PrivKeyOut :: dh_private() | ecdh_private() | rsa_private() | {srp_public(),srp_private()},
1034                             Params :: dh_params() | ecdh_params() | rsa_params() | srp_comp_params()
1035                                       .
1036
1037generate_key(dh, DHParameters0, PrivateKey) ->
1038    {DHParameters, Len} =
1039        case DHParameters0 of
1040            [P,G,L] -> {[P,G], L};
1041            [P,G] -> {[P,G], 0}
1042        end,
1043    dh_generate_key_nif(ensure_int_as_bin(PrivateKey),
1044			map_ensure_int_as_bin(DHParameters),
1045                        0, Len);
1046
1047generate_key(srp, {host, [Verifier, Generator, Prime, Version]}, PrivArg)
1048  when is_binary(Verifier), is_binary(Generator), is_binary(Prime), is_atom(Version) ->
1049    Private = case PrivArg of
1050		  undefined -> strong_rand_bytes(32);
1051		  _ -> ensure_int_as_bin(PrivArg)
1052	      end,
1053    host_srp_gen_key(Private, Verifier, Generator, Prime, Version);
1054
1055generate_key(srp, {user, [Generator, Prime, Version]}, PrivateArg)
1056  when is_binary(Generator), is_binary(Prime), is_atom(Version) ->
1057    Private = case PrivateArg of
1058		  undefined -> strong_rand_bytes(32);
1059		  _ -> PrivateArg
1060	      end,
1061    user_srp_gen_key(Private, Generator, Prime);
1062
1063generate_key(rsa, {ModulusSize, PublicExponent}, undefined) ->
1064    case rsa_generate_key_nif(ModulusSize, ensure_int_as_bin(PublicExponent)) of
1065        error ->
1066            erlang:error(computation_failed,
1067                         [rsa,{ModulusSize,PublicExponent}]);
1068        Private ->
1069            {lists:sublist(Private, 2), Private}
1070    end;
1071
1072
1073generate_key(ecdh, Curve, undefined) when Curve == x448 ;
1074                                          Curve == x25519 ->
1075    evp_generate_key_nif(Curve);
1076generate_key(ecdh, Curve, PrivKey) ->
1077    ec_key_generate(nif_curve_params(Curve), ensure_int_as_bin(PrivKey)).
1078
1079
1080evp_generate_key_nif(_Curve) -> ?nif_stub.
1081
1082
1083-spec compute_key(Type, OthersPublicKey, MyPrivateKey, Params)
1084                 -> SharedSecret
1085                        when Type :: dh | ecdh | srp,
1086                             SharedSecret :: binary(),
1087                             OthersPublicKey :: dh_public() | ecdh_public() | srp_public(),
1088                             MyPrivateKey :: dh_private() | ecdh_private() | {srp_public(),srp_private()},
1089                             Params :: dh_params() | ecdh_params() | srp_comp_params()
1090                                       .
1091
1092compute_key(dh, OthersPublicKey, MyPrivateKey, DHParameters) ->
1093    case dh_compute_key_nif(ensure_int_as_bin(OthersPublicKey),
1094			    ensure_int_as_bin(MyPrivateKey),
1095			    map_ensure_int_as_bin(DHParameters)) of
1096	error -> erlang:error(computation_failed,
1097			      [dh,OthersPublicKey,MyPrivateKey,DHParameters]);
1098	Ret -> Ret
1099    end;
1100
1101compute_key(srp, HostPublic, {UserPublic, UserPrivate},
1102	    {user, [DerivedKey, Prime, Generator, Version | ScramblerArg]}) when
1103      is_binary(Prime),
1104      is_binary(Generator),
1105      is_atom(Version) ->
1106    HostPubBin = ensure_int_as_bin(HostPublic),
1107    Multiplier = srp_multiplier(Version, Generator, Prime),
1108    Scrambler = case ScramblerArg of
1109		    [] -> srp_scrambler(Version, ensure_int_as_bin(UserPublic),
1110					HostPubBin, Prime);
1111		    [S] -> S
1112		end,
1113    notsup_to_error(
1114    srp_user_secret_nif(ensure_int_as_bin(UserPrivate), Scrambler, HostPubBin,
1115                          Multiplier, Generator, DerivedKey, Prime));
1116
1117compute_key(srp, UserPublic, {HostPublic, HostPrivate},
1118	    {host,[Verifier, Prime, Version | ScramblerArg]}) when
1119      is_binary(Verifier),
1120      is_binary(Prime),
1121      is_atom(Version) ->
1122    UserPubBin = ensure_int_as_bin(UserPublic),
1123    Scrambler = case ScramblerArg of
1124		    [] -> srp_scrambler(Version, UserPubBin, ensure_int_as_bin(HostPublic), Prime);
1125		    [S] -> S
1126		end,
1127    notsup_to_error(
1128    srp_host_secret_nif(Verifier, ensure_int_as_bin(HostPrivate), Scrambler,
1129                          UserPubBin, Prime));
1130
1131compute_key(ecdh, Others, My, Curve) when Curve == x448 ;
1132                                          Curve == x25519 ->
1133    evp_compute_key_nif(Curve, ensure_int_as_bin(Others), ensure_int_as_bin(My));
1134
1135compute_key(ecdh, Others, My, Curve) ->
1136    ecdh_compute_key_nif(ensure_int_as_bin(Others),
1137			 nif_curve_params(Curve),
1138			 ensure_int_as_bin(My)).
1139
1140
1141evp_compute_key_nif(_Curve, _OthersBin, _MyBin) -> ?nif_stub.
1142
1143
1144%%%================================================================
1145%%%
1146%%% XOR - xor to iolists and return a binary
1147%%% NB doesn't check that they are the same size, just concatenates
1148%%% them and sends them to the driver
1149%%%
1150%%%================================================================
1151
1152-spec exor(iodata(), iodata()) -> binary().
1153
1154exor(Bin1, Bin2) ->
1155    Data1 = iolist_to_binary(Bin1),
1156    Data2 = iolist_to_binary(Bin2),
1157    MaxBytes = max_bytes(),
1158    exor(Data1, Data2, erlang:byte_size(Data1), MaxBytes, []).
1159
1160
1161%%%================================================================
1162%%%
1163%%% Exponentiation modulo
1164%%%
1165%%%================================================================
1166
1167-spec mod_pow(N, P, M) -> Result when N :: binary() | integer(),
1168                                      P :: binary() | integer(),
1169                                      M :: binary() | integer(),
1170                                      Result :: binary() | error .
1171mod_pow(Base, Exponent, Prime) ->
1172    case mod_exp_nif(ensure_int_as_bin(Base), ensure_int_as_bin(Exponent), ensure_int_as_bin(Prime), 0) of
1173	<<0>> -> error;
1174	R -> R
1175    end.
1176
1177%%%======================================================================
1178%%%
1179%%% Engine functions
1180%%%
1181%%%======================================================================
1182
1183%%%---- Refering to keys stored in an engine:
1184-type key_id()   :: string() | binary() .
1185-type password() :: string() | binary() .
1186
1187-type engine_key_ref() :: #{engine :=   engine_ref(),
1188                            key_id :=   key_id(),
1189                            password => password(),
1190                            term() => term()
1191                           }.
1192
1193%%%---- Commands:
1194-type engine_cmnd() :: {unicode:chardata(), unicode:chardata()}.
1195
1196%%----------------------------------------------------------------------
1197%% Function: engine_get_all_methods/0
1198%%----------------------------------------------------------------------
1199-type engine_method_type() :: engine_method_rsa | engine_method_dsa | engine_method_dh |
1200                              engine_method_rand | engine_method_ecdh | engine_method_ecdsa |
1201                              engine_method_ciphers | engine_method_digests | engine_method_store |
1202                              engine_method_pkey_meths | engine_method_pkey_asn1_meths |
1203                              engine_method_ec.
1204
1205-type engine_ref() :: term().
1206
1207-spec engine_get_all_methods() -> Result when Result :: [engine_method_type()].
1208engine_get_all_methods() ->
1209     notsup_to_error(engine_get_all_methods_nif()).
1210
1211%%----------------------------------------------------------------------
1212%% Function: engine_load/3
1213%%----------------------------------------------------------------------
1214-spec engine_load(EngineId, PreCmds, PostCmds) ->
1215                         Result when EngineId::unicode:chardata(),
1216                                     PreCmds::[engine_cmnd()],
1217                                     PostCmds::[engine_cmnd()],
1218                                     Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
1219engine_load(EngineId, PreCmds, PostCmds) when is_list(PreCmds),
1220                                              is_list(PostCmds) ->
1221    engine_load(EngineId, PreCmds, PostCmds, engine_get_all_methods()).
1222
1223%%----------------------------------------------------------------------
1224%% Function: engine_load/4
1225%%----------------------------------------------------------------------
1226-spec engine_load(EngineId, PreCmds, PostCmds, EngineMethods) ->
1227                         Result when EngineId::unicode:chardata(),
1228                                     PreCmds::[engine_cmnd()],
1229                                     PostCmds::[engine_cmnd()],
1230                                     EngineMethods::[engine_method_type()],
1231                                     Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
1232engine_load(EngineId, PreCmds, PostCmds, EngineMethods) when is_list(PreCmds),
1233                                                             is_list(PostCmds) ->
1234    try
1235        ok = notsup_to_error(engine_load_dynamic_nif()),
1236        case notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId))) of
1237            {ok, Engine} ->
1238                engine_load_1(Engine, PreCmds, PostCmds, EngineMethods);
1239            {error, Error1} ->
1240                {error, Error1}
1241        end
1242    catch
1243        throw:Error2 ->
1244            Error2
1245    end.
1246
1247engine_load_1(Engine, PreCmds, PostCmds, EngineMethods) ->
1248    try
1249        ok = engine_nif_wrapper(engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds(PreCmds), 0)),
1250        ok = engine_nif_wrapper(engine_init_nif(Engine)),
1251        engine_load_2(Engine, PostCmds, EngineMethods),
1252        {ok, Engine}
1253    catch
1254        throw:Error ->
1255            %% The engine couldn't initialise, release the structural reference
1256            ok = engine_free_nif(Engine),
1257            throw(Error);
1258        error:badarg ->
1259            %% For example bad argument list, release the structural reference
1260            ok = engine_free_nif(Engine),
1261            error(badarg)
1262    end.
1263
1264engine_load_2(Engine, PostCmds, EngineMethods) ->
1265    try
1266        ok = engine_nif_wrapper(engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds(PostCmds), 0)),
1267        [ok = engine_nif_wrapper(engine_register_nif(Engine, engine_method_atom_to_int(Method))) ||
1268            Method <- EngineMethods],
1269        ok
1270    catch
1271       throw:Error ->
1272          %% The engine registration failed, release the functional reference
1273          ok = engine_finish_nif(Engine),
1274          throw(Error)
1275    end.
1276
1277%%----------------------------------------------------------------------
1278%% Function: engine_unload/1
1279%%----------------------------------------------------------------------
1280-spec engine_unload(Engine) -> Result when Engine :: engine_ref(),
1281                                           Result :: ok | {error, Reason::term()}.
1282engine_unload(Engine) ->
1283    engine_unload(Engine, engine_get_all_methods()).
1284
1285-spec engine_unload(Engine, EngineMethods) -> Result when Engine :: engine_ref(),
1286                                                          EngineMethods :: [engine_method_type()],
1287                                                          Result :: ok | {error, Reason::term()}.
1288engine_unload(Engine, EngineMethods) ->
1289    try
1290        [ok = engine_nif_wrapper(engine_unregister_nif(Engine, engine_method_atom_to_int(Method))) ||
1291            Method <- EngineMethods],
1292        %% Release the functional reference from engine_init_nif
1293        ok = engine_nif_wrapper(engine_finish_nif(Engine)),
1294        %% Release the structural reference from engine_by_id_nif
1295        ok = engine_nif_wrapper(engine_free_nif(Engine))
1296    catch
1297       throw:Error ->
1298          Error
1299    end.
1300
1301%%----------------------------------------------------------------------
1302%% Function: engine_by_id/1
1303%%----------------------------------------------------------------------
1304-spec engine_by_id(EngineId) -> Result when EngineId :: unicode:chardata(),
1305                                            Result :: {ok, Engine::engine_ref()} | {error, Reason::term()} .
1306engine_by_id(EngineId) ->
1307    try
1308        notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId)))
1309    catch
1310       throw:Error ->
1311          Error
1312    end.
1313
1314%%----------------------------------------------------------------------
1315%% Function: engine_add/1
1316%%----------------------------------------------------------------------
1317-spec engine_add(Engine) -> Result when Engine :: engine_ref(),
1318                                        Result ::  ok | {error, Reason::term()} .
1319engine_add(Engine) ->
1320    notsup_to_error(engine_add_nif(Engine)).
1321
1322%%----------------------------------------------------------------------
1323%% Function: engine_remove/1
1324%%----------------------------------------------------------------------
1325-spec engine_remove(Engine) -> Result when Engine :: engine_ref(),
1326                                           Result ::  ok | {error, Reason::term()} .
1327engine_remove(Engine) ->
1328    notsup_to_error(engine_remove_nif(Engine)).
1329
1330%%----------------------------------------------------------------------
1331%% Function: engine_get_id/1
1332%%----------------------------------------------------------------------
1333-spec engine_get_id(Engine) -> EngineId when Engine :: engine_ref(),
1334                                             EngineId :: unicode:chardata().
1335engine_get_id(Engine) ->
1336    notsup_to_error(engine_get_id_nif(Engine)).
1337
1338%%----------------------------------------------------------------------
1339%% Function: engine_get_name/1
1340%%----------------------------------------------------------------------
1341-spec engine_get_name(Engine) -> EngineName when Engine :: engine_ref(),
1342                                                 EngineName :: unicode:chardata().
1343engine_get_name(Engine) ->
1344    notsup_to_error(engine_get_name_nif(Engine)).
1345
1346%%----------------------------------------------------------------------
1347%% Function: engine_list/0
1348%%----------------------------------------------------------------------
1349-spec engine_list() -> Result when Result :: [EngineId::unicode:chardata()].
1350engine_list() ->
1351    case notsup_to_error(engine_get_first_nif()) of
1352        {ok, <<>>} ->
1353            [];
1354        {ok, Engine} ->
1355            case notsup_to_error(engine_get_id_nif(Engine)) of
1356                <<>> ->
1357                    engine_list(Engine, []);
1358                EngineId ->
1359                    engine_list(Engine, [EngineId])
1360            end
1361    end.
1362
1363engine_list(Engine0, IdList) ->
1364    case notsup_to_error(engine_get_next_nif(Engine0)) of
1365        {ok, <<>>} ->
1366            lists:reverse(IdList);
1367        {ok, Engine1} ->
1368            case notsup_to_error(engine_get_id_nif(Engine1)) of
1369                <<>> ->
1370                    engine_list(Engine1, IdList);
1371                EngineId ->
1372                    engine_list(Engine1, [EngineId |IdList])
1373            end
1374    end.
1375
1376%%----------------------------------------------------------------------
1377%% Function: engine_ctrl_cmd_string/3
1378%%----------------------------------------------------------------------
1379-spec engine_ctrl_cmd_string(Engine, CmdName, CmdArg) ->
1380                                    Result when Engine::term(),
1381                                                CmdName::unicode:chardata(),
1382                                                CmdArg::unicode:chardata(),
1383                                                Result :: ok | {error, Reason::term()}.
1384engine_ctrl_cmd_string(Engine, CmdName, CmdArg) ->
1385    engine_ctrl_cmd_string(Engine, CmdName, CmdArg, false).
1386
1387%%----------------------------------------------------------------------
1388%% Function: engine_ctrl_cmd_string/4
1389%%----------------------------------------------------------------------
1390-spec engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) ->
1391                                    Result when Engine::term(),
1392                                                CmdName::unicode:chardata(),
1393                                                CmdArg::unicode:chardata(),
1394                                                Optional::boolean(),
1395                                                Result :: ok | {error, Reason::term()}.
1396engine_ctrl_cmd_string(Engine, CmdName, CmdArg, Optional) ->
1397    case engine_ctrl_cmd_strings_nif(Engine,
1398                                     ensure_bin_cmds([{CmdName, CmdArg}]),
1399                                     bool_to_int(Optional)) of
1400        ok ->
1401            ok;
1402        notsup ->
1403            erlang:error(notsup);
1404        {error, Error} ->
1405            {error, Error}
1406    end.
1407
1408%%----------------------------------------------------------------------
1409%% Function: ensure_engine_loaded/2
1410%% Special version of load that only uses dynamic engine to load
1411%%----------------------------------------------------------------------
1412-spec ensure_engine_loaded(EngineId, LibPath) ->
1413                                  Result when EngineId :: unicode:chardata(),
1414                                              LibPath :: unicode:chardata(),
1415                                              Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
1416ensure_engine_loaded(EngineId, LibPath) ->
1417    ensure_engine_loaded(EngineId, LibPath, engine_get_all_methods()).
1418
1419%%----------------------------------------------------------------------
1420%% Function: ensure_engine_loaded/3
1421%% Special version of load that only uses dynamic engine to load
1422%%----------------------------------------------------------------------
1423-spec ensure_engine_loaded(EngineId, LibPath, EngineMethods) ->
1424                                  Result when EngineId :: unicode:chardata(),
1425                                              LibPath :: unicode:chardata(),
1426                                              EngineMethods :: [engine_method_type()],
1427                                              Result :: {ok, Engine::engine_ref()} | {error, Reason::term()}.
1428ensure_engine_loaded(EngineId, LibPath, EngineMethods) ->
1429    try
1430        List = crypto:engine_list(),
1431        case lists:member(EngineId, List) of
1432            true ->
1433                notsup_to_error(engine_by_id_nif(ensure_bin_chardata(EngineId)));
1434            false ->
1435                ok = notsup_to_error(engine_load_dynamic_nif()),
1436                case notsup_to_error(engine_by_id_nif(ensure_bin_chardata(<<"dynamic">>))) of
1437                    {ok, Engine} ->
1438                        PreCommands = [{<<"SO_PATH">>, ensure_bin_chardata(LibPath)},
1439                                       {<<"ID">>, ensure_bin_chardata(EngineId)},
1440                                       <<"LOAD">>],
1441                        ensure_engine_loaded_1(Engine, PreCommands, EngineMethods);
1442                    {error, Error1} ->
1443                        {error, Error1}
1444                end
1445        end
1446    catch
1447        throw:Error2 ->
1448            Error2
1449    end.
1450
1451ensure_engine_loaded_1(Engine, PreCmds, Methods) ->
1452    try
1453        ok = engine_nif_wrapper(engine_ctrl_cmd_strings_nif(Engine, ensure_bin_cmds(PreCmds), 0)),
1454        ok = engine_nif_wrapper(engine_add_nif(Engine)),
1455        ok = engine_nif_wrapper(engine_init_nif(Engine)),
1456        ensure_engine_loaded_2(Engine, Methods),
1457        {ok, Engine}
1458    catch
1459        throw:Error ->
1460            %% The engine couldn't initialise, release the structural reference
1461            ok = engine_free_nif(Engine),
1462            throw(Error)
1463    end.
1464
1465ensure_engine_loaded_2(Engine, Methods) ->
1466    try
1467        [ok = engine_nif_wrapper(engine_register_nif(Engine, engine_method_atom_to_int(Method))) ||
1468            Method <- Methods],
1469        ok
1470    catch
1471       throw:Error ->
1472          %% The engine registration failed, release the functional reference
1473          ok = engine_finish_nif(Engine),
1474          throw(Error)
1475    end.
1476%%----------------------------------------------------------------------
1477%% Function: ensure_engine_unloaded/1
1478%%----------------------------------------------------------------------
1479-spec ensure_engine_unloaded(Engine) -> Result when Engine :: engine_ref(),
1480                                                    Result :: ok | {error, Reason::term()}.
1481ensure_engine_unloaded(Engine) ->
1482    ensure_engine_unloaded(Engine, engine_get_all_methods()).
1483
1484%%----------------------------------------------------------------------
1485%% Function: ensure_engine_unloaded/2
1486%%----------------------------------------------------------------------
1487-spec ensure_engine_unloaded(Engine, EngineMethods) ->
1488                                    Result when Engine :: engine_ref(),
1489                                                EngineMethods :: [engine_method_type()],
1490                                                Result :: ok | {error, Reason::term()}.
1491ensure_engine_unloaded(Engine, EngineMethods) ->
1492    case engine_remove(Engine) of
1493        ok ->
1494            engine_unload(Engine, EngineMethods);
1495        {error, E} ->
1496            {error, E}
1497    end.
1498
1499%%--------------------------------------------------------------------
1500%%% On load
1501%%--------------------------------------------------------------------
1502on_load() ->
1503    LibBaseName = "crypto",
1504    PrivDir = code:priv_dir(crypto),
1505    LibName = case erlang:system_info(build_type) of
1506		  opt ->
1507		      LibBaseName;
1508		  Type ->
1509		      LibTypeName = LibBaseName ++ "."  ++ atom_to_list(Type),
1510		      case (filelib:wildcard(
1511			      filename:join(
1512				[PrivDir,
1513				 "lib",
1514				 LibTypeName ++ "*"])) /= []) orelse
1515			  (filelib:wildcard(
1516			     filename:join(
1517			       [PrivDir,
1518				"lib",
1519				erlang:system_info(system_architecture),
1520				LibTypeName ++ "*"])) /= []) of
1521			  true -> LibTypeName;
1522			  false -> LibBaseName
1523		      end
1524	      end,
1525    Lib = filename:join([PrivDir, "lib", LibName]),
1526    LibBin   = path2bin(Lib),
1527    FipsMode = application:get_env(crypto, fips_mode, false) == true,
1528    Status = case erlang:load_nif(Lib, {?CRYPTO_NIF_VSN,LibBin,FipsMode}) of
1529		 ok -> ok;
1530		 {error, {load_failed, _}}=Error1 ->
1531		     ArchLibDir =
1532			 filename:join([PrivDir, "lib",
1533					erlang:system_info(system_architecture)]),
1534		     Candidate =
1535			 filelib:wildcard(filename:join([ArchLibDir,LibName ++ "*" ])),
1536		     case Candidate of
1537			 [] -> Error1;
1538			 _ ->
1539			     ArchLib = filename:join([ArchLibDir, LibName]),
1540                             ArchBin = path2bin(ArchLib),
1541			     erlang:load_nif(ArchLib, {?CRYPTO_NIF_VSN,ArchBin,FipsMode})
1542		     end;
1543		 Error1 -> Error1
1544	     end,
1545    case Status of
1546	ok -> ok;
1547	{error, {E, Str}} ->
1548            Fmt = "Unable to load crypto library. Failed with error:~n\"~p, ~s\"~n~s",
1549            Extra = case E of
1550                        load_failed ->
1551                            "OpenSSL might not be installed on this system.\n";
1552                        _ -> ""
1553                    end,
1554	    error_logger:error_msg(Fmt, [E,Str,Extra]),
1555	    Status
1556    end.
1557
1558path2bin(Path) when is_list(Path) ->
1559    Encoding = file:native_name_encoding(),
1560    case unicode:characters_to_binary(Path,Encoding,Encoding) of
1561	Bin when is_binary(Bin) ->
1562	    Bin
1563    end.
1564
1565%%%================================================================
1566%%%================================================================
1567%%%
1568%%% Internal functions
1569%%%
1570%%%================================================================
1571
1572max_bytes() ->
1573    ?MAX_BYTES_TO_NIF.
1574
1575notsup_to_error(notsup) ->
1576    erlang:error(notsup);
1577notsup_to_error(Other) ->
1578    Other.
1579
1580%% HASH --------------------------------------------------------------------
1581hash(Hash, Data, Size, Max) when Size =< Max ->
1582    notsup_to_error(hash_nif(Hash, Data));
1583hash(Hash, Data, Size, Max) ->
1584    State0 = hash_init(Hash),
1585    State1 = hash_update(State0, Data, Size, Max),
1586    hash_final(State1).
1587
1588hash_update(State, Data, Size, MaxBytes)  when Size =< MaxBytes ->
1589    notsup_to_error(hash_update_nif(State, Data));
1590hash_update(State0, Data, _, MaxBytes) ->
1591    <<Increment:MaxBytes/binary, Rest/binary>> = Data,
1592    State = notsup_to_error(hash_update_nif(State0, Increment)),
1593    hash_update(State, Rest, erlang:byte_size(Rest), MaxBytes).
1594
1595hash_nif(_Hash, _Data) -> ?nif_stub.
1596hash_init_nif(_Hash) -> ?nif_stub.
1597hash_update_nif(_State, _Data) -> ?nif_stub.
1598hash_final_nif(_State) -> ?nif_stub.
1599
1600%% HMAC --------------------------------------------------------------------
1601
1602hmac(Type, Key, Data, MacSize, Size, MaxBytes) when Size =< MaxBytes ->
1603    notsup_to_error(
1604    case MacSize of
1605          undefined -> hmac_nif(Type, Key, Data);
1606          _         -> hmac_nif(Type, Key, Data, MacSize)
1607      end);
1608hmac(Type, Key, Data, MacSize, Size, MaxBytes) ->
1609    State0 = hmac_init(Type, Key),
1610    State1 = hmac_update(State0, Data, Size, MaxBytes),
1611    case MacSize of
1612        undefined -> hmac_final(State1);
1613        _         -> hmac_final_n(State1, MacSize)
1614    end.
1615
1616hmac_update(State, Data, Size, MaxBytes)  when Size =< MaxBytes ->
1617    notsup_to_error(hmac_update_nif(State, Data));
1618hmac_update(State0, Data, _, MaxBytes) ->
1619    <<Increment:MaxBytes/binary, Rest/binary>> = Data,
1620    State = notsup_to_error(hmac_update_nif(State0, Increment)),
1621    hmac_update(State, Rest, erlang:byte_size(Rest), MaxBytes).
1622
1623hmac_nif(_Type, _Key, _Data) -> ?nif_stub.
1624hmac_nif(_Type, _Key, _Data, _MacSize) -> ?nif_stub.
1625hmac_init_nif(_Type, _Key) -> ?nif_stub.
1626hmac_update_nif(_Context, _Data) -> ?nif_stub.
1627hmac_final_nif(_Context) -> ?nif_stub.
1628hmac_final_nif(_Context, _MacSize) -> ?nif_stub.
1629
1630%% CMAC
1631cmac_nif(_Type, _Key, _Data) -> ?nif_stub.
1632
1633%% POLY1305
1634poly1305_nif(_Key, _Data) -> ?nif_stub.
1635
1636
1637%% CIPHERS --------------------------------------------------------------------
1638
1639block_crypt_nif(_Type, _Key, _Ivec, _Text, _IsEncrypt) -> ?nif_stub.
1640block_crypt_nif(_Type, _Key, _Text, _IsEncrypt) -> ?nif_stub.
1641
1642check_des3_key(Key) ->
1643    case lists:map(fun erlang:iolist_to_binary/1, Key) of
1644        ValidKey = [B1, B2, B3] when byte_size(B1) =:= 8,
1645                                     byte_size(B2) =:= 8,
1646                                     byte_size(B3) =:= 8 ->
1647            ValidKey;
1648        _ ->
1649            error(badarg)
1650   end.
1651
1652%%
1653%% AES - in Galois/Counter Mode (GCM)
1654%%
1655%% The default tag length is EVP_GCM_TLS_TAG_LEN(16),
1656aead_encrypt(Type=aes_ccm, Key, Ivec, AAD, In) -> aead_encrypt(Type, Key, Ivec, AAD, In, 12);
1657aead_encrypt(Type=aes_gcm, Key, Ivec, AAD, In) -> aead_encrypt(Type, Key, Ivec, AAD, In, 16).
1658
1659aead_encrypt(_Type, _Key, _Ivec, _AAD, _In, _TagLength) -> ?nif_stub.
1660aead_decrypt(_Type, _Key, _Ivec, _AAD, _In, _Tag) -> ?nif_stub.
1661
1662%%
1663%% AES - with 256 bit key in infinite garble extension mode (IGE)
1664%%
1665
1666aes_ige_crypt_nif(_Key, _IVec, _Data, _IsEncrypt) -> ?nif_stub.
1667
1668
1669%% Stream ciphers --------------------------------------------------------------------
1670
1671stream_crypt(Fun, State, Data, Size, MaxByts, []) when Size =< MaxByts ->
1672    Fun(State, Data);
1673stream_crypt(Fun, State0, Data, Size, MaxByts, Acc) when Size =< MaxByts ->
1674    {State, Cipher} = Fun(State0, Data),
1675    {State, list_to_binary(lists:reverse([Cipher | Acc]))};
1676stream_crypt(Fun, State0, Data, _, MaxByts, Acc) ->
1677    <<Increment:MaxByts/binary, Rest/binary>> = Data,
1678    {State, CipherText} = Fun(State0, Increment),
1679    stream_crypt(Fun, State, Rest, erlang:byte_size(Rest), MaxByts, [CipherText | Acc]).
1680
1681do_stream_encrypt({aes_ctr, State0}, Data) ->
1682    {State, Cipher} = aes_ctr_stream_encrypt(State0, Data),
1683    {{aes_ctr, State}, Cipher};
1684do_stream_encrypt({rc4, State0}, Data) ->
1685    {State, Cipher} = rc4_encrypt_with_state(State0, Data),
1686    {{rc4, State}, Cipher};
1687do_stream_encrypt({chacha20, State0}, Data) ->
1688    {State, Cipher} = chacha20_stream_encrypt(State0, Data),
1689    {{chacha20, State}, Cipher}.
1690
1691do_stream_decrypt({aes_ctr, State0}, Data) ->
1692    {State, Text} = aes_ctr_stream_decrypt(State0, Data),
1693    {{aes_ctr, State}, Text};
1694do_stream_decrypt({rc4, State0}, Data) ->
1695    {State, Text} = rc4_encrypt_with_state(State0, Data),
1696    {{rc4, State}, Text};
1697do_stream_decrypt({chacha20, State0}, Data) ->
1698    {State, Cipher} = chacha20_stream_decrypt(State0, Data),
1699    {{chacha20, State}, Cipher}.
1700
1701
1702%%
1703%% AES - in counter mode (CTR) with state maintained for multi-call streaming
1704%%
1705aes_ctr_stream_init(_Key, _IVec) -> ?nif_stub.
1706aes_ctr_stream_encrypt(_State, _Data) -> ?nif_stub.
1707aes_ctr_stream_decrypt(_State, _Cipher) -> ?nif_stub.
1708
1709%%
1710%% RC4 - symmetric stream cipher
1711%%
1712rc4_set_key(_Key) -> ?nif_stub.
1713rc4_encrypt_with_state(_State, _Data) -> ?nif_stub.
1714
1715%%
1716%% CHACHA20 - stream cipher
1717%%
1718chacha20_stream_init(_Key, _IVec) -> ?nif_stub.
1719chacha20_stream_encrypt(_State, _Data) -> ?nif_stub.
1720chacha20_stream_decrypt(_State, _Data) -> ?nif_stub.
1721
1722%% Secure remote password  -------------------------------------------------------------------
1723
1724user_srp_gen_key(Private, Generator, Prime) ->
1725    %% Ensure the SRP algorithm is disabled in FIPS mode
1726    case info_fips() of
1727        enabled -> erlang:error(notsup);
1728        _       -> ok
1729    end,
1730    case mod_pow(Generator, Private, Prime) of
1731	error ->
1732	    error;
1733	Public ->
1734	    {Public, Private}
1735    end.
1736
1737host_srp_gen_key(Private, Verifier, Generator, Prime, Version) ->
1738 Multiplier = srp_multiplier(Version, Generator, Prime),
1739   case srp_value_B_nif(Multiplier, Verifier, Generator, Private, Prime) of
1740   error ->
1741       error;
1742   notsup ->
1743       erlang:error(notsup);
1744   Public ->
1745       {Public, Private}
1746   end.
1747
1748srp_multiplier('6a', Generator, Prime) ->
1749    %% k = SHA1(N | PAD(g)) from http://srp.stanford.edu/design.html
1750    C0 = hash_init(sha),
1751    C1 = hash_update(C0, Prime),
1752    C2 = hash_update(C1, srp_pad_to(erlang:byte_size(Prime), Generator)),
1753    hash_final(C2);
1754srp_multiplier('6', _, _) ->
1755    <<3/integer>>;
1756srp_multiplier('3', _, _) ->
1757    <<1/integer>>.
1758
1759srp_scrambler(Version, UserPublic, HostPublic, Prime) when Version == '6'; Version == '6a'->
1760    %% SHA1(PAD(A) | PAD(B)) from http://srp.stanford.edu/design.html
1761    PadLength = erlang:byte_size(Prime),
1762    C0 = hash_init(sha),
1763    C1 = hash_update(C0, srp_pad_to(PadLength, UserPublic)),
1764    C2 = hash_update(C1, srp_pad_to(PadLength, HostPublic)),
1765    hash_final(C2);
1766srp_scrambler('3', _, HostPublic, _Prime) ->
1767    %% The parameter u is a 32-bit unsigned integer which takes its value
1768    %% from the first 32 bits of the SHA1 hash of B, MSB first.
1769    <<U:32/bits, _/binary>> = hash(sha, HostPublic),
1770    U.
1771
1772srp_pad_length(Width, Length) ->
1773    (Width - Length rem Width) rem Width.
1774
1775srp_pad_to(Width, Binary) ->
1776    case srp_pad_length(Width, size(Binary)) of
1777        0 -> Binary;
1778        N -> << 0:(N*8), Binary/binary>>
1779    end.
1780
1781srp_host_secret_nif(_Verifier, _B, _U, _A, _Prime) -> ?nif_stub.
1782
1783srp_user_secret_nif(_A, _U, _B, _Multiplier, _Generator, _Exponent, _Prime) -> ?nif_stub.
1784
1785srp_value_B_nif(_Multiplier, _Verifier, _Generator, _Exponent, _Prime) -> ?nif_stub.
1786
1787
1788%% Public Keys  --------------------------------------------------------------------
1789%% RSA Rivest-Shamir-Adleman functions
1790%%
1791
1792rsa_generate_key_nif(_Bits, _Exp) -> ?nif_stub.
1793
1794%% DH Diffie-Hellman functions
1795%%
1796
1797%% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()]
1798%% PrivKey = mpint()
1799dh_generate_key_nif(_PrivateKey, _DHParameters, _Mpint, _Length) -> ?nif_stub.
1800
1801%% DHParameters = [P (Prime)= mpint(), G(Generator) = mpint()]
1802%% MyPrivKey, OthersPublicKey = mpint()
1803dh_compute_key_nif(_OthersPublicKey, _MyPrivateKey, _DHParameters) -> ?nif_stub.
1804
1805ec_key_generate(_Curve, _Key) -> ?nif_stub.
1806
1807ecdh_compute_key_nif(_Others, _Curve, _My) -> ?nif_stub.
1808
1809-spec ec_curves() -> [EllipticCurve] when EllipticCurve :: ec_named_curve()
1810                                                         | edwards_curve_dh()
1811                                                         | edwards_curve_ed() .
1812
1813ec_curves() ->
1814    crypto_ec_curves:curves().
1815
1816-spec ec_curve(CurveName) -> ExplicitCurve when CurveName :: ec_named_curve(),
1817                                                ExplicitCurve :: ec_explicit_curve() .
1818ec_curve(X) ->
1819    crypto_ec_curves:curve(X).
1820
1821
1822-spec privkey_to_pubkey(Type, EnginePrivateKeyRef) -> PublicKey when Type :: rsa | dss,
1823                                                                     EnginePrivateKeyRef :: engine_key_ref(),
1824                                                                     PublicKey ::  rsa_public() | dss_public() .
1825privkey_to_pubkey(Alg, EngineMap) when Alg == rsa; Alg == dss; Alg == ecdsa ->
1826    try privkey_to_pubkey_nif(Alg, format_pkey(Alg,EngineMap))
1827    of
1828        [_|_]=L -> map_ensure_bin_as_int(L);
1829        X -> X
1830    catch
1831        error:badarg when Alg==ecdsa ->
1832            {error, notsup};
1833        error:badarg ->
1834            {error, not_found};
1835        error:notsup ->
1836            {error, notsup}
1837    end.
1838
1839privkey_to_pubkey_nif(_Alg, _EngineMap) -> ?nif_stub.
1840
1841
1842%%
1843%% EC
1844%%
1845
1846term_to_nif_prime({prime_field, Prime}) ->
1847    {prime_field, ensure_int_as_bin(Prime)};
1848term_to_nif_prime(PrimeField) ->
1849    PrimeField.
1850
1851term_to_nif_curve({A, B, Seed}) ->
1852    {ensure_int_as_bin(A), ensure_int_as_bin(B), Seed}.
1853
1854nif_curve_params({PrimeField, Curve, BasePoint, Order, CoFactor}) ->
1855    {term_to_nif_prime(PrimeField),
1856     term_to_nif_curve(Curve),
1857     ensure_int_as_bin(BasePoint),
1858     ensure_int_as_bin(Order),
1859     ensure_int_as_bin(CoFactor)};
1860nif_curve_params(Curve) when is_atom(Curve) ->
1861    %% named curve
1862    case Curve of
1863        x448 -> {evp,Curve};
1864        x25519 -> {evp,Curve};
1865        _ -> crypto_ec_curves:curve(Curve)
1866    end.
1867
1868
1869%% MISC --------------------------------------------------------------------
1870
1871exor(Data1, Data2, Size, MaxByts, [])  when Size =< MaxByts ->
1872    do_exor(Data1, Data2);
1873exor(Data1, Data2, Size, MaxByts, Acc) when Size =< MaxByts ->
1874    Result = do_exor(Data1, Data2),
1875    list_to_binary(lists:reverse([Result | Acc]));
1876exor(Data1, Data2, _Size, MaxByts, Acc) ->
1877     <<Increment1:MaxByts/binary, Rest1/binary>> = Data1,
1878     <<Increment2:MaxByts/binary, Rest2/binary>> = Data2,
1879    Result = do_exor(Increment1, Increment2),
1880    exor(Rest1, Rest2, erlang:byte_size(Rest1), MaxByts, [Result | Acc]).
1881
1882do_exor(_A, _B) -> ?nif_stub.
1883
1884algorithms() -> ?nif_stub.
1885
1886int_to_bin(X) when X < 0 -> int_to_bin_neg(X, []);
1887int_to_bin(X) -> int_to_bin_pos(X, []).
1888
1889int_to_bin_pos(0,Ds=[_|_]) ->
1890    list_to_binary(Ds);
1891int_to_bin_pos(X,Ds) ->
1892    int_to_bin_pos(X bsr 8, [(X band 255)|Ds]).
1893
1894int_to_bin_neg(-1, Ds=[MSB|_]) when MSB >= 16#80 ->
1895    list_to_binary(Ds);
1896int_to_bin_neg(X,Ds) ->
1897    int_to_bin_neg(X bsr 8, [(X band 255)|Ds]).
1898
1899-spec bytes_to_integer(binary()) -> integer() .
1900bytes_to_integer(Bin) ->
1901    bin_to_int(Bin).
1902
1903bin_to_int(Bin) when is_binary(Bin) ->
1904    Bits = bit_size(Bin),
1905    <<Integer:Bits/integer>> = Bin,
1906    Integer;
1907bin_to_int(undefined) ->
1908    undefined.
1909
1910map_ensure_int_as_bin([H|_]=List) when is_integer(H) ->
1911    lists:map(fun(E) -> int_to_bin(E) end, List);
1912map_ensure_int_as_bin(List) ->
1913    List.
1914
1915ensure_int_as_bin(Int) when is_integer(Int) ->
1916    int_to_bin(Int);
1917ensure_int_as_bin(Bin) ->
1918    Bin.
1919
1920map_ensure_bin_as_int(List) when is_list(List) ->
1921    lists:map(fun ensure_bin_as_int/1, List).
1922
1923ensure_bin_as_int(Bin) when is_binary(Bin) ->
1924    bin_to_int(Bin);
1925ensure_bin_as_int(E) ->
1926    E.
1927
1928format_pkey(_Alg, #{engine:=_, key_id:=T}=M) when is_binary(T) -> format_pwd(M);
1929format_pkey(_Alg, #{engine:=_, key_id:=T}=M) when is_list(T) -> format_pwd(M#{key_id:=list_to_binary(T)});
1930format_pkey(_Alg, #{engine:=_           }=M) -> error({bad_key_id, M});
1931format_pkey(_Alg, #{}=M) -> error({bad_engine_map, M});
1932%%%
1933format_pkey(rsa, Key) ->
1934    map_ensure_int_as_bin(Key);
1935format_pkey(ecdsa, [Key, Curve]) ->
1936    {nif_curve_params(Curve), ensure_int_as_bin(Key)};
1937format_pkey(dss, Key) ->
1938    map_ensure_int_as_bin(Key);
1939format_pkey(_, Key) ->
1940    Key.
1941
1942format_pwd(#{password := Pwd}=M) when is_list(Pwd) -> M#{password := list_to_binary(Pwd)};
1943format_pwd(M) -> M.
1944
1945%%--------------------------------------------------------------------
1946%%
1947
1948%% large integer in a binary with 32bit length
1949%% MP representaion  (SSH2)
1950mpint(X) when X < 0 -> mpint_neg(X);
1951mpint(X) -> mpint_pos(X).
1952
1953-define(UINT32(X),   X:32/unsigned-big-integer).
1954
1955
1956mpint_neg(X) ->
1957    Bin = int_to_bin_neg(X, []),
1958    Sz = byte_size(Bin),
1959    <<?UINT32(Sz), Bin/binary>>.
1960
1961mpint_pos(X) ->
1962    Bin = int_to_bin_pos(X, []),
1963    <<MSB,_/binary>> = Bin,
1964    Sz = byte_size(Bin),
1965    if MSB band 16#80 == 16#80 ->
1966	    <<?UINT32((Sz+1)), 0, Bin/binary>>;
1967       true ->
1968	    <<?UINT32(Sz), Bin/binary>>
1969    end.
1970
1971%% int from integer in a binary with 32bit length
1972erlint(<<MPIntSize:32/integer,MPIntValue/binary>>) ->
1973    Bits= MPIntSize * 8,
1974    <<Integer:Bits/integer>> = MPIntValue,
1975    Integer.
1976
1977%%
1978%% mod_exp - utility for rsa generation and SRP
1979%%
1980mod_exp_nif(_Base,_Exp,_Mod,_bin_hdr) -> ?nif_stub.
1981
1982%%%----------------------------------------------------------------
1983%% 9470495 == V(0,9,8,zh).
1984%% 268435615 == V(1,0,0,i).
1985%% 268439663 == V(1,0,1,f).
1986
1987packed_openssl_version(MAJ, MIN, FIX, P0) ->
1988    %% crypto.c
1989    P1 = atom_to_list(P0),
1990    P = lists:sum([C-$a||C<-P1]),
1991    ((((((((MAJ bsl 8) bor MIN) bsl 8 ) bor FIX) bsl 8) bor (P+1)) bsl 4) bor 16#f).
1992
1993%%--------------------------------------------------------------------
1994%% Engine nifs
1995engine_by_id_nif(_EngineId) -> ?nif_stub.
1996engine_init_nif(_Engine) -> ?nif_stub.
1997engine_finish_nif(_Engine) -> ?nif_stub.
1998engine_free_nif(_Engine) -> ?nif_stub.
1999engine_load_dynamic_nif() -> ?nif_stub.
2000engine_ctrl_cmd_strings_nif(_Engine, _Cmds, _Optional) -> ?nif_stub.
2001engine_add_nif(_Engine)  -> ?nif_stub.
2002engine_remove_nif(_Engine)  -> ?nif_stub.
2003engine_register_nif(_Engine, _EngineMethod) -> ?nif_stub.
2004engine_unregister_nif(_Engine, _EngineMethod) -> ?nif_stub.
2005engine_get_first_nif() -> ?nif_stub.
2006engine_get_next_nif(_Engine) -> ?nif_stub.
2007engine_get_id_nif(_Engine) -> ?nif_stub.
2008engine_get_name_nif(_Engine) -> ?nif_stub.
2009engine_get_all_methods_nif() -> ?nif_stub.
2010
2011%%--------------------------------------------------------------------
2012%% Engine internals
2013engine_nif_wrapper(ok) ->
2014    ok;
2015engine_nif_wrapper(notsup) ->
2016    erlang:error(notsup);
2017engine_nif_wrapper({error, Error}) ->
2018    throw({error, Error}).
2019
2020ensure_bin_chardata(CharData) when is_binary(CharData) ->
2021    CharData;
2022ensure_bin_chardata(CharData) ->
2023    unicode:characters_to_binary(CharData).
2024
2025ensure_bin_cmds(CMDs) ->
2026    ensure_bin_cmds(CMDs, []).
2027
2028ensure_bin_cmds([], Acc) ->
2029    lists:reverse(Acc);
2030ensure_bin_cmds([{Key, Value} |CMDs], Acc) ->
2031    ensure_bin_cmds(CMDs, [{ensure_bin_chardata(Key), ensure_bin_chardata(Value)} | Acc]);
2032ensure_bin_cmds([Key | CMDs], Acc) ->
2033    ensure_bin_cmds(CMDs, [{ensure_bin_chardata(Key), <<"">>} | Acc]).
2034
2035engine_methods_convert_to_bitmask([], BitMask) ->
2036    BitMask;
2037engine_methods_convert_to_bitmask(engine_method_all, _BitMask) ->
2038    16#FFFF;
2039engine_methods_convert_to_bitmask(engine_method_none, _BitMask) ->
2040    16#0000;
2041engine_methods_convert_to_bitmask([M |Ms], BitMask) ->
2042    engine_methods_convert_to_bitmask(Ms, BitMask bor engine_method_atom_to_int(M)).
2043
2044bool_to_int(true) -> 1;
2045bool_to_int(false) -> 0.
2046
2047engine_method_atom_to_int(engine_method_rsa) -> 16#0001;
2048engine_method_atom_to_int(engine_method_dsa) -> 16#0002;
2049engine_method_atom_to_int(engine_method_dh) -> 16#0004;
2050engine_method_atom_to_int(engine_method_rand) -> 16#0008;
2051engine_method_atom_to_int(engine_method_ecdh) -> 16#0010;
2052engine_method_atom_to_int(engine_method_ecdsa) -> 16#0020;
2053engine_method_atom_to_int(engine_method_ciphers) -> 16#0040;
2054engine_method_atom_to_int(engine_method_digests) -> 16#0080;
2055engine_method_atom_to_int(engine_method_store) -> 16#0100;
2056engine_method_atom_to_int(engine_method_pkey_meths) -> 16#0200;
2057engine_method_atom_to_int(engine_method_pkey_asn1_meths) -> 16#0400;
2058engine_method_atom_to_int(engine_method_ec) -> 16#0800;
2059engine_method_atom_to_int(X) ->
2060    erlang:error(badarg, [X]).
2061
2062get_test_engine() ->
2063    Type = erlang:system_info(system_architecture),
2064    LibDir = filename:join([code:priv_dir(crypto), "lib"]),
2065    ArchDir = filename:join([LibDir, Type]),
2066    case filelib:is_dir(ArchDir) of
2067	true  -> check_otp_test_engine(ArchDir);
2068	false -> check_otp_test_engine(LibDir)
2069    end.
2070
2071check_otp_test_engine(LibDir) ->
2072    case filelib:wildcard("otp_test_engine*", LibDir) of
2073        [] ->
2074            {error, notexist};
2075        [LibName|_] ->                          % In case of Valgrind there could be more than one
2076            LibPath = filename:join(LibDir,LibName),
2077            case filelib:is_file(LibPath) of
2078                true ->
2079                    {ok, unicode:characters_to_binary(LibPath)};
2080                false ->
2081                    {error, notexist}
2082            end
2083    end.
2084