aboutsummaryrefslogtreecommitdiffstats
path: root/lib/crypto
diff options
context:
space:
mode:
authorHans Nilsson <[email protected]>2019-03-08 10:42:25 +0100
committerHans Nilsson <[email protected]>2019-03-19 12:45:55 +0100
commit3f8f8054254cee6bf401e1e83662e05029bde750 (patch)
treec3aeacea923d9d930850b228b15f4472e6067453 /lib/crypto
parent3a74629664f3d7f6ae7483954130dca7f9794c10 (diff)
downloadotp-3f8f8054254cee6bf401e1e83662e05029bde750.tar.gz
otp-3f8f8054254cee6bf401e1e83662e05029bde750.tar.bz2
otp-3f8f8054254cee6bf401e1e83662e05029bde750.zip
crypto: Exceptions as error return in api_ng
Diffstat (limited to 'lib/crypto')
-rw-r--r--lib/crypto/c_src/api_ng.c69
-rw-r--r--lib/crypto/c_src/atoms.c2
-rw-r--r--lib/crypto/c_src/atoms.h1
-rw-r--r--lib/crypto/src/crypto.erl120
-rw-r--r--lib/crypto/test/crypto_SUITE.erl90
5 files changed, 155 insertions, 127 deletions
diff --git a/lib/crypto/c_src/api_ng.c b/lib/crypto/c_src/api_ng.c
index a91951c84e..46522914b0 100644
--- a/lib/crypto/c_src/api_ng.c
+++ b/lib/crypto/c_src/api_ng.c
@@ -31,9 +31,14 @@ ERL_NIF_TERM ng_crypto_one_shot(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
-/* Try better error messages in new functions */
-#define ERROR_Term(Env, ReasonTerm) enif_make_tuple2((Env), atom_error, (ReasonTerm))
-#define ERROR_Str(Env, ReasonString) ERROR_Term((Env), enif_make_string((Env),(ReasonString),(ERL_NIF_LATIN1)))
+/* All nif functions return a valid value or throws an exception */
+#define EXCP(Env, Class, Str) enif_raise_exception((Env), \
+ enif_make_tuple2((Env), (Class), \
+ enif_make_string((Env),(Str),(ERL_NIF_LATIN1)) ))
+
+#define EXCP_NOTSUP(Env, Str) EXCP((Env), atom_notsup, (Str))
+#define EXCP_BADARG(Env, Str) EXCP((Env), atom_badarg, (Str))
+#define EXCP_ERROR(Env, Str) EXCP((Env), atom_error, (Str))
#ifdef HAVE_ECB_IVEC_BUG
@@ -73,33 +78,33 @@ static int get_init_args(ErlNifEnv* env,
encflg = -1;
else
{
- *return_term = ERROR_Str(env, "Bad enc flag");
+ *return_term = EXCP_BADARG(env, "Bad enc flag");
goto err;
}
/* Fetch the key */
if (!enif_inspect_iolist_as_binary(env, key_arg, &key_bin))
{
- *return_term = ERROR_Str(env, "Bad key");
+ *return_term = EXCP_BADARG(env, "Bad key");
goto err;
}
/* Fetch cipher type */
if (!enif_is_atom(env, cipher_arg))
{
- *return_term = ERROR_Str(env, "Cipher id is not an atom");
+ *return_term = EXCP_BADARG(env, "Cipher id is not an atom");
goto err;
}
if (!(*cipherp = get_cipher_type(cipher_arg, key_bin.size)))
{
- *return_term = ERROR_Str(env, "Unknown cipher or bad key size for the cipher");
+ *return_term = EXCP_BADARG(env, "Unknown cipher or bad key size for the cipher");
goto err;
}
if (FORBIDDEN_IN_FIPS(*cipherp))
{
- *return_term = enif_raise_exception(env, atom_notsup);
+ *return_term = EXCP_NOTSUP(env, "Forbidden in FIPS");
goto err;
}
@@ -118,13 +123,13 @@ static int get_init_args(ErlNifEnv* env,
if (ivec_len) {
if (!enif_inspect_iolist_as_binary(env, ivec_arg, &ivec_bin))
{
- *return_term = ERROR_Str(env, "Bad iv type");
+ *return_term = EXCP_BADARG(env, "Bad iv type");
goto err;
}
if (ivec_len != ivec_bin.size)
{
- *return_term = ERROR_Str(env, "Bad iv size");
+ *return_term = EXCP_BADARG(env, "Bad iv size");
goto err;
}
}
@@ -137,14 +142,14 @@ static int get_init_args(ErlNifEnv* env,
ERL_NIF_TERM ecount_bin;
unsigned char *outp;
if ((outp = enif_make_new_binary(env, AES_BLOCK_SIZE, &ecount_bin)) == NULL) {
- *return_term = ERROR_Str(env, "Can't allocate ecount_bin");
+ *return_term = EXCP_ERROR(env, "Can't allocate ecount_bin");
goto err;
}
memset(outp, 0, AES_BLOCK_SIZE);
ctx_res->env = enif_alloc_env();
if (!ctx_res->env) {
- *return_term = ERROR_Str(env, "Can't allocate env");
+ *return_term = EXCP_ERROR(env, "Can't allocate env");
goto err;
}
ctx_res->state =
@@ -153,7 +158,7 @@ static int get_init_args(ErlNifEnv* env,
goto success;
}
#endif
- *return_term = enif_raise_exception(env, atom_notsup);
+ *return_term = EXCP_NOTSUP(env, "Cipher");
goto err;
}
@@ -162,36 +167,36 @@ static int get_init_args(ErlNifEnv* env,
ctx_res->ctx = EVP_CIPHER_CTX_new();
if (! ctx_res->ctx)
{
- *return_term = ERROR_Str(env, "Can't allocate context");
+ *return_term = EXCP_ERROR(env, "Can't allocate context");
goto err;
}
if (!EVP_CipherInit_ex(ctx_res->ctx, (*cipherp)->cipher.p, NULL, NULL, NULL, encflg))
{
- *return_term = ERROR_Str(env, "Can't initialize context, step 1");
+ *return_term = EXCP_ERROR(env, "Can't initialize context, step 1");
goto err;
}
if (!EVP_CIPHER_CTX_set_key_length(ctx_res->ctx, (int)key_bin.size))
{
- *return_term = ERROR_Str(env, "Can't initialize context, key_length");
+ *return_term = EXCP_ERROR(env, "Can't initialize context, key_length");
goto err;
}
if (EVP_CIPHER_type((*cipherp)->cipher.p) == NID_rc2_cbc) {
if (key_bin.size > INT_MAX / 8) {
- *return_term = ERROR_Str(env, "To large rc2_cbc key");
+ *return_term = EXCP_BADARG(env, "To large rc2_cbc key");
goto err;
}
if (!EVP_CIPHER_CTX_ctrl(ctx_res->ctx, EVP_CTRL_SET_RC2_KEY_BITS, (int)key_bin.size * 8, NULL)) {
- *return_term = ERROR_Str(env, "ctrl rc2_cbc key");
+ *return_term = EXCP_ERROR(env, "ctrl rc2_cbc key");
goto err;
}
}
if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, key_bin.data, ivec_bin.data, -1)) {
- *return_term = ERROR_Str(env, "Can't initialize key and/or iv");
+ *return_term = EXCP_ERROR(env, "Can't initialize key and/or iv");
goto err;
}
@@ -223,7 +228,7 @@ static int get_update_args(ErlNifEnv* env,
if (!enif_inspect_binary(env, indata_arg, &in_data_bin) )
{
- *return_term = ERROR_Str(env, "Bad 2:nd arg");
+ *return_term = EXCP_BADARG(env, "Bad 2:nd arg");
goto err;
}
@@ -257,19 +262,19 @@ static int get_update_args(ErlNifEnv* env,
if (!enif_alloc_binary((size_t)in_data_bin.size+block_size, &out_data_bin))
{
- *return_term = ERROR_Str(env, "Can't allocate outdata");
+ *return_term = EXCP_ERROR(env, "Can't allocate outdata");
goto err;
}
if (!EVP_CipherUpdate(ctx_res->ctx, out_data_bin.data, &out_len, in_data_bin.data, in_data_bin.size))
{
- *return_term = ERROR_Str(env, "Can't update");
+ *return_term = EXCP_ERROR(env, "Can't update");
goto err;
}
if (!enif_realloc_binary(&out_data_bin, (size_t)out_len))
{
- *return_term = ERROR_Str(env, "Can't reallocate");
+ *return_term = EXCP_ERROR(env, "Can't reallocate");
goto err;
}
@@ -299,7 +304,7 @@ ERL_NIF_TERM ng_crypto_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
if (enif_is_atom(env, argv[0])) {
if ((ctx_res = enif_alloc_resource(evp_cipher_ctx_rtype, sizeof(struct evp_cipher_ctx))) == NULL)
- return ERROR_Str(env, "Can't allocate resource");
+ return EXCP_ERROR(env, "Can't allocate resource");
if (!get_init_args(env, ctx_res, argv[0], argv[1], argv[2], argv[argc-1],
&cipherp, &ret))
@@ -316,19 +321,19 @@ ERL_NIF_TERM ng_crypto_init_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
else if (argv[3] == atom_false)
encflg = 0;
else {
- ret = ERROR_Str(env, "Bad enc flag");
+ ret = EXCP_BADARG(env, "Bad enc flag");
goto ret;
}
if (ctx_res->ctx) {
/* It is *not* a ctx_res for the compatibility handling of non-EVP aes_ctr */
if (!EVP_CipherInit_ex(ctx_res->ctx, NULL, NULL, NULL, NULL, encflg)) {
- ret = ERROR_Str(env, "Can't initialize encflag");
+ ret = EXCP_ERROR(env, "Can't initialize encflag");
goto ret;
}
}
ret = argv[0];
} else {
- ret = ERROR_Str(env, "Bad 1:st arg");
+ ret = EXCP_BADARG(env, "Bad 1:st arg");
goto ret;
}
@@ -348,7 +353,7 @@ ERL_NIF_TERM ng_crypto_update(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
ERL_NIF_TERM ret;
if (!enif_get_resource(env, argv[0], evp_cipher_ctx_rtype, (void**)&ctx_res))
- return ERROR_Str(env, "Bad 1:st arg");
+ return EXCP_BADARG(env, "Bad 1:st arg");
get_update_args(env, ctx_res, argv[1], &ret);
@@ -363,10 +368,10 @@ ERL_NIF_TERM ng_crypto_update_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
ASSERT(argc <= 3);
if (!enif_inspect_binary(env, argv[1], &data_bin))
- return ERROR_Str(env, "expected binary as data");
+ return EXCP_BADARG(env, "expected binary as data");
if (data_bin.size > INT_MAX)
- return ERROR_Str(env, "to long data");
+ return EXCP_BADARG(env, "to long data");
/* Run long jobs on a dirty scheduler to not block the current emulator thread */
if (data_bin.size > MAX_BYTES_TO_NIF) {
@@ -407,10 +412,10 @@ ERL_NIF_TERM ng_crypto_one_shot_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM
ASSERT(argc == 5);
if (!enif_inspect_binary(env, argv[3], &data_bin))
- return ERROR_Str(env, "expected binary as data");
+ return EXCP_BADARG(env, "expected binary as data");
if (data_bin.size > INT_MAX)
- return ERROR_Str(env, "to long data");
+ return EXCP_BADARG(env, "to long data");
/* Run long jobs on a dirty scheduler to not block the current emulator thread */
if (data_bin.size > MAX_BYTES_TO_NIF) {
diff --git a/lib/crypto/c_src/atoms.c b/lib/crypto/c_src/atoms.c
index 798c26c9bb..114e3c1985 100644
--- a/lib/crypto/c_src/atoms.c
+++ b/lib/crypto/c_src/atoms.c
@@ -33,6 +33,7 @@ ERL_NIF_TERM atom_undefined;
ERL_NIF_TERM atom_ok;
ERL_NIF_TERM atom_none;
ERL_NIF_TERM atom_notsup;
+ERL_NIF_TERM atom_badarg;
ERL_NIF_TERM atom_digest;
#ifdef FIPS_SUPPORT
ERL_NIF_TERM atom_enabled;
@@ -150,6 +151,7 @@ int init_atoms(ErlNifEnv *env, const ERL_NIF_TERM fips_mode, const ERL_NIF_TERM
atom_ok = enif_make_atom(env,"ok");
atom_none = enif_make_atom(env,"none");
atom_notsup = enif_make_atom(env,"notsup");
+ atom_badarg = enif_make_atom(env,"badarg");
atom_digest = enif_make_atom(env,"digest");
atom_type = enif_make_atom(env,"type");
diff --git a/lib/crypto/c_src/atoms.h b/lib/crypto/c_src/atoms.h
index f8e9211459..fc46d838aa 100644
--- a/lib/crypto/c_src/atoms.h
+++ b/lib/crypto/c_src/atoms.h
@@ -37,6 +37,7 @@ extern ERL_NIF_TERM atom_undefined;
extern ERL_NIF_TERM atom_ok;
extern ERL_NIF_TERM atom_none;
extern ERL_NIF_TERM atom_notsup;
+extern ERL_NIF_TERM atom_badarg;
extern ERL_NIF_TERM atom_digest;
#ifdef FIPS_SUPPORT
extern ERL_NIF_TERM atom_enabled;
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index b4e2582fc6..bd04daee5e 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -538,6 +538,13 @@ poly1305(Key, Data) ->
%%%
%%%================================================================
+-define(COMPAT(CALL),
+ try CALL
+ catch
+ error:{E,_Reason} when E==notsup ; E==badarg ->
+ error(E)
+ end).
+
-spec cipher_info(Type) -> map() when Type :: block_cipher_with_iv()
| aead_cipher()
| block_cipher_without_iv().
@@ -545,7 +552,6 @@ cipher_info(Type) ->
cipher_info_nif(Type).
%%%---- Block ciphers
-
%%%----------------------------------------------------------------
-spec block_encrypt(Type::block_cipher_with_iv(), Key::key()|des3_key(), Ivec::binary(), PlainText::iodata()) -> binary();
(Type::aead_cipher(), Key::iodata(), Ivec::binary(), {AAD::binary(), PlainText::iodata()}) ->
@@ -573,13 +579,13 @@ do_block_encrypt(Type, Key, Ivec, Data) when Type =:= aes_gcm;
end;
do_block_encrypt(Type, Key, Ivec, PlainText) ->
- crypto_one_shot(Type, Key, Ivec, PlainText, true).
+ ?COMPAT(crypto_one_shot(Type, Key, Ivec, PlainText, true)).
-spec block_encrypt(Type::block_cipher_without_iv(), Key::key(), PlainText::iodata()) -> binary().
block_encrypt(Type, Key, PlainText) ->
- crypto_one_shot(Type, Key, <<>>, PlainText, true).
+ ?COMPAT(crypto_one_shot(Type, Key, <<>>, PlainText, true)).
%%%----------------------------------------------------------------
%%%----------------------------------------------------------------
@@ -599,13 +605,13 @@ do_block_decrypt(Type, Key, Ivec, {AAD, Data, Tag}) when Type =:= aes_gcm;
aead_decrypt(Type, Key, Ivec, AAD, Data, Tag);
do_block_decrypt(Type, Key, Ivec, Data) ->
- crypto_one_shot(Type, Key, Ivec, Data, false).
+ ?COMPAT(crypto_one_shot(Type, Key, Ivec, Data, false)).
-spec block_decrypt(Type::block_cipher_without_iv(), Key::key(), Data::iodata()) -> binary().
block_decrypt(Type, Key, Data) ->
- crypto_one_shot(Type, Key, <<>>, Data, false).
+ ?COMPAT(crypto_one_shot(Type, Key, <<>>, Data, false)).
%%%-------- Stream ciphers API
@@ -625,15 +631,11 @@ block_decrypt(Type, Key, Data) ->
-spec stream_init(Type, Key, IVec) -> State | no_return()
when Type :: stream_cipher_iv(),
Key :: iodata(),
- IVec :: binary(),
+ IVec ::binary(),
State :: stream_state() .
stream_init(Type, Key, IVec) when is_binary(IVec) ->
- case crypto_init(Type, Key, IVec) of
- {ok,Ref} ->
- {Type, {Ref,flg_undefined}};
- {error,_} ->
- error(badarg)
- end.
+ Ref = ?COMPAT(crypto_init(Type, Key, IVec)),
+ {Type, {Ref,flg_undefined}}.
-spec stream_init(Type, Key) -> State | no_return()
@@ -641,12 +643,8 @@ stream_init(Type, Key, IVec) when is_binary(IVec) ->
Key :: iodata(),
State :: stream_state() .
stream_init(rc4 = Type, Key) ->
- case crypto_init(Type, Key, undefined) of
- {ok,Ref} ->
- {Type, {Ref,flg_undefined}};
- {error,_} ->
- error(badarg)
- end.
+ Ref = ?COMPAT(crypto_init(Type, Key, undefined)),
+ {Type, {Ref,flg_undefined}}.
%%%---- stream_encrypt
-spec stream_encrypt(State, PlainText) -> {NewState, CipherText} | no_return()
@@ -655,7 +653,7 @@ stream_init(rc4 = Type, Key) ->
NewState :: stream_state(),
CipherText :: iodata() .
stream_encrypt(State, Data) ->
- crypto_stream_emulate(State, Data, true).
+ crypto_stream_emulate(State, Data, true).
%%%---- stream_decrypt
-spec stream_decrypt(State, CipherText) -> {NewState, PlainText} | no_return()
@@ -664,24 +662,17 @@ stream_encrypt(State, Data) ->
NewState :: stream_state(),
PlainText :: iodata() .
stream_decrypt(State, Data) ->
- crypto_stream_emulate(State, Data, false).
+ crypto_stream_emulate(State, Data, false).
%%%-------- helpers
-crypto_stream_emulate({Cipher,{Ref,flg_undefined}}, Data, EncryptFlag) when is_reference(Ref) ->
- case crypto_init(Ref, EncryptFlag) of
- {error,_} ->
- error(badarg);
- MaybeNewRef when is_reference(MaybeNewRef) ->
- crypto_stream_emulate({Cipher,MaybeNewRef}, Data, EncryptFlag)
- end;
+crypto_stream_emulate({Cipher,{Ref0,flg_undefined}}, Data, EncryptFlag) when is_reference(Ref0) ->
+ ?COMPAT(begin
+ Ref = crypto_init(Ref0, EncryptFlag),
+ {{Cipher,Ref}, crypto_update(Ref, Data)}
+ end);
crypto_stream_emulate({Cipher,Ref}, Data, _) when is_reference(Ref) ->
- case crypto_update(Ref, Data) of
- {error,_} ->
- error(badarg);
- Bin when is_binary(Bin) ->
- {{Cipher,Ref},Bin}
- end.
+ ?COMPAT({{Cipher,Ref}, crypto_update(Ref, Data)}).
%%%----------------------------------------------------------------
-spec next_iv(Type:: cbc_cipher(), Data) -> NextIVec when % Type :: cbc_cipher(), %des_cbc | des3_cbc | aes_cbc | aes_ige,
@@ -724,7 +715,7 @@ next_iv(Type, Data, _Ivec) ->
%%% Create and initialize a new state for encryption or decryption
%%%
--spec crypto_init(Cipher, Key, IV, EncryptFlag) -> {ok,State} | {error,term()}
+-spec crypto_init(Cipher, Key, IV, EncryptFlag) -> State | ng_crypto_error()
when Cipher :: stream_cipher()
| block_cipher_with_iv()
| block_cipher_without_iv(),
@@ -736,18 +727,12 @@ crypto_init(Cipher, Key, undefined, EncryptFlag) ->
crypto_init(Cipher, Key, <<>>, EncryptFlag);
crypto_init(Cipher, Key, IV, EncryptFlag) ->
- case ng_crypto_init_nif(alias(Cipher),
- iolist_to_binary(Key),
- iolist_to_binary(IV),
- EncryptFlag) of
- Ref when is_reference(Ref) ->
- {ok,Ref};
- {error,Error} ->
- {error,Error}
- end.
+ ng_crypto_init_nif(alias(Cipher),
+ iolist_to_binary(Key), iolist_to_binary(IV),
+ EncryptFlag).
--spec crypto_init(Cipher, Key, IV) -> {ok,State} | {error,term()}
+-spec crypto_init(Cipher, Key, IV) -> State | ng_crypto_error()
when Cipher :: stream_cipher()
| block_cipher_with_iv()
| block_cipher_without_iv(),
@@ -755,32 +740,23 @@ crypto_init(Cipher, Key, IV, EncryptFlag) ->
IV :: iodata() | undefined,
State :: crypto_state() .
crypto_init(Cipher, Key, undefined) ->
- crypto_init(Cipher, Key, <<>>);
-
-crypto_init(Cipher, Key, IV) when is_atom(Cipher) ->
- case ng_crypto_init_nif(alias(Cipher),
- iolist_to_binary(Key),
- iolist_to_binary(IV),
- undefined) of
- Ref when is_reference(Ref) ->
- {ok,Ref};
- {error,Error} ->
- {error,Error}
- end.
+ ng_crypto_init_nif(alias(Cipher),
+ iolist_to_binary(Key), <<>>,
+ undefined);
+crypto_init(Cipher, Key, IV) ->
+ ng_crypto_init_nif(alias(Cipher),
+ iolist_to_binary(Key), iolist_to_binary(IV),
+ undefined).
--spec crypto_init(Ref, EncryptFlag) -> crypto_state() | {error,term()}
+
+-spec crypto_init(Ref, EncryptFlag) -> crypto_state() | ng_crypto_error()
when Ref :: crypto_state(),
EncryptFlag :: boolean() .
crypto_init(Ref, EncryptFlag) when is_reference(Ref),
is_atom(EncryptFlag) ->
- case ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag) of
- {error,Error} ->
- {error,Error};
- R when is_reference(R) ->
- R
- end.
+ ng_crypto_init_nif(Ref, <<>>, <<>>, EncryptFlag).
%%%----------------------------------------------------------------
%%%
@@ -789,7 +765,7 @@ crypto_init(Ref, EncryptFlag) when is_reference(Ref),
%%% blocksize.
%%%
--spec crypto_update(State, Data) -> Result | {error,term()}
+-spec crypto_update(State, Data) -> Result | ng_crypto_error()
when State :: crypto_state(),
Data :: iodata(),
Result :: binary() .
@@ -808,7 +784,7 @@ crypto_update(State, Data0) ->
%%% The size must be an integer multiple of the crypto's blocksize.
%%%
--spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) -> Result | {error,term()}
+-spec crypto_one_shot(Cipher, Key, IV, Data, EncryptFlag) -> Result | ng_crypto_error()
when Cipher :: stream_cipher()
| block_cipher_with_iv()
| block_cipher_without_iv(),
@@ -825,22 +801,26 @@ crypto_one_shot(Cipher, Key, IV, Data0, EncryptFlag) ->
<<>> ->
<<>>; % Known to fail on OpenSSL 0.9.8h
Data ->
- ng_crypto_one_shot_nif(Cipher, iolist_to_binary(Key), iolist_to_binary(IV), Data, EncryptFlag)
+ ng_crypto_one_shot_nif(alias(Cipher),
+ iolist_to_binary(Key), iolist_to_binary(IV), Data,
+ EncryptFlag)
end.
%%%----------------------------------------------------------------
%%% NIFs
--spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | {error,term()}
- ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | {error,term()} .
+-type ng_crypto_error() :: no_return() .
+
+-spec ng_crypto_init_nif(atom(), binary(), binary(), boolean()|undefined ) -> crypto_state() | ng_crypto_error()
+ ; (crypto_state(), <<>>, <<>>, boolean()) -> crypto_state() | ng_crypto_error().
ng_crypto_init_nif(_Cipher, _Key, _IVec, _EncryptFlg) -> ?nif_stub.
--spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | {error,term()} .
+-spec ng_crypto_update_nif(crypto_state(), binary()) -> binary() | ng_crypto_error() .
ng_crypto_update_nif(_State, _Data) -> ?nif_stub.
--spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | {error,term()}.
+-spec ng_crypto_one_shot_nif(atom(), binary(), binary(), binary(), boolean() ) -> binary() | ng_crypto_error().
ng_crypto_one_shot_nif(_Cipher, _Key, _IVec, _Data, _EncryptFlg) -> ?nif_stub.
%%%----------------------------------------------------------------
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index 14e2c4a7a7..f76076a523 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -166,31 +166,31 @@ groups() ->
compute_bug]},
{ecdh, [], [use_all_elliptic_curves, compute, generate]},
{srp, [], [generate_compute]},
- {des_cbc, [], [block, api_ng]},
- {des_cfb, [], [block, api_ng]},
- {des3_cbc,[], [block, api_ng]},
- {des_ede3,[], [block, api_ng]},
- {des3_cbf,[], [block, api_ng]},
- {des3_cfb,[], [block, api_ng]},
- {rc2_cbc,[], [block, api_ng]},
- {aes_cbc128,[], [block, api_ng, cmac]},
- {aes_cfb8,[], [block, api_ng]},
- {aes_cfb128,[], [block, api_ng]},
- {aes_cbc256,[], [block, api_ng, cmac]},
- {aes_ecb,[], [block, api_ng]},
+ {des_cbc, [], [block, api_ng, api_ng_one_shot]},
+ {des_cfb, [], [block, api_ng, api_ng_one_shot]},
+ {des3_cbc,[], [block, api_ng, api_ng_one_shot]},
+ {des_ede3,[], [block, api_ng, api_ng_one_shot]},
+ {des3_cbf,[], [block, api_ng, api_ng_one_shot]},
+ {des3_cfb,[], [block, api_ng, api_ng_one_shot]},
+ {rc2_cbc,[], [block, api_ng, api_ng_one_shot]},
+ {aes_cbc128,[], [block, api_ng, api_ng_one_shot, cmac]},
+ {aes_cfb8,[], [block, api_ng, api_ng_one_shot]},
+ {aes_cfb128,[], [block, api_ng, api_ng_one_shot]},
+ {aes_cbc256,[], [block, api_ng, api_ng_one_shot, cmac]},
+ {aes_ecb,[], [block, api_ng, api_ng_one_shot]},
{aes_ige256,[], [block]},
- {blowfish_cbc, [], [block, api_ng]},
- {blowfish_ecb, [], [block, api_ng]},
- {blowfish_cfb64, [], [block, api_ng]},
- {blowfish_ofb64,[], [block, api_ng]},
- {rc4, [], [stream, api_ng]},
- {aes_ctr, [], [stream, api_ng]},
+ {blowfish_cbc, [], [block, api_ng, api_ng_one_shot]},
+ {blowfish_ecb, [], [block, api_ng, api_ng_one_shot]},
+ {blowfish_cfb64, [], [block, api_ng, api_ng_one_shot]},
+ {blowfish_ofb64,[], [block, api_ng, api_ng_one_shot]},
+ {rc4, [], [stream, api_ng, api_ng_one_shot]},
+ {aes_ctr, [], [stream, api_ng, api_ng_one_shot]},
{aes_ccm, [], [aead]},
{aes_gcm, [], [aead]},
{chacha20_poly1305, [], [aead]},
- {chacha20, [], [stream, api_ng]},
+ {chacha20, [], [stream, api_ng, api_ng_one_shot]},
{poly1305, [], [poly1305]},
- {aes_cbc, [], [block, api_ng]},
+ {aes_cbc, [], [block, api_ng, api_ng_one_shot]},
{no_aes_cfb8,[], [no_support, no_block]},
{no_aes_cfb128,[], [no_support, no_block]},
{no_md4, [], [no_support, no_hash]},
@@ -457,8 +457,8 @@ api_ng_cipher_increment({Type, Key, IV, PlainTexts}=_X) ->
api_ng_cipher_increment({Type, Key, IV, PlainText0, ExpectedEncText}=_X) ->
ct:log("~p",[_X]),
PlainTexts = iolistify(PlainText0),
- {ok,RefEnc} = crypto:crypto_init(Type, Key, IV, true),
- {ok,RefDec} = crypto:crypto_init(Type, Key, IV, false),
+ RefEnc = crypto:crypto_init(Type, Key, IV, true),
+ RefDec = crypto:crypto_init(Type, Key, IV, false),
EncTexts = api_ng_cipher_increment_loop(RefEnc, PlainTexts),
Enc = iolist_to_binary(EncTexts),
case ExpectedEncText of
@@ -480,16 +480,56 @@ api_ng_cipher_increment({Type, Key, IV, PlainText0, ExpectedEncText}=_X) ->
api_ng_cipher_increment_loop(Ref, InTexts) ->
lists:map(fun(Txt) ->
- case crypto:crypto_update(Ref, Txt) of
+ try crypto:crypto_update(Ref, Txt)
+ of
Bin when is_binary(Bin) ->
- Bin;
- {error,Error} ->
+ Bin
+ catch
+ error:Error ->
ct:pal("Txt = ~p",[Txt]),
ct:fail("~p",[Error])
end
end, InTexts).
%%--------------------------------------------------------------------
+api_ng_one_shot() ->
+ [{doc, "Test new api"}].
+
+api_ng_one_shot(Config) when is_list(Config) ->
+ Blocks = lazy_eval(proplists:get_value(block, Config, [])),
+ Streams = lazy_eval(proplists:get_value(stream, Config, [])),
+ lists:foreach(fun do_api_ng_one_shot/1, Blocks++Streams).
+
+do_api_ng_one_shot({Type, Key, PlainTexts}=_X) ->
+ ct:log("~p",[_X]),
+ do_api_ng_one_shot({Type, Key, <<>>, PlainTexts});
+
+do_api_ng_one_shot({Type, Key, IV, PlainTexts}=_X) ->
+ ct:log("~p",[_X]),
+ do_api_ng_one_shot({Type, Key, IV, PlainTexts, undefined});
+
+do_api_ng_one_shot({Type, Key, IV, PlainText0, ExpectedEncText}=_X) ->
+ ct:log("~p",[_X]),
+ PlainText = iolist_to_binary(PlainText0),
+ EncTxt = crypto:crypto_one_shot(Type, Key, IV, PlainText, true),
+ case ExpectedEncText of
+ undefined ->
+ ok;
+ EncTxt ->
+ ok;
+ OtherEnc ->
+ ct:log("In: ~p~nOut: ~p",[_X,OtherEnc]),
+ ct:fail("api_ng_one_shot (encode)",[])
+ end,
+ case crypto:crypto_one_shot(Type, Key, IV, EncTxt, false) of
+ PlainText ->
+ ok;
+ OtherPT ->
+ ct:log("In: ~p~nOut: ~p",[_X,OtherPT]),
+ ct:fail("api_ng_one_shot (decode)",[])
+ end.
+
+%%--------------------------------------------------------------------
no_aead() ->
[{doc, "Test disabled aead ciphers"}].
no_aead(Config) when is_list(Config) ->