From 05fdb8d355e6f018627084410cefeb3202cd7f98 Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Fri, 18 Dec 2015 17:09:45 +0100 Subject: [PATCH] Document the new EVP_CIPHER and EVP_CIPHER_CTX functionality Reviewed-by: Rich Salz --- doc/crypto/EVP_CIPHER_meth_new.pod | 253 +++++++++++++++++++++++++++++ doc/crypto/EVP_EncryptInit.pod | 98 ++++++----- 2 files changed, 311 insertions(+), 40 deletions(-) create mode 100644 doc/crypto/EVP_CIPHER_meth_new.pod diff --git a/doc/crypto/EVP_CIPHER_meth_new.pod b/doc/crypto/EVP_CIPHER_meth_new.pod new file mode 100644 index 0000000000..75b2d61415 --- /dev/null +++ b/doc/crypto/EVP_CIPHER_meth_new.pod @@ -0,0 +1,253 @@ +=pod + +=head1 NAME + +EVP_CIPHER_meth_new, EVP_CIPHER_meth_dup, EVP_CIPHER_meth_free, +EVP_CIPHER_meth_set_iv_length, EVP_CIPHER_meth_set_flags, +EVP_CIPHER_meth_set_impl_ctx_size, EVP_CIPHER_meth_set_init, +EVP_CIPHER_meth_set_do_cipher, EVP_CIPHER_meth_set_cleanup, +EVP_CIPHER_meth_set_set_asn1_params, EVP_CIPHER_meth_set_get_asn1_params, +EVP_CIPHER_meth_set_ctrl, EVP_CIPHER_meth_get_init, +EVP_CIPHER_meth_get_do_cipher, EVP_CIPHER_meth_get_cleanup, +EVP_CIPHER_meth_get_set_asn1_params, EVP_CIPHER_meth_get_get_asn1_params, +EVP_CIPHER_meth_get_ctrl - Routines to build up EVP_CIPHER methods + +=head1 SYNOPSIS + + #include + + EVP_CIPHER *EVP_CIPHER_meth_new(int cipher_type, int block_size, int key_len); + EVP_CIPHER *EVP_CIPHER_meth_dup(const EVP_CIPHER *cipher); + void EVP_CIPHER_meth_free(EVP_CIPHER *cipher); + + int EVP_CIPHER_meth_set_iv_length(EVP_CIPHER *cipher, int iv_len); + int EVP_CIPHER_meth_set_flags(EVP_CIPHER *cipher, unsigned long flags); + int EVP_CIPHER_meth_set_impl_ctx_size(EVP_CIPHER *cipher, int ctx_size); + int EVP_CIPHER_meth_set_init(EVP_CIPHER *cipher, + int (*init) (EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, + int enc)); + int EVP_CIPHER_meth_set_do_cipher(EVP_CIPHER *cipher, + int (*do_cipher) (EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, + size_t inl)); + int EVP_CIPHER_meth_set_cleanup(EVP_CIPHER *cipher, + int (*cleanup) (EVP_CIPHER_CTX *)); + int EVP_CIPHER_meth_set_set_asn1_params(EVP_CIPHER *cipher, + int (*set_asn1_parameters) (EVP_CIPHER_CTX *, + ASN1_TYPE *)); + int EVP_CIPHER_meth_set_get_asn1_params(EVP_CIPHER *cipher, + int (*get_asn1_parameters) (EVP_CIPHER_CTX *, + ASN1_TYPE *)); + int EVP_CIPHER_meth_set_ctrl(EVP_CIPHER *cipher, + int (*ctrl) (EVP_CIPHER_CTX *, int type, + int arg, void *ptr)); + + int (*EVP_CIPHER_meth_get_init(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, + int enc); + int (*EVP_CIPHER_meth_get_do_cipher(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *ctx, + unsigned char *out, + const unsigned char *in, + size_t inl); + int (*EVP_CIPHER_meth_get_cleanup(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *); + int (*EVP_CIPHER_meth_get_set_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + ASN1_TYPE *); + int (*EVP_CIPHER_meth_get_get_asn1_params(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + ASN1_TYPE *); + int (*EVP_CIPHER_meth_get_ctrl(const EVP_CIPHER *cipher))(EVP_CIPHER_CTX *, + int type, int arg, + void *ptr); + +=head1 DESCRIPTION + +The B type is a structure for symmetric cipher method +implementation. + +EVP_CIPHER_meth_new() creates a new B structure. + +EVP_CIPHER_meth_dup() creates a copy of B. + +EVP_CIPHER_meth_free() destroys a B structure. + +EVP_CIPHER_meth_iv_length() sets the length of the IV. +This is only needed when the implemented cipher mode requires it. + +EVP_CIPHER_meth_set_flags() sets the flags to describe optional +behaviours in the particular B. +With the exception of cipher modes, of which only one may be present, +several flags can be or'd together. +The available flags are: + +=over 4 + +=over 4 + +=item The cipher modes: + +=over 4 + +=item EVP_CIPH_STREAM_CIPHER + +=item EVP_CIPH_ECB_MODE + +=item EVP_CIPH_CBC_MODE + +=item EVP_CIPH_CFB_MODE + +=item EVP_CIPH_OFB_MODE + +=item EVP_CIPH_CTR_MODE + +=item EVP_CIPH_GCM_MODE + +=item EVP_CIPH_CCM_MODE + +=item EVP_CIPH_XTS_MODE + +=item EVP_CIPH_WRAP_MODE + +=item EVP_CIPH_OCB_MODE + +=back + +=item EVP_CIPH_VARIABLE_LENGTH + +This cipher is of variable length. + +=item EVP_CIPH_CUSTOM_IV + +Storing and initialising the IV is left entirely to the +implementation. + +=item EVP_CIPH_ALWAYS_CALL_INIT + +Set this if the implementation's init() function should be called even +if B is B. + +=item EVP_CIPH_CTRL_INIT + +Set this to have the implementation's ctrl() function called with +command code B early in its setup. + +=item EVP_CIPH_CUSTOM_KEY_LENGTH + +Checking and setting the key length after creating the B +is left to the implementation. +Whenever someone uses EVP_CIPHER_CTX_set_key_length() on a +B with this flag set, the implementation's ctrl() function +will be called with the control code B and +the key length in B. + +=item EVP_CIPH_NO_PADDING + +Don't use standard block padding. + +=item EVP_CIPH_RAND_KEY + +Making a key with random content is left to the implementation. +This is done by calling the implementation's ctrl() function with the +control code B and the pointer to the key memory +storage in B. + +=item EVP_CIPH_CUSTOM_COPY + +Set this to have the implementation's ctrl() function called with +command code B at the end of EVP_CIPHER_CTX_copy(). +The intended use is for further things to deal with after the +implementation specific data block has been copied. +The destination B is passed to the control with the +B parameter. +The implementation specific data block is reached with +EVP_CIPHER_CTX_cipher_data(). + +=item EVP_CIPH_FLAG_DEFAULT_ASN1 + +Use the default EVP routines to pass IV to and from ASN.1. + +=item EVP_CIPH_FLAG_LENGTH_BITS + +Signals that the length of the input buffer for encryption / +decryption is to be understood as the number of bits bits instead of +bytes for this implementation. +This is only useful for CFB1 ciphers. + +=begin comment +The FIPS flags seem to be unused, so I'm hiding them until I get an +explanation or they get removed. /RL + +=item EVP_CIPH_FLAG_FIPS + +=item EVP_CIPH_FLAG_NON_FIPS_ALLOW + +=end comment + +=item EVP_CIPH_FLAG_CUSTOM_CIPHER + +This indicates that the implementation takes care of everything, +including padding, buffering and finalization. +The EVP routines will simply give them control and do nothing more. + +=item EVP_CIPH_FLAG_AEAD_CIPHER + +This indicates that this is a AEAD cipher implementation. + +=item EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK + +=begin comment + +I could use some help explaining this one! + +=end comment + +=back + +=back + +EVP_CIPHER_meth_set_init() sets the cipher init function for +B. +The cipher init function is called by EVP_CipherInit(), +EVP_CipherInit_ex(), EVP_EncryptInit(), EVP_EncryptInit_ex(), +EVP_DecryptInit(), EVP_DecryptInit_ex(). + +EVP_CIPHER_meth_set_do_cipher() sets the cipher function for +B. +The cipher function is called by EVP_CipherUpdate(), +EVP_EncryptUpdate(), EVP_DecryptUpdate(), EVP_CipherFinal(), +EVP_EncryptFinal(), EVP_EncryptFinal_ex(), EVP_DecryptFinal() and +EVP_DecryptFinal_ex(). + +EVP_CIPHER_meth_set_cleanup() sets the function for B to do +extra cleanup before the method's privata data structure is cleaned +out and freed. +Note that the cleanup function is passed a B, the +private data structure is then available with +EVP_CIPHER_CTX_cipher_data(). +This cleanup function is called by EVP_CIPHER_CTX_reset() and +EVP_CIPHER_CTX_free(). + +EVP_CIPHER_meth_set_ctrl() sets the control function for B. + + +EVP_CIPHER_meth_get_input_blocksize(), EVP_CIPHER_meth_get_result_size(), +EVP_CIPHER_meth_get_app_datasize(), EVP_CIPHER_meth_get_flags(), +EVP_CIPHER_meth_get_init(), EVP_CIPHER_meth_get_update(), +EVP_CIPHER_meth_get_final(), EVP_CIPHER_meth_get_copy(), +EVP_CIPHER_meth_get_cleanup() and EVP_CIPHER_meth_get_ctrl() are all used +to retrieve the method data given with the EVP_CIPHER_meth_set_*() +functions above. + +=head1 SEE ALSO + +L + +=head1 HISTORY + +The B structure was openly available in OpenSSL before version +1.1. +The functions described here were added in OpenSSL version 1.1. + +=cut diff --git a/doc/crypto/EVP_EncryptInit.pod b/doc/crypto/EVP_EncryptInit.pod index 8f3216b95d..f064d672a7 100644 --- a/doc/crypto/EVP_EncryptInit.pod +++ b/doc/crypto/EVP_EncryptInit.pod @@ -2,11 +2,11 @@ =head1 NAME -EVP_CIPHER_CTX_init, EVP_EncryptInit_ex, EVP_EncryptUpdate, -EVP_EncryptFinal_ex, EVP_DecryptInit_ex, EVP_DecryptUpdate, -EVP_DecryptFinal_ex, EVP_CipherInit_ex, EVP_CipherUpdate, -EVP_CipherFinal_ex, EVP_CIPHER_CTX_set_key_length, -EVP_CIPHER_CTX_ctrl, EVP_CIPHER_CTX_cleanup, EVP_EncryptInit, +EVP_CIPHER_CTX_new, EVP_CIPHER_CTX_reset, EVP_CIPHER_CTX_free, +EVP_EncryptInit_ex, EVP_EncryptUpdate, EVP_EncryptFinal_ex, +EVP_DecryptInit_ex, EVP_DecryptUpdate, EVP_DecryptFinal_ex, +EVP_CipherInit_ex, EVP_CipherUpdate, EVP_CipherFinal_ex, +EVP_CIPHER_CTX_set_key_length, EVP_CIPHER_CTX_ctrl, EVP_EncryptInit, EVP_EncryptFinal, EVP_DecryptInit, EVP_DecryptFinal, EVP_CipherInit, EVP_CipherFinal, EVP_get_cipherbyname, EVP_get_cipherbynid, EVP_get_cipherbyobj, EVP_CIPHER_nid, @@ -35,7 +35,9 @@ EVP_aes_128_ccm, EVP_aes_192_ccm, EVP_aes_256_ccm - EVP cipher routines #include - void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a); + EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); + int EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx); + void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, ENGINE *impl, unsigned char *key, unsigned char *iv); @@ -76,7 +78,6 @@ EVP_aes_128_ccm, EVP_aes_192_ccm, EVP_aes_256_ccm - EVP cipher routines int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding); int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); - int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); const EVP_CIPHER *EVP_get_cipherbyname(const char *name); #define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) @@ -90,16 +91,18 @@ EVP_aes_128_ccm, EVP_aes_192_ccm, EVP_aes_256_ccm - EVP cipher routines #define EVP_CIPHER_mode(e) ((e)->flags) & EVP_CIPH_MODE) int EVP_CIPHER_type(const EVP_CIPHER *ctx); - #define EVP_CIPHER_CTX_cipher(e) ((e)->cipher) - #define EVP_CIPHER_CTX_nid(e) ((e)->cipher->nid) - #define EVP_CIPHER_CTX_block_size(e) ((e)->cipher->block_size) - #define EVP_CIPHER_CTX_key_length(e) ((e)->key_len) - #define EVP_CIPHER_CTX_iv_length(e) ((e)->cipher->iv_len) - #define EVP_CIPHER_CTX_get_app_data(e) ((e)->app_data) - #define EVP_CIPHER_CTX_set_app_data(e,d) ((e)->app_data=(char *)(d)) - #define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) - #define EVP_CIPHER_CTX_flags(e) ((e)->cipher->flags) - #define EVP_CIPHER_CTX_mode(e) ((e)->cipher->flags & EVP_CIPH_MODE) + const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx); + int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); + int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); + int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); + int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); + void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); + void EVP_CIPHER_CTX_set_app_data(const EVP_CIPHER_CTX *ctx, void *data); + int EVP_CIPHER_CTX_type(const EVP_CIPHER_CTX *ctx); + void EVP_CIPHER_CTX_set_flags(const EVP_CIPHER_CTX *ctx, int flags); + void EVP_CIPHER_CTX_clear_flags(const EVP_CIPHER_CTX *ctx, int flags); + int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags); + int EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx); int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); @@ -109,10 +112,16 @@ EVP_aes_128_ccm, EVP_aes_192_ccm, EVP_aes_256_ccm - EVP cipher routines The EVP cipher routines are a high level interface to certain symmetric ciphers. -EVP_CIPHER_CTX_init() initializes cipher contex B. +EVP_CIPHER_CTX_new() creates a cipher context. + +EVP_CIPHER_CTX_free() clears all information from a cipher context +and free up any allocated memory associate with it, including B +itself. This function should be called after all operations using a +cipher are complete so sensitive information does not remain in +memory. EVP_EncryptInit_ex() sets up cipher context B for encryption -with cipher B from ENGINE B. B must be initialized +with cipher B from ENGINE B. B must be created before calling this function. B is normally supplied by a function such as EVP_aes_256_cbc(). If B is NULL then the default implementation is used. B is the symmetric key to use @@ -159,10 +168,11 @@ performed depends on the value of the B parameter. It should be set to 1 for encryption, 0 for decryption and -1 to leave the value unchanged (the actual value of 'enc' being supplied in a previous call). -EVP_CIPHER_CTX_cleanup() clears all information from a cipher context -and free up any allocated memory associate with it. It should be called -after all operations using a cipher are complete so sensitive information -does not remain in memory. +EVP_CIPHER_CTX_reset() clears all information from a cipher context +and free up any allocated memory associate with it, except the B +itself. This function should be called anytime B is to be reused +for another EVP_CipherInit() / EVP_CipherUpdate() / EVP_CipherFinal() +series of calls. EVP_EncryptInit(), EVP_DecryptInit() and EVP_CipherInit() behave in a similar way to EVP_EncryptInit_ex(), EVP_DecryptInit_ex() and @@ -250,6 +260,9 @@ and set. =head1 RETURN VALUES +EVP_CIPHER_CTX_new() returns a pointer to a newly created +B for success and B for failure. + EVP_EncryptInit_ex(), EVP_EncryptUpdate() and EVP_EncryptFinal_ex() return 1 for success and 0 for failure. @@ -259,7 +272,7 @@ EVP_DecryptFinal_ex() returns 0 if the decrypt failed or 1 for success. EVP_CipherInit_ex() and EVP_CipherUpdate() return 1 for success and 0 for failure. EVP_CipherFinal_ex() returns 0 for a decryption failure or 1 for success. -EVP_CIPHER_CTX_cleanup() returns 1 for success and 0 for failure. +EVP_CIPHER_CTX_reset() returns 1 for success and 0 for failure. EVP_get_cipherbyname(), EVP_get_cipherbynid() and EVP_get_cipherbyobj() return an B structure or NULL on error. @@ -511,7 +524,7 @@ for certain common S/MIME ciphers (RC2, DES, triple DES) in CBC mode. Encrypt a string using IDEA: int do_crypt(char *outfile) - { + { unsigned char outbuf[1024]; int outlen, tmplen; /* Bogus key and IV: we'd normally set these from @@ -523,10 +536,10 @@ Encrypt a string using IDEA: EVP_CIPHER_CTX ctx; FILE *out; - EVP_CIPHER_CTX_init(&ctx); - EVP_EncryptInit_ex(&ctx, EVP_idea_cbc(), NULL, key, iv); + ctx = EVP_CIPHER_CTX_new(); + EVP_EncryptInit_ex(ctx, EVP_idea_cbc(), NULL, key, iv); - if(!EVP_EncryptUpdate(&ctx, outbuf, &outlen, intext, strlen(intext))) + if(!EVP_EncryptUpdate(ctx, outbuf, &outlen, intext, strlen(intext))) { /* Error */ return 0; @@ -534,13 +547,13 @@ Encrypt a string using IDEA: /* Buffer passed to EVP_EncryptFinal() must be after data just * encrypted to avoid overwriting it. */ - if(!EVP_EncryptFinal_ex(&ctx, outbuf + outlen, &tmplen)) + if(!EVP_EncryptFinal_ex(ctx, outbuf + outlen, &tmplen)) { /* Error */ return 0; } outlen += tmplen; - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); /* Need binary mode for fopen because encrypted data is * binary data. Also cannot use strlen() on it because * it wont be null terminated and may contain embedded @@ -566,7 +579,7 @@ with a 128-bit key: /* Allow enough space in output buffer for additional block */ unsigned char inbuf[1024], outbuf[1024 + EVP_MAX_BLOCK_LENGTH]; int inlen, outlen; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx; /* Bogus key and IV: we'd normally set these from * another source. */ @@ -574,36 +587,36 @@ with a 128-bit key: unsigned char iv[] = "1234567887654321"; /* Don't set key or IV right away; we want to check lengths */ - EVP_CIPHER_CTX_init(&ctx); + ctx = EVP_CIPHER_CTX_new(); EVP_CipherInit_ex(&ctx, EVP_aes_128_cbc(), NULL, NULL, NULL, do_encrypt); - OPENSSL_assert(EVP_CIPHER_CTX_key_length(&ctx) == 16); - OPENSSL_assert(EVP_CIPHER_CTX_iv_length(&ctx) == 16); + OPENSSL_assert(EVP_CIPHER_CTX_key_length(ctx) == 16); + OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) == 16); /* Now we can set key and IV */ - EVP_CipherInit_ex(&ctx, NULL, NULL, key, iv, do_encrypt); + EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, do_encrypt); for(;;) { inlen = fread(inbuf, 1, 1024, in); if(inlen <= 0) break; - if(!EVP_CipherUpdate(&ctx, outbuf, &outlen, inbuf, inlen)) + if(!EVP_CipherUpdate(ctx, outbuf, &outlen, inbuf, inlen)) { /* Error */ - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); return 0; } fwrite(outbuf, 1, outlen, out); } - if(!EVP_CipherFinal_ex(&ctx, outbuf, &outlen)) + if(!EVP_CipherFinal_ex(ctx, outbuf, &outlen)) { /* Error */ - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); return 0; } fwrite(outbuf, 1, outlen, out); - EVP_CIPHER_CTX_cleanup(&ctx); + EVP_CIPHER_CTX_free(ctx); return 1; } @@ -616,4 +629,9 @@ L Support for OCB mode was added in OpenSSL 1.1.0 +B was made opaque in OpenSSL 1.1.0. As a result, +EVP_CIPHER_CTX_reset() appeared and EVP_CIPHER_CTX_cleanup() +disappeared. EVP_CIPHER_CTX_init() remains as an alias for +EVP_CIPHER_CTX_reset(). + =cut -- 2.34.1