From b950289736287275307f1b5579d82c3bd2271db9 Mon Sep 17 00:00:00 2001 From: Lars Thorsen Date: Thu, 22 Jun 2017 13:13:09 +0200 Subject: [crypto] Add support for loading an alternative Engine Add support to plug in alternative implementations for some or all of the cryptographic operations supported by the OpenSSL Engine API. When configured appropriately, OpenSSL calls the engine's implementation of these operations instead of its own. --- lib/crypto/doc/src/Makefile | 18 ++-- lib/crypto/doc/src/crypto.xml | 165 ++++++++++++++++++++++++++++++++----- lib/crypto/doc/src/engine_load.xml | 110 +++++++++++++++++++++++++ lib/crypto/doc/src/usersguide.xml | 6 +- 4 files changed, 264 insertions(+), 35 deletions(-) create mode 100644 lib/crypto/doc/src/engine_load.xml (limited to 'lib/crypto/doc') diff --git a/lib/crypto/doc/src/Makefile b/lib/crypto/doc/src/Makefile index 9c503b8fe0..937bb1419f 100644 --- a/lib/crypto/doc/src/Makefile +++ b/lib/crypto/doc/src/Makefile @@ -9,11 +9,11 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -# +# # The Initial Developer of the Original Code is Ericsson Utvecklings AB. # Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings # AB. All Rights Reserved.'' -# +# # $Id$ # include $(ERL_TOP)/make/target.mk @@ -39,12 +39,12 @@ XML_REF3_FILES = crypto.xml XML_REF6_FILES = crypto_app.xml XML_PART_FILES = release_notes.xml usersguide.xml -XML_CHAPTER_FILES = notes.xml licenses.xml fips.xml +XML_CHAPTER_FILES = notes.xml licenses.xml fips.xml engine_load.xml BOOK_FILES = book.xml XML_FILES = $(BOOK_FILES) $(XML_APPLICATION_FILES) $(XML_REF3_FILES) $(XML_REF6_FILES) \ - $(XML_PART_FILES) $(XML_CHAPTER_FILES) + $(XML_PART_FILES) $(XML_CHAPTER_FILES) GIF_FILES = @@ -63,9 +63,9 @@ HTML_REF_MAN_FILE = $(HTMLDIR)/index.html TOP_PDF_FILE = $(PDFDIR)/$(APPLICATION)-$(VSN).pdf # ---------------------------------------------------- -# FLAGS +# FLAGS # ---------------------------------------------------- -XML_FLAGS += +XML_FLAGS += # ---------------------------------------------------- # Targets @@ -73,7 +73,6 @@ XML_FLAGS += $(HTMLDIR)/%.gif: %.gif $(INSTALL_DATA) $< $@ - docs: pdf html man $(TOP_PDF_FILE): $(XML_FILES) @@ -86,7 +85,7 @@ man: $(MAN3_FILES) $(MAN6_FILES) gifs: $(GIF_FILES:%=$(HTMLDIR)/%) -debug opt valgrind: +debug opt valgrind: clean clean_docs clean_tex: rm -rf $(HTMLDIR)/* @@ -97,7 +96,7 @@ clean clean_docs clean_tex: # ---------------------------------------------------- # Release Target -# ---------------------------------------------------- +# ---------------------------------------------------- include $(ERL_TOP)/make/otp_release_targets.mk release_docs_spec: docs @@ -114,4 +113,3 @@ release_docs_spec: docs release_spec: - diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml index 5b2c46a004..c0f85945a7 100644 --- a/lib/crypto/doc/src/crypto.xml +++ b/lib/crypto/doc/src/crypto.xml @@ -11,7 +11,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software @@ -19,7 +19,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - crypto @@ -68,11 +67,11 @@
DATA TYPES - - key_value() = integer() | binary() + + key_value() = integer() | binary()

Always binary() when used as return value

- rsa_public() = [key_value()] = [E, N] + rsa_public() = [key_value()] = [E, N]

Where E is the public exponent and N is public modulus.

rsa_private() = [key_value()] = [E, N, D] | [E, N, D, P1, P2, E1, E2, C] @@ -85,7 +84,7 @@ dss_public() = [key_value()] = [P, Q, G, Y]

Where P, Q and G are the dss parameters and Y is the public key.

- dss_private() = [key_value()] = [P, Q, G, X] + dss_private() = [key_value()] = [P, Q, G, X]

Where P, Q and G are the dss parameters and X is the private key.

srp_public() = key_value() @@ -109,15 +108,16 @@ ecdh_private() = key_value() - ecdh_params() = ec_named_curve() | ec_explicit_curve() + ecdh_params() = ec_named_curve() | ec_explicit_curve() ec_explicit_curve() = - {ec_field(), Prime :: key_value(), Point :: key_value(), Order :: integer(), CoFactor :: none | integer()} + {ec_field(), Prime :: key_value(), Point :: key_value(), Order :: integer(), + CoFactor :: none | integer()} ec_field() = {prime_field, Prime :: integer()} | {characteristic_two_field, M :: integer(), Basis :: ec_basis()} - ec_basis() = {tpbasis, K :: non_neg_integer()} | + ec_basis() = {tpbasis, K :: non_neg_integer()} | {ppbasis, K1 :: non_neg_integer(), K2 :: non_neg_integer(), K3 :: non_neg_integer()} | onbasis @@ -138,14 +138,14 @@ stream_cipher() = rc4 | aes_ctr - block_cipher() = aes_cbc | aes_cfb8 | aes_cfb128 | aes_ige256 | blowfish_cbc | + block_cipher() = aes_cbc | aes_cfb8 | aes_cfb128 | aes_ige256 | blowfish_cbc | blowfish_cfb64 | des_cbc | des_cfb | des3_cbc | des3_cfb | des_ede3 | rc2_cbc - aead_cipher() = aes_gcm | chacha20_poly1305 + aead_cipher() = aes_gcm | chacha20_poly1305 - stream_key() = aes_key() | rc4_key() + stream_key() = aes_key() | rc4_key() - block_key() = aes_key() | blowfish_key() | des_key()| des3_key() + block_key() = aes_key() | blowfish_key() | des_key()| des3_key() aes_key() = iodata()

Key length is 128, 192 or 256 bits

@@ -174,13 +174,17 @@ Note that both md4 and md5 are recommended only for compatibility with existing applications.

cipher_algorithms() = aes_cbc | aes_cfb8 | aes_cfb128 | aes_ctr | aes_gcm | - aes_ige256 | blowfish_cbc | blowfish_cfb64 | chacha20_poly1305 | des_cbc | des_cfb | - des3_cbc | des3_cfb | des_ede3 | rc2_cbc | rc4 - mac_algorithms() = hmac | cmac - public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh | ec_gf2m + aes_ige256 | blowfish_cbc | blowfish_cfb64 | chacha20_poly1305 | des_cbc | + des_cfb | des3_cbc | des3_cfb | des_ede3 | rc2_cbc | rc4
+ mac_algorithms() = hmac | cmac + public_key_algorithms() = rsa |dss | ecdsa | dh | ecdh | ec_gf2m

Note that ec_gf2m is not strictly a public key algorithm, but a restriction on what curves are supported with ecdsa and ecdh.

+ engine_method_type() = engine_method_rsa | engine_method_dsa | engine_method_dh | + engine_method_rand | engine_method_ecdh | engine_method_ecdsa | + engine_method_ciphers | engine_method_digests | engine_method_store | + engine_method_pkey_meths | engine_method_pkey_asn1_meths
@@ -261,13 +265,13 @@ is not supported by the underlying OpenSSL implementation.

- + bytes_to_integer(Bin) -> Integer Convert binary representation, of an integer, to an Erlang integer. Bin = binary() - as returned by crypto functions - + Integer = integer() @@ -439,7 +443,7 @@

Updates the HMAC represented by Context using the given Data. Context - must have been generated using an HMAC init function (such as + must have been generated using an HMAC init function (such as hmac_init). Data can be any length. NewContext must be passed into the next call to hmac_update or to one of the functions hmac_final and @@ -594,7 +598,7 @@

- + private_encrypt(Type, PlainText, PrivateKey, Padding) -> CipherText Encrypts PlainText using the private Key. @@ -905,6 +909,124 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ + + + engine_get_all_methods() -> Result + Return list of all possible engine methods + + Result = [EngineMethod::atom()] + + +

+ Returns a list of all possible engine methods. +

+

+ May throw exception notsup in case there is + no engine support in the underlying OpenSSL implementation. +

+

+ See also the chapter Engine Load + in the User's Guide. +

+
+
+ + + engine_load(EngineId, PreCmds, PostCmds) -> Result + Dynamical load an encryption engine + + EngineId = unicode:chardata() + PreCmds, PostCmds = [{unicode:chardata(), unicode:chardata()}] + Result = {ok, Engine::term()} | {error, Reason::term()} + + +

+ Loads the OpenSSL engine given by EngineId if it is available and then returns ok and + an engine handle. This function is the same as calling engine_load/4 with + EngineMethods set to a list of all the possible methods. An error tuple is + returned if the engine can't be loaded. +

+

+ The function throws a badarg if the parameters are in wrong format. + It may also throw the exception notsup in case there is + no engine support in the underlying OpenSSL implementation. +

+

+ See also the chapter Engine Load + in the User's Guide. +

+
+
+ + + engine_load(EngineId, PreCmds, PostCmds, EngineMethods) -> Result + Dynamical load an encryption engine + + EngineId = unicode:chardata() + PreCmds, PostCmds = [{unicode:chardata(), unicode:chardata()}] + EngineMethods = [engine_method_type()] + Result = {ok, Engine::term()} | {error, Reason::term()} + + +

+ Loads the OpenSSL engine given by EngineId if it is available and then returns ok and + an engine handle. An error tuple is returned if the engine can't be loaded. +

+

+ The function throws a badarg if the parameters are in wrong format. + It may also throw the exception notsup in case there is + no engine support in the underlying OpenSSL implementation. +

+

+ See also the chapter Engine Load + in the User's Guide. +

+
+
+ + + engine_unload(Engine) -> Result + Dynamical load an encryption engine + + Engine = term() + Result = ok | {error, Reason::term()} + + +

+ Unloads the OpenSSL engine given by EngineId. + An error tuple is returned if the engine can't be unloaded. +

+

+ The function throws a badarg if the parameter is in wrong format. + It may also throw the exception notsup in case there is + no engine support in the underlying OpenSSL implementation. +

+

+ See also the chapter Engine Load + in the User's Guide. +

+
+
+ + + engine_list() -> Result + List the known engine ids + + Result = [EngineId::unicode:chardata()] + + +

List the id's of all engines in OpenSSL's internal list.

+

+ It may also throw the exception notsup in case there is + no engine support in the underlying OpenSSL implementation. +

+

+ See also the chapter Engine Load + in the User's Guide. +

+
+
+ @@ -979,4 +1101,3 @@ _FloatValue = rand:uniform(). % [0.0; 1.0[ - diff --git a/lib/crypto/doc/src/engine_load.xml b/lib/crypto/doc/src/engine_load.xml new file mode 100644 index 0000000000..e5c3f5d561 --- /dev/null +++ b/lib/crypto/doc/src/engine_load.xml @@ -0,0 +1,110 @@ + + + + +
+ + 20172017 + Ericsson AB. All Rights Reserved. + + + The contents of this file are subject to the Erlang Public License, + Version 1.1, (the "License"); you may not use this file except in + compliance with the License. You should have received a copy of the + Erlang Public License along with this software. If not, it can be + retrieved online at http://www.erlang.org/. + + Software distributed under the License is distributed on an "AS IS" + basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + the License for the specific language governing rights and limitations + under the License. + + Engine Load + Lars Thorsén + 2017-08-22 + engine_load.xml +
+

+ + This chapter describes the support for loading encryption engines in the crypto application. +

+ +
+ Background +

+ OpenSSL exposes an Engine API, which makes it possible to plug in alternative + implementations for some or all of the cryptographic operations implemented by OpenSSL. + When configured appropriately, OpenSSL calls the engine's implementation of these + operations instead of its own. +

+

+ Typically, OpenSSL engines provide a hardware implementation of specific cryptographic + operations. The hardware implementation usually offers improved performance over its + software-based counterpart, which is known as cryptographic acceleration. +

+
+ +
+ Use Cases +
+ Dynamically load an engine from default directory +

+ If the engine is located in the OpenSSL/LibreSSL installation engines directory. +

+ +1> {ok, Engine} = crypto:engine_load(<<"otp_test_engine">>, [], []). + {ok, #Ref} + +

The file name requirement on the engine dynamic library can differ between SSL versions.

+
+
+ +
+ Load an engine with the dynamic engine +

+ Load an engine with the help of the dynamic engine by giving the path to the library. +

+ + 2> {ok, Engine} = crypto:engine_load(<<"dynamic">>, + [{<<"SO_PATH">>, + <<"/some/path/otp_test_engine.so">>}, + {<<"ID">>, <<"MD5">>}, + <<"LOAD">>], + []). + {ok, #Ref} + +

The dynamic engine is not supported in LibreSSL from version 2.2.1

+
+
+ +
+ Load an engine and replace some methods +

+ Load an engine with the help of the dynamic engine and just + replace some engine methods. +

+ + 3> Methods = crypto:engine_get_all_methods() -- [engine_method_dh,engine_method_rand, +engine_method_ciphers,engine_method_digests, engine_method_store, +engine_method_pkey_meths, engine_method_pkey_asn1_meths]. +[engine_method_rsa,engine_method_dsa, + engine_method_ecdh,engine_method_ecdsa] + 4> {ok, Engine} = crypto:engine_load(<<"dynamic">>, + [{<<"SO_PATH">>, + <<"/some/path/otp_test_engine.so">>}, + {<<"ID">>, <<"MD5">>}, + <<"LOAD">>], + [], + Methods). + {ok, #Ref} +
+ +
+ List all engines currently loaded + + 5> crypto:engine_list(). +[<<"dynamic">>, <<"MD5">>] +
+ +
+
diff --git a/lib/crypto/doc/src/usersguide.xml b/lib/crypto/doc/src/usersguide.xml index 7971aefff4..f637a1db79 100644 --- a/lib/crypto/doc/src/usersguide.xml +++ b/lib/crypto/doc/src/usersguide.xml @@ -11,7 +11,7 @@ Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software @@ -19,7 +19,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. - + Crypto User's Guide @@ -48,5 +48,5 @@ + - -- cgit v1.2.3