AES and EVP_CIPHER question

Matt Caswell matt at openssl.org
Tue May 17 10:32:31 UTC 2022



On 16/05/2022 23:48, Philip Prindeville wrote:
> Sorry, I shouldn't have phrased that inartfully.
> 
> There is no EVP_CIPHER_CTX_get_padding(), so how does one achieve something analogous?


 From 3.0, assuming you are using provided ciphers (i.e. not engine 
ones), then OSSL_CIPHER_PARAM_PADDING is a "gettable" parameter. See the 
section "Gettable and Settable EVP_CIPHER_CTX parameters" on this page:

https://www.openssl.org/docs/man3.0/man3/EVP_EncryptInit_ex2.html

So you can use EVP_CIPHER_CTX_get_params() to obtain that value 
(documented on the same man page as above). E.g. something like:

OSSL_PARAM params[2], *p = params;
unsigned int pad;

*p++ = OSSL_PARAM_construct_uint(OSSL_CIPHER_PARAM_PADDING,
                                  &pad);
*p = OSSL_PARAM_construct_end();

if (!EVP_CIPHER_CTX_get_params(ctx, params)) {
     /* Error */
}

Matt

> 
> 
>> On May 16, 2022, at 1:00 PM, Philip Prindeville <philipp_subx at redfish-solutions.com> wrote:
>>
>> Thanks.  That fixed the return value of EVP_CipherFinal().
>>
>> Is there a reciprocal EVP_CIPHER_CTX_get_padding() method to find out what the default padding method is for ECB?
>>
>>
>>
>>> On May 16, 2022, at 12:41 AM, Tomas Mraz <tomas at openssl.org> wrote:
>>>
>>> The EVP_CIPHER_CTX_set_padding(ctx, 0) must be called after the
>>> EVP_CipherInit() to have an effect.
>>>
>>> Also what is the AST_CRYPTO_AES_BLOCKSIZE value? Is it in bits (i.e,
>>> 128)?
>>>
>>> Also res should be initialized to -1 so you do not return uninitialized
>>> value on error.
>>>
>>> Tomas Mraz
>>>
>>> On Fri, 2022-05-13 at 09:49 -0600, Philip Prindeville wrote:
>>>> Hi,
>>>>
>>>> I'm trying to rewrite some legacy AES_* code to use EVP_CIPHER_* so
>>>> it's forward compatible into 3.x.
>>>>
>>>> My code, in a nutshell, looks like:
>>>>
>>>> static int evp_cipher_aes_decrypt(const unsigned char *in, unsigned
>>>> char *out, unsigned inlen, const ast_aes_decrypt_key *key)
>>>> {
>>>>         EVP_CIPHER_CTX *ctx;
>>>>         int res, outlen, finallen;
>>>>         unsigned char final[AST_CRYPTO_AES_BLOCKSIZE / 8];
>>>>
>>>>         if ((ctx = EVP_CIPHER_CTX_new()) == NULL) {
>>>>                 return -1;
>>>>         }
>>>>
>>>>         EVP_CIPHER_CTX_set_padding(ctx, 0);
>>>>
>>>>         do {
>>>>                 if ((res = EVP_CipherInit(ctx, EVP_aes_128_ecb(),
>>>> key->raw, NULL, 0)) <= 0) {
>>>>                         break;
>>>>                 }
>>>>                 if ((res = EVP_CipherUpdate(ctx, out, &outlen, in,
>>>> inlen)) <= 0) {
>>>>                         break;
>>>>                 }
>>>>                 /* for ECB, this is a no-op */
>>>>                 if ((res = EVP_CipherFinal(ctx, final, &finallen)) <=
>>>> 0) {
>>>>                         break;
>>>>                 }
>>>>
>>>>                 res = outlen;
>>>>         } while (0);
>>>>
>>>>         EVP_CIPHER_CTX_free(ctx);
>>>>
>>>>         return res;
>>>> }
>>>>
>>>> It's ECB, so there's no IV.  Or padding.  The block size and key size
>>>> are both 128 bits.
>>>>
>>>> One thing I noticed right away is that EVP_CipherUpdate() returns 1,
>>>> and sees "outlen" to zero.
>>>>
>>>> And then EVP_CipherFinal() returns 0, and sets "finallen" to zero.
>>>>
>>>> What's wrong with this code?
>>>>
>>>> I'm trying to write "naive" code that counts on the primitives to
>>>> indicate how much resultant output is generated for the input I've
>>>> given (yes, I know that it's 1:1 in the case of ECB, but I shouldn't
>>>> have to hard-code that in case I want to use the same code with
>>>> multiple block modes).
>>>>
>>>> The function is supposed to return <= 0 on error, otherwise the
>>>> number of bytes decrypted into "out" on success.
>>>>
>>>> Thanks,
>>>>
>>>> -Philip
>>>>
>>>
>>> -- 
>>> Tomáš Mráz, OpenSSL
>>>
>>>
>>
> 


More information about the openssl-users mailing list