mirror of
https://github.com/openssl/openssl.git
synced 2024-11-25 11:03:37 +08:00
Option to disable standard block padding with EVP API.
Add -nopad option to enc command. Update docs.
This commit is contained in:
parent
36fafffae2
commit
f2e5ca84d4
7
CHANGES
7
CHANGES
@ -3,6 +3,13 @@
|
||||
|
||||
Changes between 0.9.6 and 0.9.7 [xx XXX 2000]
|
||||
|
||||
*) New function EVP_CIPHER_CTX_set_padding() this is used to
|
||||
disable standard block padding (aka PKCS#5 padding) in the EVP
|
||||
API, which was previously mandatory. This means that the data is
|
||||
not padded in any way and so the total length much be a multiple
|
||||
of the block size, otherwise an error occurs.
|
||||
[Steve Henson]
|
||||
|
||||
*) Initial (incomplete) OCSP SSL support.
|
||||
[Steve Henson]
|
||||
|
||||
|
@ -111,6 +111,7 @@ int MAIN(int argc, char **argv)
|
||||
unsigned char *buff=NULL,*bufsize=NULL;
|
||||
int bsize=BSIZE,verbose=0;
|
||||
int ret=1,inl;
|
||||
int nopad = 0;
|
||||
unsigned char key[EVP_MAX_KEY_LENGTH],iv[EVP_MAX_IV_LENGTH];
|
||||
unsigned char salt[PKCS5_SALT_LEN];
|
||||
char *str=NULL, *passarg = NULL, *pass = NULL;
|
||||
@ -174,6 +175,8 @@ int MAIN(int argc, char **argv)
|
||||
printkey=1;
|
||||
else if (strcmp(*argv,"-v") == 0)
|
||||
verbose=1;
|
||||
else if (strcmp(*argv,"-nopad") == 0)
|
||||
nopad=1;
|
||||
else if (strcmp(*argv,"-salt") == 0)
|
||||
nosalt=0;
|
||||
else if (strcmp(*argv,"-nosalt") == 0)
|
||||
@ -513,6 +516,12 @@ bad:
|
||||
if ((benc=BIO_new(BIO_f_cipher())) == NULL)
|
||||
goto end;
|
||||
BIO_set_cipher(benc,cipher,key,iv,enc);
|
||||
if (nopad)
|
||||
{
|
||||
EVP_CIPHER_CTX *ctx;
|
||||
BIO_get_cipher_ctx(benc, &ctx);
|
||||
EVP_CIPHER_CTX_set_padding(ctx, 0);
|
||||
}
|
||||
if (debug)
|
||||
{
|
||||
BIO_set_callback(benc,BIO_debug_callback);
|
||||
|
@ -373,6 +373,8 @@ struct evp_cipher_st
|
||||
#define EVP_CIPH_CTRL_INIT 0x40
|
||||
/* Don't use standard key length function */
|
||||
#define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80
|
||||
/* Don't use standard block padding */
|
||||
#define EVP_CIPH_NO_PADDING 0x100
|
||||
|
||||
/* ctrl() values */
|
||||
|
||||
@ -402,6 +404,7 @@ struct evp_cipher_ctx_st
|
||||
|
||||
void *app_data; /* application stuff */
|
||||
int key_len; /* May change for variable length cipher */
|
||||
unsigned long flags; /* Various flags */
|
||||
union
|
||||
{
|
||||
#ifndef NO_RC4
|
||||
@ -620,6 +623,7 @@ void ERR_load_EVP_strings(void );
|
||||
void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
|
||||
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
|
||||
int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen);
|
||||
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad);
|
||||
int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr);
|
||||
|
||||
#ifndef NO_BIO
|
||||
@ -807,6 +811,7 @@ void EVP_PBE_cleanup(void);
|
||||
#define EVP_F_EVP_CIPHER_CTX_CTRL 124
|
||||
#define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122
|
||||
#define EVP_F_EVP_DECRYPTFINAL 101
|
||||
#define EVP_F_EVP_ENCRYPTFINAL 127
|
||||
#define EVP_F_EVP_MD_CTX_COPY 110
|
||||
#define EVP_F_EVP_OPENINIT 102
|
||||
#define EVP_F_EVP_PBE_ALG_ADD 115
|
||||
@ -838,6 +843,7 @@ void EVP_PBE_cleanup(void);
|
||||
#define EVP_R_CIPHER_PARAMETER_ERROR 122
|
||||
#define EVP_R_CTRL_NOT_IMPLEMENTED 132
|
||||
#define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133
|
||||
#define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138
|
||||
#define EVP_R_DECODE_ERROR 114
|
||||
#define EVP_R_DIFFERENT_KEY_TYPES 101
|
||||
#define EVP_R_ENCODE_ERROR 115
|
||||
|
@ -77,6 +77,7 @@ int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
|
||||
if (cipher) {
|
||||
ctx->cipher=cipher;
|
||||
ctx->key_len = cipher->key_len;
|
||||
ctx->flags = 0;
|
||||
if(ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
|
||||
if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) {
|
||||
EVPerr(EVP_F_EVP_CIPHERINIT, EVP_R_INITIALIZATION_ERROR);
|
||||
@ -200,6 +201,16 @@ int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
||||
return 1;
|
||||
}
|
||||
bl=ctx->buf_len;
|
||||
if (ctx->flags & EVP_CIPH_NO_PADDING)
|
||||
{
|
||||
if(bl)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_ENCRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
*outl = 0;
|
||||
return 1;
|
||||
}
|
||||
n=b-bl;
|
||||
for (i=bl; i<b; i++)
|
||||
ctx->buf[i]=n;
|
||||
@ -217,6 +228,9 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl,
|
||||
*outl=0;
|
||||
if (inl == 0) return 1;
|
||||
|
||||
if (ctx->flags & EVP_CIPH_NO_PADDING)
|
||||
return EVP_EncryptUpdate(ctx, out, outl, in, inl);
|
||||
|
||||
b=ctx->cipher->block_size;
|
||||
if (b > 1)
|
||||
{
|
||||
@ -261,6 +275,16 @@ int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl)
|
||||
|
||||
*outl=0;
|
||||
b=ctx->cipher->block_size;
|
||||
if (ctx->flags & EVP_CIPH_NO_PADDING)
|
||||
{
|
||||
if(ctx->buf_len)
|
||||
{
|
||||
EVPerr(EVP_F_EVP_DECRYPTFINAL,EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
*outl = 0;
|
||||
return 1;
|
||||
}
|
||||
if (b > 1)
|
||||
{
|
||||
if (ctx->buf_len != b)
|
||||
@ -319,6 +343,13 @@ int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad)
|
||||
{
|
||||
if (pad) ctx->flags &= ~EVP_CIPH_NO_PADDING;
|
||||
else ctx->flags |= EVP_CIPH_NO_PADDING;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr)
|
||||
{
|
||||
int ret;
|
||||
|
@ -71,6 +71,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
|
||||
{ERR_PACK(0,EVP_F_EVP_CIPHER_CTX_CTRL,0), "EVP_CIPHER_CTX_ctrl"},
|
||||
{ERR_PACK(0,EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH,0), "EVP_CIPHER_CTX_set_key_length"},
|
||||
{ERR_PACK(0,EVP_F_EVP_DECRYPTFINAL,0), "EVP_DecryptFinal"},
|
||||
{ERR_PACK(0,EVP_F_EVP_ENCRYPTFINAL,0), "EVP_EncryptFinal"},
|
||||
{ERR_PACK(0,EVP_F_EVP_MD_CTX_COPY,0), "EVP_MD_CTX_copy"},
|
||||
{ERR_PACK(0,EVP_F_EVP_OPENINIT,0), "EVP_OpenInit"},
|
||||
{ERR_PACK(0,EVP_F_EVP_PBE_ALG_ADD,0), "EVP_PBE_alg_add"},
|
||||
@ -105,6 +106,7 @@ static ERR_STRING_DATA EVP_str_reasons[]=
|
||||
{EVP_R_CIPHER_PARAMETER_ERROR ,"cipher parameter error"},
|
||||
{EVP_R_CTRL_NOT_IMPLEMENTED ,"ctrl not implemented"},
|
||||
{EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED ,"ctrl operation not implemented"},
|
||||
{EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH ,"data not multiple of block length"},
|
||||
{EVP_R_DECODE_ERROR ,"decode error"},
|
||||
{EVP_R_DIFFERENT_KEY_TYPES ,"different key types"},
|
||||
{EVP_R_ENCODE_ERROR ,"encode error"},
|
||||
|
@ -21,6 +21,7 @@ B<openssl enc -ciphername>
|
||||
[B<-p>]
|
||||
[B<-P>]
|
||||
[B<-bufsize number>]
|
||||
[B<-nopad>]
|
||||
[B<-debug>]
|
||||
|
||||
=head1 DESCRIPTION
|
||||
@ -116,6 +117,10 @@ or decryption.
|
||||
|
||||
set the buffer size for I/O
|
||||
|
||||
=item B<-nopad>
|
||||
|
||||
disable standard block padding
|
||||
|
||||
=item B<-debug>
|
||||
|
||||
debug the BIOs used for I/O.
|
||||
@ -144,11 +149,14 @@ Some of the ciphers do not have large keys and others have security
|
||||
implications if not used correctly. A beginner is advised to just use
|
||||
a strong block cipher in CBC mode such as bf or des3.
|
||||
|
||||
All the block ciphers use PKCS#5 padding also known as standard block
|
||||
All the block ciphers normally use PKCS#5 padding also known as standard block
|
||||
padding: this allows a rudimentary integrity or password check to be
|
||||
performed. However since the chance of random data passing the test is
|
||||
better than 1 in 256 it isn't a very good test.
|
||||
|
||||
If padding is disabled then the input data must be a muliple of the cipher
|
||||
block length.
|
||||
|
||||
All RC2 ciphers have the same key and effective key length.
|
||||
|
||||
Blowfish and RC5 algorithms use a 128 bit key.
|
||||
@ -250,8 +258,8 @@ The B<-A> option when used with large files doesn't work properly.
|
||||
|
||||
There should be an option to allow an iteration count to be included.
|
||||
|
||||
Like the EVP library the B<enc> program only supports a fixed number of
|
||||
algorithms with certain parameters. So if, for example, you want to use RC2
|
||||
with a 76 bit key or RC4 with an 84 bit key you can't use this program.
|
||||
The B<enc> program only supports a fixed number of algorithms with
|
||||
certain parameters. So if, for example, you want to use RC2 with a
|
||||
76 bit key or RC4 with an 84 bit key you can't use this program.
|
||||
|
||||
=cut
|
||||
|
@ -12,7 +12,7 @@ EVP_CIPHER_mode, EVP_CIPHER_type, EVP_CIPHER_CTX_cipher, EVP_CIPHER_CTX_nid,
|
||||
EVP_CIPHER_CTX_block_size, EVP_CIPHER_CTX_key_length, EVP_CIPHER_CTX_iv_length,
|
||||
EVP_CIPHER_CTX_get_app_data, EVP_CIPHER_CTX_set_app_data, EVP_CIPHER_CTX_type,
|
||||
EVP_CIPHER_CTX_flags, EVP_CIPHER_CTX_mode, EVP_CIPHER_param_to_asn1,
|
||||
EVP_CIPHER_asn1_to_param - EVP cipher routines
|
||||
EVP_CIPHER_asn1_to_param, EVP_CIPHER_CTX_set_padding - EVP cipher routines
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
@ -39,6 +39,7 @@ EVP_CIPHER_asn1_to_param - EVP cipher routines
|
||||
int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm,
|
||||
int *outl);
|
||||
|
||||
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);
|
||||
@ -89,22 +90,28 @@ multiple times to encrypt successive blocks of data. The amount
|
||||
of data written depends on the block alignment of the encrypted data:
|
||||
as a result the amount of data written may be anything from zero bytes
|
||||
to (inl + cipher_block_size - 1) so B<outl> should contain sufficient
|
||||
room. The actual number of bytes written is placed in B<outl>.
|
||||
room. The actual number of bytes written is placed in B<outl>.
|
||||
|
||||
EVP_EncryptFinal() encrypts the "final" data, that is any data that
|
||||
remains in a partial block. It uses L<standard block padding|/NOTES> (aka PKCS
|
||||
padding). The encrypted final data is written to B<out> which should
|
||||
have sufficient space for one cipher block. The number of bytes written
|
||||
is placed in B<outl>. After this function is called the encryption operation
|
||||
is finished and no further calls to EVP_EncryptUpdate() should be made.
|
||||
If padding is enabled (the default) then EVP_EncryptFinal() encrypts
|
||||
the "final" data, that is any data that remains in a partial block.
|
||||
It uses L<standard block padding|/NOTES> (aka PKCS padding). The encrypted
|
||||
final data is written to B<out> which should have sufficient space for
|
||||
one cipher block. The number of bytes written is placed in B<outl>. After
|
||||
this function is called the encryption operation is finished and no further
|
||||
calls to EVP_EncryptUpdate() should be made.
|
||||
|
||||
If padding is disabled then EVP_EncryptFinal() will not encrypt any more
|
||||
data and it will return an error if any data remains in a partial block:
|
||||
that is if the total data length is not a multiple of the block size.
|
||||
|
||||
EVP_DecryptInit(), EVP_DecryptUpdate() and EVP_DecryptFinal() are the
|
||||
corresponding decryption operations. EVP_DecryptFinal() will return an
|
||||
error code if the final block is not correctly formatted. The parameters
|
||||
and restrictions are identical to the encryption operations except that
|
||||
the decrypted data buffer B<out> passed to EVP_DecryptUpdate() should
|
||||
have sufficient room for (B<inl> + cipher_block_size) bytes unless the
|
||||
cipher block size is 1 in which case B<inl> bytes is sufficient.
|
||||
error code if padding is enabled and the final block is not correctly
|
||||
formatted. The parameters and restrictions are identical to the encryption
|
||||
operations except that if padding is enabled the decrypted data buffer B<out>
|
||||
passed to EVP_DecryptUpdate() should have sufficient room for
|
||||
(B<inl> + cipher_block_size) bytes unless the cipher block size is 1 in
|
||||
which case B<inl> bytes is sufficient.
|
||||
|
||||
EVP_CipherInit(), EVP_CipherUpdate() and EVP_CipherFinal() are functions
|
||||
that can be used for decryption or encryption. The operation performed
|
||||
@ -125,6 +132,13 @@ passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX> structure. The actual NID
|
||||
value is an internal value which may not have a corresponding OBJECT
|
||||
IDENTIFIER.
|
||||
|
||||
EVP_CIPHER_CTX_set_padding() enables or disables padding. By default
|
||||
encryption operations are padded using standard block padding and the
|
||||
padding is checked and removed when decrypting. If the B<pad> parameter
|
||||
is zero then no padding is performed, the total amount of data encrypted
|
||||
or decrypted must then be a multiple of the block size or an error will
|
||||
occur.
|
||||
|
||||
EVP_CIPHER_key_length() and EVP_CIPHER_CTX_key_length() return the key
|
||||
length of a cipher when passed an B<EVP_CIPHER> or B<EVP_CIPHER_CTX>
|
||||
structure. The constant B<EVP_MAX_KEY_LENGTH> is the maximum key length
|
||||
@ -207,6 +221,8 @@ size.
|
||||
EVP_CIPHER_key_length() and EVP_CIPHER_CTX_key_length() return the key
|
||||
length.
|
||||
|
||||
EVP_CIPHER_CTX_set_padding() always returns 1.
|
||||
|
||||
EVP_CIPHER_iv_length() and EVP_CIPHER_CTX_iv_length() return the IV
|
||||
length or zero if the cipher does not use an IV.
|
||||
|
||||
@ -301,10 +317,13 @@ encrypted then 5 padding bytes of value 5 will be added.
|
||||
|
||||
When decrypting the final block is checked to see if it has the correct form.
|
||||
|
||||
Although the decryption operation can produce an error, it is not a strong
|
||||
test that the input data or key is correct. A random block has better than
|
||||
1 in 256 chance of being of the correct format and problems with the
|
||||
input data earlier on will not produce a final decrypt error.
|
||||
Although the decryption operation can produce an error if padding is enabled,
|
||||
it is not a strong test that the input data or key is correct. A random block
|
||||
has better than 1 in 256 chance of being of the correct format and problems with
|
||||
the input data earlier on will not produce a final decrypt error.
|
||||
|
||||
If padding is disabled then the decryption operation will always succeed if
|
||||
the total amount of data decrypted is a multiple of the block size.
|
||||
|
||||
The functions EVP_EncryptInit(), EVP_EncryptUpdate(), EVP_EncryptFinal(),
|
||||
EVP_DecryptInit(), EVP_DecryptUpdate(), EVP_CipherInit() and EVP_CipherUpdate()
|
||||
@ -318,8 +337,6 @@ and attempt to set the key before the cipher is set in EVP_EncryptInit() ).
|
||||
For RC5 the number of rounds can currently only be set to 8, 12 or 16. This is
|
||||
a limitation of the current RC5 code rather than the EVP interface.
|
||||
|
||||
It should be possible to disable PKCS padding: currently it isn't.
|
||||
|
||||
EVP_MAX_KEY_LENGTH and EVP_MAX_IV_LENGTH only refer to the internal ciphers with
|
||||
default key lengths. If custom ciphers exceed these values the results are
|
||||
unpredictable. This is because it has become standard practice to define a
|
||||
@ -333,22 +350,22 @@ for certain common S/MIME ciphers (RC2, DES, triple DES) in CBC mode.
|
||||
Get the number of rounds used in RC5:
|
||||
|
||||
int nrounds;
|
||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_RC5_ROUNDS, 0, &i);
|
||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_RC5_ROUNDS, 0, &nrounds);
|
||||
|
||||
Get the RC2 effective key length:
|
||||
|
||||
int key_bits;
|
||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i);
|
||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GET_RC2_KEY_BITS, 0, &key_bits);
|
||||
|
||||
Set the number of rounds used in RC5:
|
||||
|
||||
int nrounds;
|
||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC5_ROUNDS, i, NULL);
|
||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC5_ROUNDS, nrounds, NULL);
|
||||
|
||||
Set the number of rounds used in RC2:
|
||||
Set the effective key length used in RC2:
|
||||
|
||||
int nrounds;
|
||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, i, NULL);
|
||||
int key_bits;
|
||||
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL);
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user