Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[openssl-users] SHA256() to EVP_* ?

502 views
Skip to first unread message

jonetsu

unread,
Apr 28, 2015, 2:10:35 PM4/28/15
to
Hello,

What would be the equivalent of the SHA256() function in the EVP
class of methods ? EVP_sha256() could be it, although from the
short description in manual page it does not seemingly fit in,
returning a EVP_MD which is, if not mistaken, a env_md_st
structure.

The code I'm adapting to EVP has a first pass of shortening the
key if too long:

/* Change key if longer than 64 bytes */
if (klen > HMAC_INT_LEN) {
SHA256(key, klen, nkey);
key = nkey;
klen = SHA256_DIGEST_LENGTH;
}

Before proceeding with the usual SHA256_Init(),
SHA256_Update() (twice), and SHA256_Final. All of which I have
tested with the corresponding EVP_* methods. For the use of
SHA256() above, though, I'm puzzled regarding its EVP_*
counterpart.

Suggestions, comments appreciated.

Regards.





--
View this message in context: http://openssl.6102.n7.nabble.com/SHA256-to-EVP-tp57774.html
Sent from the OpenSSL - User mailing list archive at Nabble.com.
_______________________________________________
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

Dave Thompson

unread,
Apr 28, 2015, 8:30:02 PM4/28/15
to
> From: openssl-users On Behalf Of jonetsu
> Sent: Tuesday, April 28, 2015 13:53

> What would be the equivalent of the SHA256() function in the EVP
> class of methods ? EVP_sha256() could be it, although from the
> short description in manual page it does not seemingly fit in,
> returning a EVP_MD which is, if not mistaken, a env_md_st
> structure.
>
The LOWLEVEL modules use separate routines. There are routines
for SHA1, and *separate* routines for SHA256, and separate routines
for SHA384, and separate routines for MD5, and separate routines for
RIPEMD160. There are routines for AES, and separate routines for
RC4, and separate routines for Blowfish, and routines for DES and
"tripleDES" aka DESede that overlap *some* because of the very
close relationship but separate from all other symmetric ciphers.
There are routines for RSA, and separate routines for DSA, and
separate routines for DH, and separate routines for ECDSA,
and separate routines for ECDH.

EVP DOES NOT. EVP has *one* set of digest routines used for ALL
digest algorithms, but with a data object specifying *which* digest.
EVP has *one* set of Cipher routines used for all symmetric ciphers,
with a data object specifying which. EVP has due to history *two*
sets of asymmetric signature routines, which apply to three (and
possibly more) asymmetric algorithms specified by data objects.

Thus the EVP equivalent to the SHA256*() lowlevel calls is
to call the EVP_Digest* routines with a data object specifying
SHA256, which is exactly what the value of EVP_sha256() is.

The man page named for EVP_DigestInit which also covers
EVP_DigestInit_ex, EVP_DigestUpdate, EVP_DigestFinal,
EVP_DigestFinal_ex, and some related routines (although
the link for EVP_DigestFinal original seems to be missing)
tells you how to do digests with EVP in general. Apparently
it wasn't updated to list SHA2 digests, but that variation
should be obvious from documented pattern.

> The code I'm adapting to EVP has a first pass of shortening the
> key if too long:
>
> /* Change key if longer than 64 bytes */
> if (klen > HMAC_INT_LEN) {
> SHA256(key, klen, nkey);
> key = nkey;
> klen = SHA256_DIGEST_LENGTH;
> }
>
> Before proceeding with the usual SHA256_Init(),
> SHA256_Update() (twice), and SHA256_Final. All of which I have
> tested with the corresponding EVP_* methods. For the use of
> SHA256() above, though, I'm puzzled regarding its EVP_*
> counterpart.
>
If you are implementing HMAC, perhaps for PBKDF2 (which does
that prehash-if-too-long), I hope you mean the code does
one hash of ipad+data, which can consist of Init, 2 Updates,
and Finial (although there are other ways) and then a SECOND
ENTIRE HASH of opad+innerhash, similarly. If that's not what
you're doing, you're not doing standard HMAC, so it definitely
won't be interoperable and may well not be secure, because
HMAC was defined the way it is precisely because it was found
the naïve way merely hashing key+data is not reliably secure.

Although if what you want is PBKDF2-HMAC, there is already
two OpenSSL routines for that (again due to history).

jonetsu

unread,
Apr 29, 2015, 10:38:33 AM4/29/15
to
Thanks for the comments.

> If you are implementing HMAC, perhaps for PBKDF2 (which does
> that prehash-if-too-long), I hope you mean the code does...

Yes it does.

The man page (the one online from OpenSSL project - SHA256.html)
gives a description using SHA1() which computes a message digest.
Being generally new to OpenSSL at that level, what is then the
difference between using, say, SHA1() vs. using SHA1_Init,
SHA1_Update and SHA1_Final ? Is it only that the latter allows
for continuously add data until _Final is called ?





--
View this message in context: http://openssl.6102.n7.nabble.com/SHA256-to-EVP-tp57774p57791.html
Sent from the OpenSSL - User mailing list archive at Nabble.com.

Dave Thompson

unread,
May 1, 2015, 12:59:17 AM5/1/15
to
> From: openssl-users On Behalf Of jonetsu
> Sent: Wednesday, April 29, 2015 10:07
<snip>
> The man page (the one online from OpenSSL project - SHA256.html)
> gives a description using SHA1() which computes a message digest.

Note this is the same page for
SHA{1,224,256,384,512}{,_Init,_Update,_Final}.html
and is the same content that is provided as 'man' pages on a Unix install of
OpenSSL.
On Unix systems a man page for several related routines (or types/structures
etc)
can actually be one file with multiple links to it, but the website doesn't
bother.

> Being generally new to OpenSSL at that level, what is then the
> difference between using, say, SHA1() vs. using SHA1_Init,
> SHA1_Update and SHA1_Final ? Is it only that the latter allows
> for continuously add data until _Final is called ?
>
Very nearly. The 'all-in-one' routine SHA1() consists of:
- declare (thus implicitly allocate) CTX
- provide a static buffer by default (for legacy but this is a bad idea,
it is unsafe for threads or recursion, and should not be used today)
- do SHA1_Init and test for error (error won't actually occur but this
preserves a consistent structure with other algorithms that might)
- do EXACTLY ONE SHA1_Update
- do SHA1_Final
- "cleanse" the CTX to prevent leakage of data that might be sensitive
(whether it actually is sensitive depends on what the data is, but to be
on safe side always cleanse) and implicitly deallocate

and similarly for the other algorithms.

So the difference using separate calls is: you can do multiple _Update
steps/buffers, and you must handle the CTX and output buffer.

And you can do more flexible things like compute both SHA1 and MD5
for the same data concurrently, without needing to buffer all the data
(which in some applications might exceed your memory) or reread it
(which may be impossible in some applications like streaming video).

You may be thinking: this is just a small convenience, it's not hard to
do the separate routines. You're right, it's not. But if it happens 10
or 20 or 50 places in your code, saving 10 lines 50 times is 500 lines
you don't have to write, read, keep in source control, compile every
build, cover in your test strategy and coverage reports, etc.
Even a small convenience is still a convenience.

jonetsu

unread,
May 1, 2015, 7:50:34 AM5/1/15
to
> Even a small convenience is still a convenience.

And eventually they add up.

Thanks for the comments - it's appreciated.



--
View this message in context: http://openssl.6102.n7.nabble.com/SHA256-to-EVP-tp57774p57826.html
Sent from the OpenSSL - User mailing list archive at Nabble.com.
0 new messages