diff options
author | Hans Nilsson <[email protected]> | 2019-03-08 10:42:25 +0100 |
---|---|---|
committer | Hans Nilsson <[email protected]> | 2019-03-19 12:45:55 +0100 |
commit | 3f8f8054254cee6bf401e1e83662e05029bde750 (patch) | |
tree | c3aeacea923d9d930850b228b15f4472e6067453 /lib | |
parent | 3a74629664f3d7f6ae7483954130dca7f9794c10 (diff) | |
download | otp-3f8f8054254cee6bf401e1e83662e05029bde750.tar.gz otp-3f8f8054254cee6bf401e1e83662e05029bde750.tar.bz2 otp-3f8f8054254cee6bf401e1e83662e05029bde750.zip |
crypto: Exceptions as error return in api_ng
Diffstat (limited to 'lib')
-rw-r--r-- | lib/crypto/c_src/api_ng.c | 69 | ||||
-rw-r--r-- | lib/crypto/c_src/atoms.c | 2 | ||||
-rw-r--r-- | lib/crypto/c_src/atoms.h | 1 | ||||
-rw-r--r-- | lib/crypto/src/crypto.erl | 120 | ||||
-rw-r--r-- | lib/crypto/test/crypto_SUITE.erl | 90 |
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) -> |