Nasty bug in crypto/evp/m_sigver.c

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Nasty bug in crypto/evp/m_sigver.c

Blumenthal, Uri - 0553 - MITLL

This bug prevents normal working of EVP_DigestSignInit() and subsequent calls when pkcs11 engine is involved.

 

Scenario: hashing and signing data, when signing is done on a token that supports only internal padding (aka it performs RSA-PSS padding on-board, rather than letting software such as OpenSSL do the PSS padding for it).

 

The current implementation works if either the token (pkcs11 engine) can do the digest (data hashing) on-board, or when it doesn’t do anything on-board except for the raw RSA.

 

For a pkcs11 device that does not hash data on-board, but does the padding on-board, one needs to pass two contexts to EVP_DigestSignInit(): md_ctx that does not point at an engine, and “signing context” ctx that was created with the engine so it can pass signing request to it.

 

The nature of this bug is that EVP_DigestSignInit() ignores provided ctx. Then if you provide the engine, it is used for both digest and signature – which fails on the attempt to off-load digest to the engine (HSM device that does not hash data). If you don’t provide the engine, then everything is done in software, and the engine receives only the very last raw RSA request – which gets rejected as this HSM device does not support raw RSA.

 

Here’s the patch:

 

--- a/crypto/evp/m_sigver.c

+++ b/crypto/evp/m_sigver.c

@@ -19,8 +19,12 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,

                           const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,

                           int ver)

{

-    if (ctx->pctx == NULL)

-        ctx->pctx = EVP_PKEY_CTX_new(pkey, e);

+    if (ctx->pctx == NULL) {

+        if (pctx && *pctx)

+            ctx->pctx = *pctx;

+        else

+            ctx->pctx = EVP_PKEY_CTX_new(pkey, e);

+    }

     if (ctx->pctx == NULL)

         return 0;

 

I’ve tested with and without this patch. Here are the results (debugging information is from the libp11 pkcs11 engine):

 

Without the patch:

$ ./t2

Using YubiHSM device...

Signature padding is RSA-PSS padding

Enter PKCS#11 token PIN for YubiHSM:

Set RSA signature padding to RSA-PSS padding

t2.c:178 sign: EVP_DigestSignFinal() failed olen=512 (rv=0)

140736410264512:error:8207A070:PKCS#11 module:pkcs11_private_encrypt:Mechanism invalid:p11_rsa.c:140:

 

Mechanism invalid because raw RSA operation is requested, and the device does not support it.

 

With the above patch:

$ ./t2

Using YubiHSM device...

Signature padding is RSA-PSS padding

Enter PKCS#11 token PIN for YubiHSM:

Set RSA signature padding to RSA-PSS padding

p11_pkey.c:171 pkcs11_pkey_rsa_sign(): sig=0x7fa38f645cd0 *siglen=512 tbs=0x7fff51d83d40 tbslen=32

p11_pkey.c:215 saltlen=478 hashAlg=SHA256 mgf=MGF1-SHA256

p11_pkey.c:513 hashAlg=SHA256 mgf=MGF1-SHA256

Signed (data len=83, sig len=512):

1b d9 56 0e 80 80 7d 3b 29 0a 93 34 7d c5 27 7b

54 d3 c8 2d 59 3d 08 fc 59 d4 62 64 ce 1c 73 51

d9 9f 87 41 2e 2b 6c 2c d6 7e 9f 30 60 cf 0c 99

4e 85 b4 7b 9e 82 63 40 ce 33 27 4c 13 aa 3c b7

ba 8f 77 e1 5e 32 7c 70 78 e8 74 5a 6f cf 0f f3

5c 56 91 c9 62 46 a4 c2 3e 7d 54 2b ed a5 e1 ec

ff a1 54 29 f2 ac d6 91 09 98 3a 8f 99 1b 22 32

c0 a5 84 ce a8 ee fc 89 db 6e 82 50 0b 62 57 1b

09 cc 70 f6 57 27 b3 e4 4f fe 8d 65 e5 4c 61 ad

0b a8 77 97 22 14 59 6d 25 28 b2 8a 3f ee 63 a1

fc fa ab 20 f3 68 37 65 b2 3a c6 71 75 ac 2d fd

79 67 17 27 62 b2 26 35 0b 84 9b 1a db d7 23 c1

cb de 7d 29 5d 87 24 7b f5 88 45 82 d9 7a 84 e8

80 36 35 f8 a6 79 a5 54 98 4b 37 e0 1d b2 ff 4f

0e d2 f5 a2 b7 21 26 96 8c b8 f4 c2 32 6d 7b 62

16 57 de 29 b9 f9 df 6d db 9b 4e 8b b5 00 c5 3f

7b 21 03 36 10 50 e6 e3 93 52 07 15 c1 15 7d 92

02 8e 89 df d3 63 0d 8d d3 ca 22 bb 7f d1 1d c2

9c d8 e9 3b 7a c4 52 de 5d 71 a4 08 6e 18 a9 ff

4a 36 7f 54 c3 ae 1d 91 f1 aa 46 30 b6 ba 0b cb

46 fc bb de bb d5 5e e5 aa 9e f4 93 9b 6f 68 dc

83 20 b0 e0 74 be 1b c7 87 f9 8e ef 47 eb 1a 7d

93 0d be e8 66 ca 4a ff c0 f7 66 58 32 39 2d 84

9f 0c 63 53 11 4e 92 44 a1 83 59 09 1a 86 04 21

05 c5 35 6c f7 46 96 08 ff 2c 37 3b 48 a2 28 50

60 2d 1e 54 ce 4f d5 00 c8 58 86 6e 61 ca 68 d6

16 f6 16 60 22 9e 9a 64 f2 1a ff 87 1d 56 59 48

c8 c6 c7 eb 43 0a 02 10 a9 6e fa d1 86 32 a0 c4

f2 de d6 94 e1 4a cd 41 64 73 e3 85 0f 07 57 f9

85 ef 38 8f f9 01 6d 94 28 c7 a3 51 8f b5 47 16

b7 15 d7 0b b6 c1 58 26 5a 2c 18 b4 ca 9a ab d1

8b d8 b9 d6 03 80 7e c4 a6 28 27 6b 51 dd 3e 41

 

$

 

Digest is correctly performed by OpenSSL, and the entire RSA-PSS operation is sent to the engine. HSM device completes it successfully.

 

I’d really appreciate if you could apply it.

--

Regards,

Uri Blumenthal


--
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

smime.p7s (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Nasty bug in crypto/evp/m_sigver.c

Blumenthal, Uri - 0553 - MITLL

Forgot to add that when you do provide the engine impl in the EVP_DigestSignInit() invocation, the app fails because it tries to “outsource” the digesting of the data to the engine as well:

 

$ ./t2a

Using YubiHSM device...

Signature padding is RSA-PSS padding

Enter PKCS#11 token PIN for YubiHSM:

t2.c:143 sign: EVP_DigestSignInit() failed (rv=0)

140736410264584:error:260BA093:engine routines:ENGINE_get_digest:unimplemented digest:tb_digest.c:126:

140736410264584:error:06080086:digital envelope routines:EVP_DigestInit_ex:initialization error:digest.c:193:

 

--

Regards,

Uri Blumenthal

 

From: Uri Blumenthal <[hidden email]>
Date: Wednesday, October 04, 2017 at 16:03
To: openssl-dev <[hidden email]>
Subject: Nasty bug in crypto/evp/m_sigver.c

 

This bug prevents normal working of EVP_DigestSignInit() and subsequent calls when pkcs11 engine is involved.

 

Scenario: hashing and signing data, when signing is done on a token that supports only internal padding (aka it performs RSA-PSS padding on-board, rather than letting software such as OpenSSL do the PSS padding for it).

 

The current implementation works if either the token (pkcs11 engine) can do the digest (data hashing) on-board, or when it doesn’t do anything on-board except for the raw RSA.

 

For a pkcs11 device that does not hash data on-board, but does the padding on-board, one needs to pass two contexts to EVP_DigestSignInit(): md_ctx that does not point at an engine, and “signing context” ctx that was created with the engine so it can pass signing request to it.

 

The nature of this bug is that EVP_DigestSignInit() ignores provided ctx. Then if you provide the engine, it is used for both digest and signature – which fails on the attempt to off-load digest to the engine (HSM device that does not hash data). If you don’t provide the engine, then everything is done in software, and the engine receives only the very last raw RSA request – which gets rejected as this HSM device does not support raw RSA.

 

Here’s the patch:

 

--- a/crypto/evp/m_sigver.c

+++ b/crypto/evp/m_sigver.c

@@ -19,8 +19,12 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,

                           const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey,

                           int ver)

{

-    if (ctx->pctx == NULL)

-        ctx->pctx = EVP_PKEY_CTX_new(pkey, e);

+    if (ctx->pctx == NULL) {

+        if (pctx && *pctx)

+            ctx->pctx = *pctx;

+        else

+            ctx->pctx = EVP_PKEY_CTX_new(pkey, e);

+    }

     if (ctx->pctx == NULL)

         return 0;

 

I’ve tested with and without this patch. Here are the results (debugging information is from the libp11 pkcs11 engine):

 

Without the patch:

$ ./t2

Using YubiHSM device...

Signature padding is RSA-PSS padding

Enter PKCS#11 token PIN for YubiHSM:

Set RSA signature padding to RSA-PSS padding

t2.c:178 sign: EVP_DigestSignFinal() failed olen=512 (rv=0)

140736410264512:error:8207A070:PKCS#11 module:pkcs11_private_encrypt:Mechanism invalid:p11_rsa.c:140:

 

Mechanism invalid because raw RSA operation is requested, and the device does not support it.

 

With the above patch:

$ ./t2

Using YubiHSM device...

Signature padding is RSA-PSS padding

Enter PKCS#11 token PIN for YubiHSM:

Set RSA signature padding to RSA-PSS padding

p11_pkey.c:171 pkcs11_pkey_rsa_sign(): sig=0x7fa38f645cd0 *siglen=512 tbs=0x7fff51d83d40 tbslen=32

p11_pkey.c:215 saltlen=478 hashAlg=SHA256 mgf=MGF1-SHA256

p11_pkey.c:513 hashAlg=SHA256 mgf=MGF1-SHA256

Signed (data len=83, sig len=512):

1b d9 56 0e 80 80 7d 3b 29 0a 93 34 7d c5 27 7b

54 d3 c8 2d 59 3d 08 fc 59 d4 62 64 ce 1c 73 51

d9 9f 87 41 2e 2b 6c 2c d6 7e 9f 30 60 cf 0c 99

4e 85 b4 7b 9e 82 63 40 ce 33 27 4c 13 aa 3c b7

ba 8f 77 e1 5e 32 7c 70 78 e8 74 5a 6f cf 0f f3

5c 56 91 c9 62 46 a4 c2 3e 7d 54 2b ed a5 e1 ec

ff a1 54 29 f2 ac d6 91 09 98 3a 8f 99 1b 22 32

c0 a5 84 ce a8 ee fc 89 db 6e 82 50 0b 62 57 1b

09 cc 70 f6 57 27 b3 e4 4f fe 8d 65 e5 4c 61 ad

0b a8 77 97 22 14 59 6d 25 28 b2 8a 3f ee 63 a1

fc fa ab 20 f3 68 37 65 b2 3a c6 71 75 ac 2d fd

79 67 17 27 62 b2 26 35 0b 84 9b 1a db d7 23 c1

cb de 7d 29 5d 87 24 7b f5 88 45 82 d9 7a 84 e8

80 36 35 f8 a6 79 a5 54 98 4b 37 e0 1d b2 ff 4f

0e d2 f5 a2 b7 21 26 96 8c b8 f4 c2 32 6d 7b 62

16 57 de 29 b9 f9 df 6d db 9b 4e 8b b5 00 c5 3f

7b 21 03 36 10 50 e6 e3 93 52 07 15 c1 15 7d 92

02 8e 89 df d3 63 0d 8d d3 ca 22 bb 7f d1 1d c2

9c d8 e9 3b 7a c4 52 de 5d 71 a4 08 6e 18 a9 ff

4a 36 7f 54 c3 ae 1d 91 f1 aa 46 30 b6 ba 0b cb

46 fc bb de bb d5 5e e5 aa 9e f4 93 9b 6f 68 dc

83 20 b0 e0 74 be 1b c7 87 f9 8e ef 47 eb 1a 7d

93 0d be e8 66 ca 4a ff c0 f7 66 58 32 39 2d 84

9f 0c 63 53 11 4e 92 44 a1 83 59 09 1a 86 04 21

05 c5 35 6c f7 46 96 08 ff 2c 37 3b 48 a2 28 50

60 2d 1e 54 ce 4f d5 00 c8 58 86 6e 61 ca 68 d6

16 f6 16 60 22 9e 9a 64 f2 1a ff 87 1d 56 59 48

c8 c6 c7 eb 43 0a 02 10 a9 6e fa d1 86 32 a0 c4

f2 de d6 94 e1 4a cd 41 64 73 e3 85 0f 07 57 f9

85 ef 38 8f f9 01 6d 94 28 c7 a3 51 8f b5 47 16

b7 15 d7 0b b6 c1 58 26 5a 2c 18 b4 ca 9a ab d1

8b d8 b9 d6 03 80 7e c4 a6 28 27 6b 51 dd 3e 41

 

$

 

Digest is correctly performed by OpenSSL, and the entire RSA-PSS operation is sent to the engine. HSM device completes it successfully.

 

I’d really appreciate if you could apply it.

--

Regards,

Uri Blumenthal


--
openssl-dev mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-dev

smime.p7s (6K) Download Attachment