Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signature broken for HSM devices in the current master #178

Closed
mouse07410 opened this issue Oct 6, 2017 · 29 comments
Closed

Signature broken for HSM devices in the current master #178

mouse07410 opened this issue Oct 6, 2017 · 29 comments
Labels

Comments

@mouse07410
Copy link
Contributor

mouse07410 commented Oct 6, 2017

First, thank you for starting to add support for PSS and OAEP.

Problem:

Current master fails to perform RSA-PSS (and RSA-PKCS) signing on HSM:

+ openssl rand -out t6400.dat 800
+ /Users/uri/openssl-1.1/bin/openssl dgst -engine pkcs11 -keyform engine -sign 'pkcs11:token=YubiHSM;id=%03%01;type=private' -sha384 -sigopt rsa_padding_mode:pss -out t6400.dat.sig t6400.dat
engine "pkcs11" set.
Enter PKCS#11 token PIN for YubiHSM:
pkcs11_pkey_rsa_sign called
salt_len=334 sig_md=673 mdf1_md=673
Enter PKCS#11 key PIN for RSASign:
C_SignInit and or C_Sign rv =259
Error Signing Data
140736337826752:error:8207A090:PKCS#11 module:pkcs11_private_encrypt:Operation active:p11_rsa.c:99:

Reason:

In 297fdda#diff-2590b49662dd77719cf90b1afe59cf81R173 you are forcing re-auth, which is rejected by the HSM device.

Solution:

Replace the offending line with something like

 if (rv != CKR_OK && rv != CKR_USER_NOT_LOGGED_IN) goto unlock;
 if (rv == CKR_USER_NOT_LOGGED_IN || kpriv->always_authenticate == CK_TRUE)
          rv = pkcs11_authenticate(key); /* don't re-auth unless flag is set! */

As we're at it, might add SHA224 and SHA-1 to sig_md hash just before 3a7750e#diff-2590b49662dd77719cf90b1afe59cf81R86, and SHA-1 just before 3a7750e#diff-2590b49662dd77719cf90b1afe59cf81R102.

As a nit, it would be nice to display the xxx_md not as numbers but as names, using something like EVP_MD_name(md) instead of EVP_MD_type(md). I'd much prefer seeing SHA384 to 673. ;-)

Thanks!

mtrojnar added a commit that referenced this issue Oct 6, 2017
These fixes should also address #178.
@mtrojnar
Copy link
Member

mtrojnar commented Oct 7, 2017

Please let us know whether the fix I implemented works for you.

@mouse07410
Copy link
Contributor Author

mouse07410 commented Oct 7, 2017

Please let us know whether the fix I implemented works for you.

Better, but still not good. It doesn't quite work for HSM, and broke it for PIV.

I see three big problems:

  1. It keeps prompting for re-authentication when it isn't appropriate.
  2. It fails to address the sig==NULL case.
  3. Improperly handles the fallback.

Also, the way it implements the fall-back seems broken. I don't see an obvious problem, but it does not work properly: keeps prompting for the PIN, and eventually fails...

For the first problem I recommend

diff --git a/src/p11_pkey.c b/src/p11_pkey.c
index de01771..b01493a 100644
--- a/src/p11_pkey.c
+++ b/src/p11_pkey.c
@@ -278,7 +278,7 @@ static int pkcs11_try_pkey_rsa_sign(EVP_PKEY_CTX *evp_pkey_ctx,
        CRYPTO_THREAD_write_lock(PRIVCTX(ctx)->rwlock);
        rv = CRYPTOKI_call(ctx,
                C_SignInit(spriv->session, &mechanism, kpriv->object));
-       if (kpriv->always_authenticate == CK_TRUE)
+       if ((rv == CKR_OK && kpriv->always_authenticate == CK_TRUE) || (rv == CKR_USER_NOT_LOGGED_IN))
                rv = pkcs11_authenticate(key);
        if (!rv)
                rv = CRYPTOKI_call(ctx,

For the 2nd one - solution I have in my fork works. Perhaps you could implement it.

Tested for RSA-PKCS1 and RSA-PSS. Here's HSM SPY:

$ OSSL-Tst5
Using OpenSSL v1.1.x
Using YubiHSM device...
Sign/verify using RSA PKCS1 padding


*************** OpenSC PKCS#11 spy *****************
Loaded: "/usr/local/lib/yubihsm_pkcs11.dylib"

0: C_GetFunctionList
2017-10-07 19:30:27.426
Returned:  0 CKR_OK

1: C_Initialize
2017-10-07 19:30:28.217
[in] pInitArgs = 0x7fdcecc1f2c0
     flags: 2
       CKF_OS_LOCKING_OK
Returned:  0 CKR_OK

2: C_GetSlotList
2017-10-07 19:30:28.364
[in] tokenPresent = 0x0
[out] pSlotList: 
Count is 1
[out] *pulCount = 0x1
Returned:  0 CKR_OK

3: C_GetSlotList
2017-10-07 19:30:28.364
[in] tokenPresent = 0x0
[out] pSlotList: 
Slot 0
[out] *pulCount = 0x1
Returned:  0 CKR_OK

4: C_GetSlotInfo
2017-10-07 19:30:28.396
[in] slotID = 0x0
[out] pInfo: 
      slotDescription:        'YubiHSM Connector 127.0.0.1     '
                              '                                '
      manufacturerID:         'Yubico                          '
      hardwareVersion:         0.200
      firmwareVersion:         0.200
      flags:                   7
        CKF_TOKEN_PRESENT                
        CKF_REMOVABLE_DEVICE             
        CKF_HW_SLOT                      
Returned:  0 CKR_OK

5: C_GetTokenInfo
2017-10-07 19:30:28.396
[in] slotID = 0x0
[out] pInfo: 
      label:                  'YubiHSM                         '
      manufacturerID:         'Yubico (www.yubico.com)         '
      model:                  'YubiHSM         '
      serialNumber:           'xxxxxxxxxxxx'
      ulMaxSessionCount:       0
      ulSessionCount:          -1
      ulMaxRwSessionCount:     0
      ulRwSessionCount:        -1
      ulMaxPinLen:             68
      ulMinPinLen:             12
      ulTotalPublicMemory:     -1
      ulFreePublicMemory:      -1
      ulTotalPrivateMemory:    -1
      ulFreePrivateMemory:     -1
      hardwareVersion:         0.200
      firmwareVersion:         0.200
      time:                   '               '
      flags:                   40d
        CKF_RNG                          
        CKF_LOGIN_REQUIRED               
        CKF_USER_PIN_INITIALIZED         
        CKF_TOKEN_INITIALIZED            
Returned:  0 CKR_OK

6: C_OpenSession
2017-10-07 19:30:28.405
[in] slotID = 0x0
[in] flags = 0x4
pApplication=0x0
Notify=0x0
[out] *phSession = 0x0
Returned:  0 CKR_OK

7: C_FindObjectsInit
2017-10-07 19:30:28.405
[in] hSession = 0x0
[in] pTemplate[1]: 
    CKA_CLASS             CKO_CERTIFICATE      
Returned:  0 CKR_OK

8: C_FindObjects
2017-10-07 19:30:28.405
[in] hSession = 0x0
[in] ulMaxObjectCount = 0x1
[out] ulObjectCount = 0x0
Returned:  0 CKR_OK
. . . . .
16: C_GetSessionInfo
2017-10-07 19:30:28.405
[in] hSession = 0x0
[out] pInfo: 
      slotID:                  0
      state:                  '           CKS_RO_PUBLIC_SESSION'
      flags:                   4
        CKF_SERIAL_SESSION               
      ulDeviceError:           0
Returned:  0 CKR_OK
Enter PKCS#11 token PIN for YubiHSM:

17: C_Login
2017-10-07 19:30:31.847
[in] hSession = 0x0
[in] userType = CKU_USER
[in] pPin[ulPinLen] 00007fdcecd05900 / 12
    00000000  XX XX XX XX XX . . . . .    
Returned:  0 CKR_OK

18: C_FindObjectsInit
2017-10-07 19:30:31.894
[in] hSession = 0x0
[in] pTemplate[1]: 
    CKA_CLASS             CKO_PRIVATE_KEY      
Returned:  0 CKR_OK
. . . . .
54: C_FindObjects
2017-10-07 19:30:31.963
[in] hSession = 0x0
[in] ulMaxObjectCount = 0x1
[out] ulObjectCount = 0x1
Object 0x30301 matches
Returned:  0 CKR_OK

55: C_GetAttributeValue
2017-10-07 19:30:31.963
[in] hSession = 0x0
[in] hObject = 0x30301
[in] pTemplate[1]: 
    CKA_KEY_TYPE          00007fff5e379908 / 8
[out] pTemplate[1]: 
    CKA_KEY_TYPE          CKK_RSA            
Returned:  0 CKR_OK

56: C_GetAttributeValue
2017-10-07 19:30:31.974
[in] hSession = 0x0
[in] hObject = 0x30301
[in] pTemplate[1]: 
    CKA_LABEL             0000000000000000 / 0
[out] pTemplate[1]: 
    CKA_LABEL             0000000000000000 / 7
Returned:  0 CKR_OK

57: C_GetAttributeValue
2017-10-07 19:30:31.974
[in] hSession = 0x0
[in] hObject = 0x30301
[in] pTemplate[1]: 
    CKA_LABEL             00007fdcecd05830 / 7
[out] pTemplate[1]: 
    CKA_LABEL             00007fdcecd05830 / 7
    52534153 69676E
     R S A S  i g n
Returned:  0 CKR_OK

58: C_GetAttributeValue
2017-10-07 19:30:31.974
[in] hSession = 0x0
[in] hObject = 0x30301
[in] pTemplate[1]: 
    CKA_ID                0000000000000000 / 0
[out] pTemplate[1]: 
    CKA_ID                0000000000000000 / 2
Returned:  0 CKR_OK
. . . . .
95: C_GetAttributeValue
2017-10-07 19:30:32.045
[in] hSession = 0x0
[in] hObject = 0x30301
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007fdcecd05e10 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  False
Returned:  0 CKR_OK

96: C_SignInit
2017-10-07 19:30:32.045
[in] hSession = 0x0
pMechanism->type=CKM_RSA_PKCS                 
[in] hKey = 0x30301
Returned:  0 CKR_OK

97: C_Sign
2017-10-07 19:30:32.046
[in] hSession = 0x0
[in] pData[ulDataLen] 00007fdcecc18770 / 32
    00000000  50 FD F1 74 27 45 FE AA 4A 19 63 E4 72 CF 58 C7  P..t'E..J.c.r.X.
    00000010  63 0E 26 BE 20 B5 99 35 E7 5D A1 F8 10 A4 21 58  c.&. ..5.]....!X
[out] pSignature[*pulSignatureLen] NULL [size : 0x180 (384)]
Returned:  0 CKR_OK

98: C_SignInit
2017-10-07 19:30:32.046
[in] hSession = 0x0
pMechanism->type=CKM_RSA_PKCS                 
[in] hKey = 0x30301
Returned:  144 CKR_OPERATION_ACTIVE

99: C_SignInit
2017-10-07 19:30:32.046
[in] hSession = 0x0
pMechanism->type=CKM_RSA_PKCS                 
[in] hKey = 0x30301
Returned:  144 CKR_OPERATION_ACTIVE

sign: failed to sign (rv=0)
140736337826752:error:8207A090:PKCS#11 module:pkcs11_private_encrypt:Operation active:p11_rsa.c:95:
Signing failed! (rv=0 olen=384)

And the same for PSS:

. . . . .
95: C_GetAttributeValue
2017-10-07 19:36:17.718
[in] hSession = 0x0
[in] hObject = 0x30301
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007f959c610cf0 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  False
Returned:  0 CKR_OK

96: C_SignInit
2017-10-07 19:36:17.719
[in] hSession = 0x0
pMechanism->type=CKM_RSA_PKCS_PSS             
pMechanism->pParameter->hashAlg=CKM_SHA256                   
pMechanism->pParameter->mgf=CKG_MGF1_SHA256
pMechanism->pParameter->sLen=350
[in] hKey = 0x30301
Returned:  0 CKR_OK

97: C_Sign
2017-10-07 19:36:17.720
[in] hSession = 0x0
[in] pData[ulDataLen] NULL [size : 0x20 (32)]
[out] pSignature[*pulSignatureLen] NULL [size : 0x180 (384)]
Returned:  0 CKR_OK

98: C_SignInit
2017-10-07 19:36:17.720
[in] hSession = 0x0
pMechanism->type=CKM_RSA_PKCS_PSS             
pMechanism->pParameter->hashAlg=CKM_SHA256                   
pMechanism->pParameter->mgf=CKG_MGF1_SHA256
pMechanism->pParameter->sLen=350
[in] hKey = 0x30301
Returned:  144 CKR_OPERATION_ACTIVE

99: C_SignInit
2017-10-07 19:36:17.720
[in] hSession = 0x0
pMechanism->type=CKM_RSA_X_509                
[in] hKey = 0x30301
Returned:  144 CKR_OPERATION_ACTIVE
/Users/uri/src/OSSL-Tst5/OSSL-Tst5/main.c:613 sign: failed to sign (rv=0)
140736337826752:error:8207A090:PKCS#11 module:pkcs11_private_encrypt:Operation active:p11_rsa.c:95:
Signing failed! (rv=0 olen=384)

This indicates that it still tried to re-authenticate. I know for sure that the keys on the HSM do not have the ALWAYS_AUTHENTICATE flag set.

Also, RSA-OAEP decryption on the HSM fails with the symptom that looks like the case out==NULL is not addressed. (Though OAEP is not implemented in your master yet? So why did the OAEP processing go this far...? Oh well...)

On a PIV token:

$ ~/openssl-1.1/bin/openssl dgst -engine pkcs11 -keyform engine -sign 'pkcs11:token=Uri%20the%20Great;id=%02;type=private' -sha384 -sigopt rsa_padding_mode:pss -out t6400.dat.sig t6400.dat
engine "pkcs11" set.
Enter PKCS#11 token PIN for Uri the Great:
Enter PKCS#11 key PIN for SIGN key:
Enter PKCS#11 key PIN for SIGN key:
$ 

OpenSSL manages to get the PIV token to sign, but I still consider this wrong. Prompting for the token key and then for the SIGN key is fine. But keeping prompting for the SIGN key...?! Here's the SPYL

$ ~/openssl-1.1/bin/openssl dgst -engine pkcs11 -keyform engine -sign 'pkcs11:token=Uri%20the%20Great;id=%02;type=private' -sha384 -sigopt rsa_padding_mode:pss -out t6400.dat.sig t6400.dat
. . . . .
100: C_GetAttributeValue
2017-10-07 20:17:42.534
[in] hSession = 0x7fe225f016a0
[in] hObject = 0x7fe225e04850
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007fe225c539c0 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  True
Returned:  0 CKR_OK

101: C_SignInit
2017-10-07 20:17:42.534
[in] hSession = 0x7fe225f016a0
pMechanism->type=CKM_RSA_PKCS_PSS             
pMechanism->pParameter->hashAlg=CKM_SHA384                   
pMechanism->pParameter->mgf=CKG_MGF1_SHA384
pMechanism->pParameter->sLen=206
[in] hKey = 0x7fe225e04850
Returned:  112 CKR_MECHANISM_INVALID
Enter PKCS#11 key PIN for SIGN key:

102: C_Login
2017-10-07 20:17:46.053
[in] hSession = 0x7fe225f016a0
[in] userType = CKU_CONTEXT_SPECIFIC
[in] pPin[ulPinLen] 00007fff547862a0 / 6
    00000000  31 32 33 34 35 36 37 38                                12345678          
Returned:  0 CKR_OK

103: C_Sign
2017-10-07 20:17:46.086
[in] hSession = 0x7fe225f016a0
[in] pData[ulDataLen] 00007fff54786470 / 48
    00000000  95 47 25 4E 39 66 45 10 44 AE D7 DB F1 45 84 0C  .G%N9fE.D....E..
    00000010  EF 10 18 EA DD 39 7E BE B0 7C FE 28 6F AC D6 75  .....9~..|.(o..u
    00000020  98 02 81 9A 24 F3 4B B7 25 0D C2 5A 23 19 AA 51  ....$.K.%..Z#..Q
Returned:  145 CKR_OPERATION_NOT_INITIALIZED

104: C_SignInit
2017-10-07 20:17:46.087
[in] hSession = 0x7fe225f016a0
pMechanism->type=CKM_RSA_X_509                
[in] hKey = 0x7fe225e04850
Returned:  0 CKR_OK
Enter PKCS#11 key PIN for SIGN key:

105: C_Login
2017-10-07 20:17:50.992
[in] hSession = 0x7fe225f016a0
[in] userType = CKU_CONTEXT_SPECIFIC
[in] pPin[ulPinLen] 00007fff54786160 / 8
    00000000  31 32 33 34 35 36 37 38                                12345678          
Returned:  0 CKR_OK

106: C_Sign
2017-10-07 20:17:51.024
[in] hSession = 0x7fe225f016a0
[in] pData[ulDataLen] 00007fe225c540c0 / 256
    00000000  21 58 9B CF 59 BE 83 EE CE BC E4 F5 98 53 CB B2  !X..Y........S..
    . . . . .
    000000F0  8A 62 9E DD 06 58 F4 4E 5E DB 8A D7 BD 37 40 BC  .b...X.N^....7@.
[out] pSignature[*pulSignatureLen] 00007fe226800000 / 256
    00000000  5E 62 DF 0B 1E 43 6C 76 B5 39 91 F0 D6 B5 F4 15  ^b...Clv.9......
    . . . . .
    000000F0  CA 3C 83 39 D1 94 2A A2 88 48 88 8F 7A 57 9A 4F  .<.9..*..H..zW.O
Returned:  0 CKR_OK

And this shows how PIV token that cannot do internal padding (supports raw RSA only) doesn't work any more:

$ OSSL-Tst5 neo
Using OpenSSL v1.1.x
Using YubiKey NEO device...
Sign/verify using RSA-PSS padding


*************** OpenSC PKCS#11 spy *****************
Loaded: "/Library/OpenSC/lib/opensc-pkcs11.dylib"

0: C_GetFunctionList
2017-10-07 20:12:12.987
Returned:  0 CKR_OK

1: C_GetFunctionList
2017-10-07 20:12:12.988
Returned:  0 CKR_OK

2: C_Initialize
2017-10-07 20:12:12.989
[in] pInitArgs = 0x7fe86d705580
     flags: 2
       CKF_OS_LOCKING_OK
Returned:  0 CKR_OK

3: C_GetSlotList
2017-10-07 20:12:13.772
[in] tokenPresent = 0x0
[out] pSlotList: 
Count is 1
[out] *pulCount = 0x1
Returned:  0 CKR_OK

4: C_GetSlotList
2017-10-07 20:12:13.773
[in] tokenPresent = 0x0
[out] pSlotList: 
Slot 0
[out] *pulCount = 0x1
Returned:  0 CKR_OK

5: C_GetSlotInfo
2017-10-07 20:12:13.774
[in] slotID = 0x0
[out] pInfo: 
      slotDescription:        'Yubico Yubikey NEO OTP+U2F+CCID '
                              '                                '
      manufacturerID:         'Yubico                          '
      hardwareVersion:         3.70
      firmwareVersion:         0.0
      flags:                   7
        CKF_TOKEN_PRESENT                
        CKF_REMOVABLE_DEVICE             
        CKF_HW_SLOT                      
Returned:  0 CKR_OK

6: C_GetTokenInfo
2017-10-07 20:12:13.776
[in] slotID = 0x0
[out] pInfo: 
      label:                  'Uri the Great                   '
      manufacturerID:         'piv_II                          '
      model:                  'PKCS#15 emulated'
      serialNumber:           'xxxxxxxxxxxxxx'
      ulMaxSessionCount:       0
      ulSessionCount:          0
      ulMaxRwSessionCount:     0
      ulRwSessionCount:        0
      ulMaxPinLen:             8
      ulMinPinLen:             4
      ulTotalPublicMemory:     -1
      ulFreePublicMemory:      -1
      ulTotalPrivateMemory:    -1
      ulFreePrivateMemory:     -1
      hardwareVersion:         0.0
      firmwareVersion:         0.0
      time:                   '                '
      flags:                   40d
        CKF_RNG                          
        CKF_LOGIN_REQUIRED               
        CKF_USER_PIN_INITIALIZED         
        CKF_TOKEN_INITIALIZED            
Returned:  0 CKR_OK

7: C_OpenSession
2017-10-07 20:12:13.806
[in] slotID = 0x0
[in] flags = 0x4
pApplication=0x0
Notify=0x0
[out] *phSession = 0x7fe86d517880
Returned:  0 CKR_OK

8: C_FindObjectsInit
2017-10-07 20:12:13.806
[in] hSession = 0x7fe86d517880
[in] pTemplate[1]: 
    CKA_CLASS             CKO_CERTIFICATE      
Returned:  0 CKR_OK
. . . . .
100: C_GetAttributeValue
2017-10-07 20:12:16.303
[in] hSession = 0x7fe86d517880
[in] hObject = 0x7fe86d50e7e0
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007fe86d518190 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  True
Returned:  0 CKR_OK

101: C_SignInit
2017-10-07 20:12:16.303
[in] hSession = 0x7fe86d517880
pMechanism->type=CKM_RSA_PKCS_PSS             
pMechanism->pParameter->hashAlg=CKM_SHA256                   
pMechanism->pParameter->mgf=CKG_MGF1_SHA256
pMechanism->pParameter->sLen=222
[in] hKey = 0x7fe86d50e7e0
Returned:  112 CKR_MECHANISM_INVALID
Enter PKCS#11 key PIN for SIGN key:

102: C_Login
2017-10-07 20:12:19.029
[in] hSession = 0x7fe86d517880
[in] userType = CKU_CONTEXT_SPECIFIC
[in] pPin[ulPinLen] 00007fff5a9a0a20 / 8
    00000000  31 32 33 34 35 36 37 38                                12345678          
Returned:  0 CKR_OK

103: C_Sign
2017-10-07 20:12:19.061
[in] hSession = 0x7fe86d517880
[in] pData[ulDataLen] NULL [size : 0x20 (32)]
Returned:  145 CKR_OPERATION_NOT_INITIALIZED
Segmentation fault: 11

Crash details:

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000010
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [0]

VM Regions Near 0x10:
--> 
    __TEXT                 000000010525e000-0000000105262000 [   16K] r-x/rwx SM=COW  /Users/USER/*

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_platform.dylib      	0x00007fffb29baeed _platform_memmove$VARIANT$Haswell + 77
1   libsystem_c.dylib             	0x00007fffb286342e __memcpy_chk + 22
2   libcrypto.1.1.dylib           	0x00000001054307c3 SHA256_Update + 403 (md32_common.h:290)
3   libcrypto.1.1.dylib           	0x00000001053b01ad update256 + 45 (m_sha1.c:130)
4   libcrypto.1.1.dylib           	0x0000000105396945 EVP_DigestUpdate + 53 (digest.c:148)
5   libcrypto.1.1.dylib           	0x00000001054103a4 RSA_padding_add_PKCS1_PSS_mgf1 + 660 (rsa_pss.c:211)
6   libcrypto.1.1.dylib           	0x000000010540e285 pkey_rsa_sign + 741 (rsa_pmeth.c:155)
7   pkcs11.dylib                  	0x00000001056e789f pkcs11_pkey_rsa_sign + 463 (p11_pkey.c:303)
8   libcrypto.1.1.dylib           	0x00000001053b43e7 EVP_PKEY_sign + 407 (pmeth_fn.c:66)
9   libcrypto.1.1.dylib           	0x00000001053b0a04 EVP_DigestSignFinal + 868 (m_sigver.c:139)
10  OSSL-Tst5                     	0x000000010525fac4 sign + 1652 (main.c:598)
11  OSSL-Tst5                     	0x000000010525ed8d main + 877 (main.c:155)
12  libdyld.dylib                 	0x00007fffb27a8235 start + 1

All of the above work fine with my branch/fork.

OpenSSL-1.1.0-stable with the proposed fix to (1):

~/openssl-1.1/bin/openssl dgst -engine pkcs11 -keyform engine -sign 'pkcs11:token=Uri%20the%20Great;id=%02;type=private' -sha384 -sigopt rsa_padding_mode:pss -out t6400.dat.sig t6400.dat
. . . . .
68: C_GetSessionInfo
2017-10-07 20:34:37.734
[in] hSession = 0x7ff68b409f30
[out] pInfo: 
      slotID:                  0
      state:                  '           CKS_RO_PUBLIC_SESSION'
      flags:                   4
        CKF_SERIAL_SESSION               
      ulDeviceError:           0
Returned:  0 CKR_OK
Enter PKCS#11 token PIN for Uri the Great:

69: C_Login
2017-10-07 20:34:39.985
[in] hSession = 0x7ff68b409f30
[in] userType = CKU_USER
[in] pPin[ulPinLen] 00007ff68b703490 / 8
    00000000  31 32 33 34 35 36 37 38                                12345678          
Returned:  0 CKR_OK

70: C_FindObjectsInit
2017-10-07 20:34:40.017
[in] hSession = 0x7ff68b409f30
[in] pTemplate[1]: 
    CKA_CLASS             CKO_PRIVATE_KEY      
Returned:  0 CKR_OK
. . . . .
100: C_GetAttributeValue
2017-10-07 20:34:40.018
[in] hSession = 0x7ff68b409f30
[in] hObject = 0x7ff68b6186b0
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007ff68b40a4a0 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  True
Returned:  0 CKR_OK

101: C_SignInit
2017-10-07 20:34:40.018
[in] hSession = 0x7ff68b409f30
pMechanism->type=CKM_RSA_PKCS_PSS             
pMechanism->pParameter->hashAlg=CKM_SHA384                   
pMechanism->pParameter->mgf=CKG_MGF1_SHA384
pMechanism->pParameter->sLen=206
[in] hKey = 0x7ff68b6186b0
Returned:  112 CKR_MECHANISM_INVALID

102: C_SignInit
2017-10-07 20:34:40.018
[in] hSession = 0x7ff68b409f30
pMechanism->type=CKM_RSA_X_509                
[in] hKey = 0x7ff68b6186b0
Returned:  0 CKR_OK
Enter PKCS#11 key PIN for SIGN key:

103: C_Login
2017-10-07 20:34:42.605
[in] hSession = 0x7ff68b409f30
[in] userType = CKU_CONTEXT_SPECIFIC
[in] pPin[ulPinLen] 00007fff502e3160 / 8
    00000000  31 32 33 34 35 36 37 38                                12345678          
Returned:  0 CKR_OK

104: C_Sign
2017-10-07 20:34:42.637
[in] hSession = 0x7ff68b409f30
[in] pData[ulDataLen] 00007ff68b706b60 / 256
    00000000  5C CF 55 89 E9 B0 03 67 E2 37 1F 93 C4 E2 C5 29  \.U....g.7.....)
    . . . . .
    000000F0  81 41 AA 49 AF 12 F2 59 BB 8D 26 49 D6 7F 28 BC  .A.I...Y..&I.(.
Returned:  0 CKR_OK

I can provide complete SPY for your master and for my fork, if needed - it's verbose but IMHO can be useful.

Here are excerpts for my fork:

$ 
OSSL-Tst5 neo
. . . . .
100: C_GetAttributeValue
2017-10-07 20:42:33.527
[in] hSession = 0x7f8b7051afb0
[in] hObject = 0x7f8b70708b10
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007f8b7051fbd0 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  True
Returned:  0 CKR_OK

101: C_SignInit
2017-10-07 20:42:33.527
[in] hSession = 0x7f8b7051afb0
pMechanism->type=CKM_RSA_PKCS_PSS             
pMechanism->pParameter->hashAlg=CKM_SHA256                   
pMechanism->pParameter->mgf=CKG_MGF1_SHA256
pMechanism->pParameter->sLen=222
[in] hKey = 0x7f8b70708b10
Returned:  112 CKR_MECHANISM_INVALID

102: C_SignInit
2017-10-07 20:42:33.527
[in] hSession = 0x7f8b7051afb0
pMechanism->type=CKM_RSA_X_509                
[in] hKey = 0x7f8b70708b10
Returned:  0 CKR_OK
Enter PKCS#11 key PIN for SIGN key:

103: C_Login
2017-10-07 20:42:38.737
[in] hSession = 0x7f8b7051afb0
[in] userType = CKU_CONTEXT_SPECIFIC
[in] pPin[ulPinLen] 00007fff5bf568d0 / 8
    00000000  xxxxxxxxx          
Returned:  0 CKR_OK

104: C_Sign
2017-10-07 20:42:38.770
[in] hSession = 0x7f8b7051afb0
[in] pData[ulDataLen] 00007f8b7040c0f0 / 256
    00000000  7C 93 C8 2C 41 FA 23 9B B1 9E B8 BD 63 77 75 9E  |..,A.#.....cwu.
    . . . . .
    000000F0  C6 E2 D5 06 12 8F 86 C9 6C 1A 4C 29 4F EB 51 BC  ........l.L)O.Q.
[out] pSignature[*pulSignatureLen] 00007f8b705202c0 / 256
    00000000  4A 4D 48 48 A4 56 2F AD DB A2 89 4B 85 D4 32 39  JMHH.V/....K..29
    . . . . .
    000000F0  47 1F D0 48 C1 70 EC 07 95 DB A6 41 7D 36 AA EA  G..H.p.....A}6..
Returned:  0 CKR_OK
Signed (data len=83, signature 256 bytes): rv=1
. . . . .
203: C_GetAttributeValue
2017-10-07 20:42:39.444
[in] hSession = 0x7f8b7051afb0
[in] hObject = 0x7f8b70708f80
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007f8b7051fd80 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  False
Returned:  0 CKR_OK

204: C_DecryptInit
2017-10-07 20:42:39.444
[in] hSession = 0x7f8b7051afb0
pMechanism->type=CKM_RSA_PKCS_OAEP            
pMechanism->pParameter->hashAlg=CKM_SHA_1                    
pMechanism->pParameter->mgf=CKG_MGF1_SHA1  
pMechanism->pParameter->source=0
[out] pSourceData[ulSourceDalaLen] NULL [size : 0x0 (0)]
[in] hKey = 0x7f8b70708f80
Returned:  112 CKR_MECHANISM_INVALID

205: C_DecryptInit
2017-10-07 20:42:39.444
[in] hSession = 0x7f8b7051afb0
pMechanism->type=CKM_RSA_X_509                
[in] hKey = 0x7f8b70708f80
Returned:  0 CKR_OK

206: C_Decrypt
2017-10-07 20:42:39.444
[in] hSession = 0x7f8b7051afb0
[in] pEncryptedData[ulEncryptedDataLen] 00007f8b705206f0 / 256
    00000000  6A E7 28 A2 66 10 46 61 C0 74 1C 38 9E 02 C0 75  j.(.f.Fa.t.8...u
    . . . . .
    000000F0  CF 26 76 1A 58 A4 A4 BE 84 69 F9 A1 3C 18 EC 9C  .&v.X....i..<...
[out] pData[*pulDataLen] 00007f8b70632a10 / 256
    00000000  00 5C 00 37 48 91 81 52 7B 88 C7 CC 19 D3 CD 39  .\.7H..R{......9
    . . . . .
    000000F0  B0 8B A8 36 39 4B E6 13 C3 DB 48 C2 C0 F1 86 2D  ...69K....H....-
Returned:  0 CKR_OK
Decrypted symmetric key (32 bytes):
28 40 d1 31 cd ba b8 0b f1 7e 79 44 fc cf 59 92 
51 e7 15 b7 20 f7 15 94 6b 45 44 99 2c 2e 4b 71 

Decrypted key matches the original.

And for HSM:

$ OSSL-Tst5
. . . . .
96: C_GetAttributeValue
2017-10-07 20:47:20.814
[in] hSession = 0x0
[in] hObject = 0x30301
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007f8736c194a0 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  False
Returned:  0 CKR_OK

97: C_SignInit
2017-10-07 20:47:20.814
[in] hSession = 0x0
pMechanism->type=CKM_RSA_PKCS_PSS             
pMechanism->pParameter->hashAlg=CKM_SHA256                   
pMechanism->pParameter->mgf=CKG_MGF1_SHA256
pMechanism->pParameter->sLen=350
[in] hKey = 0x30301
Returned:  0 CKR_OK

98: C_Sign
2017-10-07 20:47:20.815
[in] hSession = 0x0
[in] pData[ulDataLen] 00007fff50d19c00 / 32
    00000000  6E 9F BF FD 4C 0D 02 B4 4F 2F D1 1F 75 AD EE DB  n...L...O/..u...
    00000010  44 4B F6 FA 16 23 32 EB FA D3 21 E7 C0 B5 3C CA  DK...#2...!...<.
[out] pSignature[*pulSignatureLen] 00007f8736e09100 / 384
    00000000  0B CA BA 96 91 85 E7 3B 37 B0 F4 55 A0 44 78 17  .......;7..U.Dx.
    . . . . .
    00000170  AA 98 6A 81 51 96 58 3A 55 B4 F3 65 E7 55 BB D0  ..j.Q.X:U..e.U..
Returned:  0 CKR_OK
Signed (data len=83, signature 384 bytes): rv=1
. . . . .
234: C_GetAttributeValue
2017-10-07 20:47:21.480
[in] hSession = 0x0
[in] hObject = 0x22030302
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007f8736d06ee0 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  False
Returned:  0 CKR_OK

235: C_DecryptInit
2017-10-07 20:47:21.480
[in] hSession = 0x0
pMechanism->type=CKM_RSA_PKCS_OAEP            
pMechanism->pParameter->hashAlg=CKM_SHA_1                    
pMechanism->pParameter->mgf=CKG_MGF1_SHA1  
pMechanism->pParameter->source=0
[out] pSourceData[ulSourceDalaLen] NULL [size : 0x0 (0)]
[in] hKey = 0x22030302
Returned:  0 CKR_OK

236: C_Decrypt
2017-10-07 20:47:21.480
[in] hSession = 0x0
[in] pEncryptedData[ulEncryptedDataLen] 00007f8736f0ddc0 / 384
    00000000  9A AC 8D EB A0 88 AD 98 69 DB BA 66 E4 19 33 88  ........i..f..3.
    . . . . .
    00000170  0F CD 71 26 30 1D EF 4A 77 D9 44 B5 C7 46 13 C9  ..q&0..Jw.D..F..
[out] pData[*pulDataLen] 00007fff50d14c40 / 32
    00000000  E1 73 41 B8 1F A9 24 5B 9E C3 AE 22 CA 8F 76 54  .sA...$[..."..vT
    00000010  43 CE DC 3A 37 DE 86 8A 76 9E 1A 33 AF 49 70 C3  C..:7...v..3.Ip.
Returned:  0 CKR_OK
Decrypted symmetric key (32 bytes):
e1 73 41 b8 1f a9 24 5b 9e c3 ae 22 ca 8f 76 54 
43 ce dc 3a 37 de 86 8a 76 9e 1a 33 af 49 70 c3 

Decrypted key matches the original.


237: C_CloseSession
2017-10-07 20:47:21.991
[in] hSession = 0x0
Returned:  0 CKR_OK

OpenSSL crypto demo completed.

@dengert
Copy link
Member

dengert commented Oct 8, 2017

@mouse07410
Did you do this line as suggest by the OpenSSL people:
EVP_PKEY_meth_new(EVP_PKEY_RSA, EVP_PKEY_FLAG_AUTOARGLEN)
If you did then the OSSL_test would never request the length of the output buffer.
The buffer size would have been handled before the first C_SignInit.
see: #176 (comment)

PKCS#11 2.40 Section 5.11:
"The signing operation MUST have been initialized with C_SignInit. A call to C_Sign always terminates
the active signing operation unless it returns CKR_BUFFER_TOO_SMALL or is a successful call (i.e.,
one which returns CKR_OK) to determine the length of the buffer needed to hold the signature.
C_Sign cannot be used to terminate a multi-part operation, and MUST be called after C_SignInit without
intervening C_SignUpdate calls."

Also see 5.2 Conventions for functions returning output in a variable-length buffer

SPY trace 97: C_Sign is a successful call (i.e.,one which returns CKR_OK) to determine the length of the buffer needed to hold the signature. The above says the session stays active.

But the SPY Trace 98: C_SignInit tries to use the active session and returns CKR_OPERATION_ACTIVE
99: C_SignInit retries the operation and also fails with CKR_OPERATION_ACTIVE

I do not see a cancel operation function. It appears the calling application should have allocated the buffer then called C_Sign to continue the operation, not call C_SignInit to start over.

I would suspect that the OpenSC PKCS#11 module may have allowed C_SignInit be called twice to in effect cancel the previous operation. But the Yubico module does not.

So this is a gray area in the PKCS#11 documentation: No way to cancel an operation.

An application or libp11 needs to address a sign operation with the buffer == NULL and somehow not restart the operation with C_SignInit , but go right to the C_Sign.

@mouse07410
Copy link
Contributor Author

@mouse07410 Did you do this line as suggest by the OpenSSL people: EVP_PKEY_meth_new(EVP_PKEY_RSA, EVP_PKEY_FLAG_AUTOARGLEN)

@dengert in my code - yes I did, as you suggested. And I also kept all the necessary handling of out==NULL for OAEP and sig==NULL for PKCS1 and PSS (to deal with the case that the above flag for whatever reason is not set).

But I don't see this flag set in the master. The master does not seem to create a new pmeth blob, at least explicitly...

Also, I suspect that the streamlining that @mtrojnar did, affected how the repeated calls and fallback are done, which probably causes the failing attempts to re-initalize the session that at least this HSM (and PIV) refuse to do. I might be able to try this with CAC next week, but you seem to be right on the money here:

...this is a gray area in the PKCS#11 documentation: No way to cancel an operation.

I would suspect that the OpenSC PKCS#11 module may have allowed C_SignInit be called twice to in effect cancel the previous operation. But the Yubico module does not.

An application or libp11 needs to address a sign operation with the buffer == NULL and somehow not restart the operation with C_SignInit , but go right to the C_Sign.

Exactly. And your proof-of-concept code that I polished (https://github.com/mouse07410/libp11/tree/rsa-oaep-prep) did exactly that, and works fine.

mtrojnar added a commit that referenced this issue Oct 8, 2017
@mtrojnar
Copy link
Member

mtrojnar commented Oct 8, 2017

@mouse07410 You are right: I indeed haven't started implementing OAEP yet. AFAIR in fact this feature wasn't even requested (or maybe it was requested somewhere deep within the PSS feature request)...

@mouse07410
Copy link
Contributor Author

mouse07410 commented Oct 8, 2017

Signature appears to be fixed for HSM but remains broken for PIV. And using OpenSSL with PIV, it prompts for the SIGN key twice, after it prompted for the token key.

I think HSM support is good, but the fallback remains broken, which is why PIV doesn't work.

On PIV, for PKCS1 signature it does sign, but the created signature fails verification:

. . . . .
140736337826752:error:04091068:rsa routines:int_rsa_verify:bad signature:crypto/rsa/rsa_sign.c:220:
Verification failed! (rv=0 olen=256)

For PSS signature on PIV, it just fails and crashes:

99: C_GetAttributeValue
2017-10-08 06:09:22.309
[in] hSession = 0x7fb592c3c410
[in] hObject = 0x7fb592c34170
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007fb592c3c740 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  True
Returned:  0 CKR_OK

100: C_SignInit
2017-10-08 06:09:22.309
[in] hSession = 0x7fb592c3c410
pMechanism->type=CKM_RSA_PKCS_PSS             
pMechanism->pParameter->hashAlg=CKM_SHA256                   
pMechanism->pParameter->mgf=CKG_MGF1_SHA256
pMechanism->pParameter->sLen=222
[in] hKey = 0x7fb592c34170
Returned:  112 CKR_MECHANISM_INVALID
Enter PKCS#11 key PIN for SIGN key:

101: C_Login
2017-10-08 06:09:26.272
[in] hSession = 0x7fb592c3c410
[in] userType = CKU_CONTEXT_SPECIFIC
[in] pPin[ulPinLen] 00007fff57e47a20 / 8
    00000000  31 32 33 34 35 36 37 38                                12345678          
Returned:  0 CKR_OK

102: C_Sign
2017-10-08 06:09:26.305
[in] hSession = 0x7fb592c3c410
[in] pData[ulDataLen] NULL [size : 0x20 (32)]
Returned:  145 CKR_OPERATION_NOT_INITIALIZED
Segmentation fault: 11

with the crash report:

Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000010
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [0]

VM Regions Near 0x10:
--> 
    __TEXT                 0000000107db7000-0000000107dbb000 [   16K] r-x/rwx SM=COW  /Users/USER/*

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_platform.dylib      	0x00007fffb29baeed _platform_memmove$VARIANT$Haswell + 77
1   libsystem_c.dylib             	0x00007fffb286342e __memcpy_chk + 22
2   libcrypto.1.1.dylib           	0x0000000107f8a7c3 SHA256_Update + 403 (md32_common.h:290)
3   libcrypto.1.1.dylib           	0x0000000107f0a1ad update256 + 45 (m_sha1.c:130)
4   libcrypto.1.1.dylib           	0x0000000107ef0945 EVP_DigestUpdate + 53 (digest.c:148)
5   libcrypto.1.1.dylib           	0x0000000107f6a3a4 RSA_padding_add_PKCS1_PSS_mgf1 + 660 (rsa_pss.c:211)
6   libcrypto.1.1.dylib           	0x0000000107f68285 pkey_rsa_sign + 741 (rsa_pmeth.c:155)
7   pkcs11.dylib                  	0x0000000108245899 pkcs11_pkey_rsa_sign + 489 (p11_pkey.c:312)
8   libcrypto.1.1.dylib           	0x0000000107f0e3e7 EVP_PKEY_sign + 407 (pmeth_fn.c:66)
9   libcrypto.1.1.dylib           	0x0000000107f0aa04 EVP_DigestSignFinal + 868 (m_sigver.c:139)
10  OSSL-Tst5                     	0x0000000107db8ac4 sign + 1652 (main.c:598)
11  OSSL-Tst5                     	0x0000000107db7d8d main + 877 (main.c:155)
12  libdyld.dylib                 	0x00007fffb27a8235 start + 1

On the good side, here's the good logs from HSM:

$ OSSL-Tst5
. . . . .
95: C_GetAttributeValue
2017-10-08 06:15:34.640
[in] hSession = 0x0
[in] hObject = 0x30301
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007f9fd763a1c0 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  False
Returned:  0 CKR_OK

96: C_SignInit
2017-10-08 06:15:34.640
[in] hSession = 0x0
pMechanism->type=CKM_RSA_PKCS                 
[in] hKey = 0x30301
Returned:  0 CKR_OK

97: C_Sign
2017-10-08 06:15:34.642
[in] hSession = 0x0
[in] pData[ulDataLen] 00007f9fd7500020 / 32
    00000000  29 85 12 C9 0B D7 A7 63 E5 E2 8C A3 F5 2A A0 C3  )......c.....*..
    00000010  86 F7 08 15 84 2B 86 20 67 BA 45 AD D9 0E 5D F9  .....+. g.E...].
[out] pSignature[*pulSignatureLen] NULL [size : 0x180 (384)]
Returned:  0 CKR_OK

98: C_Sign
2017-10-08 06:15:34.642
[in] hSession = 0x0
[in] pData[ulDataLen] 00007f9fd7500020 / 32
    00000000  29 85 12 C9 0B D7 A7 63 E5 E2 8C A3 F5 2A A0 C3  )......c.....*..
    00000010  86 F7 08 15 84 2B 86 20 67 BA 45 AD D9 0E 5D F9  .....+. g.E...].
[out] pSignature[*pulSignatureLen] 00007f9fd7515c60 / 384
    00000000  53 53 CB 9C FA 32 98 E3 E5 23 DC 93 D4 D4 2D AD  SS...2...#....-.
    . . . . .
    00000170  E0 1A D4 8A C9 21 96 EB 1D D4 80 37 EF 34 EE 15  .....!.....7.4..
Returned:  0 CKR_OK
Signed (data len=32, signature 384 bytes): rv=1
. . . . .
200: C_SignInit
2017-10-08 06:15:35.228
[in] hSession = 0x0
pMechanism->type=CKM_RSA_PKCS_PSS             
pMechanism->pParameter->hashAlg=CKM_SHA256                   
pMechanism->pParameter->mgf=CKG_MGF1_SHA256
pMechanism->pParameter->sLen=350
[in] hKey = 0x30301
Returned:  0 CKR_OK

201: C_Sign
2017-10-08 06:15:35.228
[in] hSession = 0x0
[in] pData[ulDataLen] NULL [size : 0x20 (32)]
[out] pSignature[*pulSignatureLen] NULL [size : 0x180 (384)]
Returned:  0 CKR_OK

202: C_Sign
2017-10-08 06:15:35.228
[in] hSession = 0x0
[in] pData[ulDataLen] 00007fff5c6cfc00 / 32
    00000000  69 BD 98 2B 48 8B 2A C1 6B 36 FC 10 5C 81 63 26  i..+H.*.k6..\.c&
    00000010  75 5A 47 86 29 3A 43 BD 5A D4 A9 A2 D9 DE D6 2C  uZG.):C.Z......,
[out] pSignature[*pulSignatureLen] 00007f9fd741eb90 / 384
    00000000  7E 06 73 A8 D9 C2 D7 37 BB 16 2D 92 A3 C7 A8 93  ~.s....7..-.....
    . . . . .
    00000170  E3 59 BB 82 77 7E E7 A7 FA D6 0A 06 67 C3 65 CA  .Y..w~......g.e.
Returned:  0 CKR_OK
Signed (data len=83, signature 384 bytes): rv=1

AFAIR in fact this feature wasn't even requested (or maybe it was requested somewhere deep within the PSS feature request)...

Please consider the request submitted. ;-)

P.S. OpenSSL-1.0.2-stable added the get methods for the struct evp_pkey_method_st members.

@mtrojnar
Copy link
Member

mtrojnar commented Oct 8, 2017

Please consider opening a new issue, so that we can prioritize and track your request.

@mouse07410
Copy link
Contributor Author

Please consider opening a new issue, so that we can prioritize and track your request.

Thanks, done: #180

@mouse07410
Copy link
Contributor Author

mouse07410 commented Oct 8, 2017

Update

With this change

diff --git a/src/p11_pkey.c b/src/p11_pkey.c
index fb7d84c..16d69e4 100644
--- a/src/p11_pkey.c
+++ b/src/p11_pkey.c
@@ -283,7 +283,7 @@ static int pkcs11_try_pkey_rsa_sign(EVP_PKEY_CTX *evp_pkey_ctx,
                CRYPTO_THREAD_write_lock(cpriv->rwlock);
                rv = CRYPTOKI_call(ctx,
                        C_SignInit(spriv->session, &mechanism, kpriv->object));
-               if (kpriv->always_authenticate == CK_TRUE)
+               if ((rv == CKR_OK || rv == CKR_USER_NOT_LOGGED_IN) && kpriv->always_authenticate == CK_TRUE)
                        rv = pkcs11_authenticate(key);
        }
        if (!rv)

it stops prompting for the PIN unnecessarily.

Update 2

After tweaking the test-code, and with the above change:

  1. HSM PKCS1 signature works.
  2. HSM PSS signature works.
  3. PIV PKCS1 signature is created bad - verification fails.
  4. PIV PSS signature fails (see crash report below).
Exception Type:        EXC_BAD_ACCESS (SIGSEGV)
Exception Codes:       KERN_INVALID_ADDRESS at 0x0000000000000010
Exception Note:        EXC_CORPSE_NOTIFY

Termination Signal:    Segmentation fault: 11
Termination Reason:    Namespace SIGNAL, Code 0xb
Terminating Process:   exc handler [0]

VM Regions Near 0x10:
--> 
    __TEXT                 0000000104b81000-0000000104b86000 [   20K] r-x/rwx SM=COW  /Users/USER/*

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_platform.dylib      	0x00007fffb29baeed _platform_memmove$VARIANT$Haswell + 77
1   libsystem_c.dylib             	0x00007fffb286342e __memcpy_chk + 22
2   libcrypto.1.1.dylib           	0x0000000104d557c3 SHA256_Update + 403 (md32_common.h:290)
3   libcrypto.1.1.dylib           	0x0000000104cd51ad update256 + 45 (m_sha1.c:130)
4   libcrypto.1.1.dylib           	0x0000000104cbb945 EVP_DigestUpdate + 53 (digest.c:148)
5   libcrypto.1.1.dylib           	0x0000000104d353a4 RSA_padding_add_PKCS1_PSS_mgf1 + 660 (rsa_pss.c:211)
6   libcrypto.1.1.dylib           	0x0000000104d33285 pkey_rsa_sign + 741 (rsa_pmeth.c:155)
7   pkcs11.dylib                  	0x000000010500b8aa pkcs11_pkey_rsa_sign + 538 (p11_pkey.c:312)
8   libcrypto.1.1.dylib           	0x0000000104cd93e7 EVP_PKEY_sign + 407 (pmeth_fn.c:66)
9   libcrypto.1.1.dylib           	0x0000000104cd5a04 EVP_DigestSignFinal + 868 (m_sigver.c:139)
10  OSSL-Tst5                     	0x0000000104b836fa sign + 1738 (main.c:639)
11  OSSL-Tst5                     	0x0000000104b8297d main + 877 (main.c:155)
12  libdyld.dylib                 	0x00007fffb27a8235 start + 1

mtrojnar added a commit that referenced this issue Oct 8, 2017
CKU_CONTEXT_SPECIFIC logins should not be performed after
an unsuccessful initialization.  This bug surfaced in #178.
@mtrojnar
Copy link
Member

mtrojnar commented Oct 8, 2017

@mouse07410 You are (mostly) right. In case C_SignInit() returns CKR_USER_NOT_LOGGED_IN, pkcs11_authenticate() would not help, because pkcs11_authenticate() only handles CKU_CONTEXT_SPECIFIC logins.
Signature initialization should never return CKR_USER_NOT_LOGGED_IN anyway, as a CKA_PRIVATE key handle is only returned after a successful login.

I also fixed the other occurrences of this bug.

@mouse07410
Copy link
Contributor Author

mouse07410 commented Oct 8, 2017

@mtrojnar I agree, and thanks for fixing this in other places as well.

Current status:

  • HSM signatures appear to work, RSA-PKCS1 and RSA-PSS.
  • PIV still broken. RSA-PKCS1 signature is created OK but fails verification, and attempts to make an RSA-PSS signature crash the program. Something with fallback remains broken.

Also, is there a possibility that somewhere in your code the engine misses the opportunity to set EVP_PKEY_FLAG_AUTOARGLEN flag? Would be nice to try setting it and observing if it makes a difference (as I hope it would)?

@mtrojnar
Copy link
Member

mtrojnar commented Oct 8, 2017

@mouse07410 Could you please capture some PIV SPY traces with the current master branch?

mtrojnar added a commit that referenced this issue Oct 8, 2017
@mouse07410
Copy link
Contributor Author

First, I do not observe crashes any more. RSA-PSS seems to work on PIV tokens now:

$ ~/openssl-1.1/bin/openssl dgst -engine pkcs11 -keyform engine -sign 'pkcs11:token=Uri%20the%20Great;id=%02;type=private' -sha256 -sigopt rsa_padding_mode:pss -out t6400.dat.sig t6400.dat
engine "pkcs11" set.
Enter PKCS#11 token PIN for Uri the Great:
Enter PKCS#11 key PIN for SIGN key:
$ ~/openssl-1.1/bin/openssl dgst -engine pkcs11 -keyform engine -verify 'pkcs11:token=Uri%20the%20Great;id=%02;type=public' -sha256 -sigopt rsa_padding_mode:pss -signature t6400.dat.sig t6400.dat
engine "pkcs11" set.
Verified OK
$

RSA-PKCS1 still produces bad signatures:

$ OSSL-Tst5 neo
Using OpenSSL v1.1.x
Using YubiKey NEO device...
Sign/verify using RSA PKCS1 padding


*************** OpenSC PKCS#11 spy *****************
Loaded: "/Library/OpenSC/lib/opensc-pkcs11.dylib"

0: C_GetFunctionList
2017-10-08 13:47:36.774
Returned:  0 CKR_OK

1: C_Initialize
2017-10-08 13:47:36.776
[in] pInitArgs = 0x7fb809613280
     flags: 2
$ OSSL-Tst5 neo
Using OpenSSL v1.1.x
Using YubiKey NEO device...
Sign/verify using RSA PKCS1 padding


*************** OpenSC PKCS#11 spy *****************
Loaded: "/Library/OpenSC/lib/opensc-pkcs11.dylib"

0: C_GetFunctionList
2017-10-08 13:47:36.774
Returned:  0 CKR_OK

1: C_Initialize
2017-10-08 13:47:36.776
[in] pInitArgs = 0x7fb809613280
     flags: 2
       CKF_OS_LOCKING_OK
Returned:  0 CKR_OK
. . . . .

4: C_GetSlotInfo
2017-10-08 13:47:37.675
[in] slotID = 0x0
[out] pInfo: 
      slotDescription:        'Yubico Yubikey NEO OTP+U2F+CCID '
                              '                                '
      manufacturerID:         'Yubico                          '
      hardwareVersion:         3.70
      firmwareVersion:         0.0
      flags:                   7
        CKF_TOKEN_PRESENT                
        CKF_REMOVABLE_DEVICE             
        CKF_HW_SLOT                      
Returned:  0 CKR_OK

5: C_GetTokenInfo
2017-10-08 13:47:37.677
[in] slotID = 0x0
[out] pInfo: 
      label:                  'Uri the Great                   '
      manufacturerID:         'piv_II                          '
      model:                  'PKCS#15 emulated'
      serialNumber:           'xxxxxxxxxxxxxxxx'
      ulMaxSessionCount:       0
      ulSessionCount:          0
      ulMaxRwSessionCount:     0
      ulRwSessionCount:        0
      ulMaxPinLen:             8
      ulMinPinLen:             4
      ulTotalPublicMemory:     -1
      ulFreePublicMemory:      -1
      ulTotalPrivateMemory:    -1
      ulFreePrivateMemory:     -1
      hardwareVersion:         0.0
      firmwareVersion:         0.0
      time:                   '                '
      flags:                   40d
        CKF_RNG                          
        CKF_LOGIN_REQUIRED               
        CKF_USER_PIN_INITIALIZED         
        CKF_TOKEN_INITIALIZED            
Returned:  0 CKR_OK

6: C_OpenSession
2017-10-08 13:47:37.714
[in] slotID = 0x0
[in] flags = 0x4
pApplication=0x0
Notify=0x0
[out] *phSession = 0x7fb809428960
Returned:  0 CKR_OK
. . . . .

67: C_GetSessionInfo
2017-10-08 13:47:37.720
[in] hSession = 0x7fb809428960
[out] pInfo: 
      slotID:                  0
      state:                  '           CKS_RO_PUBLIC_SESSION'
      flags:                   4
        CKF_SERIAL_SESSION               
      ulDeviceError:           0
Returned:  0 CKR_OK
Enter PKCS#11 token PIN for Uri the Great:

68: C_Login
2017-10-08 13:47:40.819
[in] hSession = 0x7fb809428960
[in] userType = CKU_USER
[in] pPin[ulPinLen] 00007fb8096141f0 / 8
    00000000  31 32 33 34 35 36 37 38                                12345678          
Returned:  0 CKR_OK

69: C_FindObjectsInit
2017-10-08 13:47:40.851
[in] hSession = 0x7fb809428960
[in] pTemplate[1]: 
    CKA_CLASS             CKO_PRIVATE_KEY      
Returned:  0 CKR_OK
. . . . .

99: C_GetAttributeValue
2017-10-08 13:47:40.852
[in] hSession = 0x7fb809428960
[in] hObject = 0x7fb809420070
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007fb809614510 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  True
Returned:  0 CKR_OK

100: C_SignInit
2017-10-08 13:47:40.852
[in] hSession = 0x7fb809428960
pMechanism->type=CKM_RSA_PKCS                 
[in] hKey = 0x7fb809420070
Returned:  0 CKR_OK
Enter PKCS#11 key PIN for SIGN key:

101: C_Login
2017-10-08 13:47:43.866
[in] hSession = 0x7fb809428960
[in] userType = CKU_CONTEXT_SPECIFIC
[in] pPin[ulPinLen] 00007fff5414aac0 / 6
    00000000  31 32 33 34 35 36 37 38                                12345678          
Returned:  0 CKR_OK

102: C_Sign
2017-10-08 13:47:43.899
[in] hSession = 0x7fb809428960
[in] pData[ulDataLen] 00007fb809600000 / 32
    00000000  20 AE 85 79 CD 8A D0 29 55 7E D0 0D 83 C7 12 8F   ..y...)U~......
    00000010  6B 5E 91 5E F0 58 51 82 E4 78 2B 6C 83 5A 7A E7  k^.^.XQ..x+l.Zz.
[out] pSignature[*pulSignatureLen] 00007fb809614c60 / 256
    00000000  84 0A BD 44 32 81 0B AB 27 8F A8 C8 91 D7 6E 2D  ...D2...'.....n-
    00000010  11 30 73 F0 A0 5C 88 54 A8 48 75 AD 92 AB DE B7  .0s..\.T.Hu.....
    00000020  5E 79 F9 BC 4D F3 A7 0B 41 10 E6 D4 8D D6 5E 16  ^y..M...A.....^.
    00000030  9C D5 65 D5 86 8F 15 DB E9 19 EA CA 75 01 95 E6  ..e.........u...
    00000040  F6 4C C7 2C CC 57 8D C6 22 FF AD BF 72 D5 C2 C1  .L.,.W.."...r...
    00000050  9B FC 9A 62 CA EA E7 16 49 8C D2 C7 65 50 2D 02  ...b....I...eP-.
    00000060  10 E6 6E 1C 80 86 BE 39 6F B7 67 96 6C A6 82 EB  ..n....9o.g.l...
    00000070  C8 4F 19 D4 09 87 10 33 42 D9 BD F0 9E AB 7F 8C  .O.....3B......
    00000080  07 6E 7B 43 CA 4E 96 26 B9 BF 5F 0E 76 43 1F 20  .n{C.N.&.._.vC. 
    00000090  BC 99 4E D9 9B 25 CB E7 6D A1 7D 8B 27 8B 2F 0D  ..N..%..m.}.'./.
    000000A0  D7 42 57 8F 9E A4 B5 02 36 85 BA 59 6C C3 5C 16  .BW.....6..Yl.\.
    000000B0  AF C1 7E 03 7F B2 E7 EB 00 E6 AE 23 5A AA D2 84  ..~.......#Z...
    000000C0  3C CA 7A 59 60 67 2A 15 AF 6D 02 A8 E2 F4 28 9B  <.zY`g*..m....(.
    000000D0  EF C2 AB E3 AA 2B 2D 90 A7 D9 10 13 49 1E 37 FD  .....+-.....I.7.
    000000E0  D2 D2 A9 6B 28 37 EB 5A DC 7A 9E 3B 89 D0 34 67  ...k(7.Z.z.;..4g
    000000F0  3C F0 38 77 40 4B 00 FB 29 0B 9B 7F 4F 5A CF 4E  <.8w@K..)..OZ.N
Returned:  0 CKR_OK
Signed (data len=32, signature 256 bytes): rv=1
. . . . .

146: C_GetAttributeValue
2017-10-08 13:47:44.578
[in] hSession = 0x7fb809428960
[in] hObject = 0x7fb8094201f0
[in] pTemplate[1]: 
    CKA_MODULUS           00007fb80942ab70 / 256
[out] pTemplate[1]: 
    CKA_MODULUS           00007fb80942ab70 / 256
    00000000  BF 03 6F 94 56 56 89 D1 91 8B 1D F5 63 7F 8F 5C  ..o.VV......c.\
    00000010  94 09 0D 67 0D C4 A8 B3 AB 6D 94 4C 03 67 4E 4D  ...g.....m.L.gNM
    00000020  B6 1D 3B 2A 55 9B 13 86 49 96 9F C1 0E AE 65 70  ..;*U...I.....ep
    00000030  51 48 FD E2 EB 4C 33 1D 9F 3A 57 75 8A 3D 5F 0E  QH...L3..:Wu.=_.
    00000040  34 FA 76 85 31 43 FC 87 F1 D4 6B 04 2A FE 54 3F  4.v.1C....k.*.T?
    00000050  85 C1 A2 1A AD 93 3A 8A 94 22 BD 9F 4A 20 EA FB  ......:.."..J ..
    00000060  97 34 89 96 B9 C8 44 B2 C2 6A C8 E6 72 40 55 FB  .4....D..j..r@U.
    00000070  CF BF D0 89 51 95 7A 70 1F 6B 94 0B A0 96 48 AD  ....Q.zp.k....H.
    00000080  C6 E2 80 BA 7D 63 C1 08 6B F4 8C 92 AD 48 E1 BF  ....}c..k....H..
    00000090  64 76 D3 6E BC 7E 12 58 EA A2 FA 67 21 CF A6 3D  dv.n.~.X...g!..=
    000000A0  07 F1 B3 54 EA 94 8F 10 66 C0 7C 30 ED 5C 42 B0  ...T....f.|0.\B.
    000000B0  9A 15 02 2E 71 C4 77 4E D9 9F 12 56 2E 18 15 0B  ....q.wN...V....
    000000C0  05 A2 84 5F 7A 67 E0 13 2C A8 8B 77 54 19 20 48  ..._zg..,..wT. H
    000000D0  C4 5A A8 D0 17 42 4A 6D 73 75 AF 97 D1 71 44 7D  .Z...BJmsu...qD}
    000000E0  F9 F8 A8 D8 E5 34 49 C0 FB 32 37 AE A6 60 F5 4A  .....4I..27..`.J
    000000F0  52 ED EC EA 97 83 46 D9 0A 34 51 19 60 BD 5E EB  R.....F..4Q.`.^.
Returned:  0 CKR_OK

147: C_GetAttributeValue
2017-10-08 13:47:44.578
[in] hSession = 0x7fb809428960
[in] hObject = 0x7fb8094201f0
[in] pTemplate[1]: 
    CKA_PUBLIC_EXPONENT   0000000000000000 / 0
[out] pTemplate[1]: 
    CKA_PUBLIC_EXPONENT   0000000000000000 / 3
Returned:  0 CKR_OK

148: C_GetAttributeValue
2017-10-08 13:47:44.578
[in] hSession = 0x7fb809428960
[in] hObject = 0x7fb8094201f0
[in] pTemplate[1]: 
    CKA_PUBLIC_EXPONENT   00007fb809429a00 / 3
[out] pTemplate[1]: 
    CKA_PUBLIC_EXPONENT   00007fb809429a00 / 3
    00000000  01 00 01                                         ...             
Returned:  0 CKR_OK
140736337826752:error:04091068:rsa routines:int_rsa_verify:bad signature:crypto/rsa/rsa_sign.c:220:
Verification failed! (rv=0 olen=256)
. . . . .

171: C_SignInit
2017-10-08 13:47:44.580
[in] hSession = 0x7fb809428960
pMechanism->type=CKM_RSA_PKCS_PSS             
pMechanism->pParameter->hashAlg=CKM_SHA256                   
pMechanism->pParameter->mgf=CKG_MGF1_SHA256
pMechanism->pParameter->sLen=222
[in] hKey = 0x7fb809420070
Returned:  112 CKR_MECHANISM_INVALID

172: C_SignInit
2017-10-08 13:47:44.580
[in] hSession = 0x7fb809428960
pMechanism->type=CKM_RSA_X_509                
[in] hKey = 0x7fb809420070
Returned:  0 CKR_OK
Enter PKCS#11 key PIN for SIGN key:

173: C_Login
2017-10-08 13:47:56.808
[in] hSession = 0x7fb809428960
[in] userType = CKU_CONTEXT_SPECIFIC
. . . . .
Returned:  0 CKR_OK

174: C_Sign
2017-10-08 13:47:56.841
[in] hSession = 0x7fb809428960
[in] pData[ulDataLen] 00007fb80953a830 / 256
    00000000  59 37 26 6A D2 85 7A 12 DB 6F 45 76 18 2C 9C 7E  Y7&j..z..oEv.,.~
    00000010  02 56 EE 45 31 58 15 66 A2 6F 45 4B 4B 63 46 5D  .V.E1X.f.oEKKcF]
    00000020  24 A6 09 DF 17 20 EF 51 D1 8E 44 97 F8 E7 61 7A  $.... .Q..D...az
    00000030  74 B7 AE 44 BC 76 81 67 EF 77 EA A0 C8 91 52 C4  t..D.v.g.w....R.
    00000040  BC A5 03 AF 52 81 5E 55 DE 75 B2 05 FF 1D 1D A7  ....R.^U.u......
    00000050  DB 63 C5 09 2E AF 90 89 C9 3C D0 3A 33 39 65 AA  .c.......<.:39e.
    00000060  C6 A1 CE 3D D4 91 B3 4B 5F BF 74 A8 0B 8E 4C 63  ...=...K_.t...Lc
    00000070  3E 1E D0 07 F4 3E ED 99 35 F2 83 C3 4E 3C 61 5B  >....>..5...N<a[
    00000080  07 99 F9 20 3C C7 86 13 C8 B3 79 77 0A 5A 86 66  ... <.....yw.Z.f
    00000090  C4 76 93 4B 99 CC 9A CC E5 63 70 92 8B 04 DA 82  .v.K.....cp.....
    000000A0  CA CF 24 0F D6 8C B0 97 C3 CF 90 7E E8 41 7E 94  ..$........~.A~.
    000000B0  8B 2A B6 61 C6 A8 72 FC CD 17 56 44 B2 17 FE E6  .*.a..r...VD....
    000000C0  BC 95 CD 20 FE 18 4F 00 A6 43 99 D4 41 D6 6F 14  ... ..O..C..A.o.
    000000D0  19 CB A2 5E 4E 9A B1 91 32 19 73 AF B3 4B E0 3F  ...^N...2.s..K.?
    000000E0  B6 AC 05 0D C1 AE 28 35 3F 5B 92 10 D0 08 D7 9A  ......(5?[......
    000000F0  0C 96 74 69 75 B8 A8 6E 30 D2 B7 6E E9 27 A6 BC  ..tiu..n0..n.'..
[out] pSignature[*pulSignatureLen] 00007fb80953a730 / 256
    00000000  60 FF 21 26 00 C1 DF 4A 14 76 A8 2B AE 0F 08 E7  `.!&...J.v.+....
    00000010  8E AC E2 6A 39 CB D6 35 9B 3B D1 08 92 95 B4 64  ...j9..5.;.....d
    00000020  B1 66 8F 33 62 22 3A 23 A0 17 CC 2B 6F 21 75 E2  .f.3b":#...+o!u.
    00000030  C1 88 4A B1 87 2D 9F 4C 7E 88 97 C5 DF 10 BB 78  ..J..-.L~......x
    00000040  23 5A 70 A2 5F 76 21 8E 97 BB 0C 38 75 BB BB 78  #Zp._v!....8u..x
    00000050  11 50 B0 0D 17 49 60 2A 34 42 6E 48 D0 43 40 B1  .P...I`*4BnH.C@.
    00000060  8B AA 7E 49 A1 3B 36 99 EF FA E0 E5 AF E0 8D E5  ..~I.;6.........
    00000070  CC CC E9 57 F2 0B AA 83 D2 4F FF 6F 4F 54 1B 31  ...W.....O.oOT.1
    00000080  17 8B 22 A9 3F 65 2C 4C 33 B6 A0 C2 AE C8 97 F8  ..".?e,L3.......
    00000090  C3 0E 66 07 1D 67 AD B3 A8 D4 6B 97 7B 1B 8A 3E  ..f..g....k.{..>
    000000A0  95 72 3E 79 68 05 5E 87 B4 86 31 71 61 AD D9 F6  .r>yh.^...1qa...
    000000B0  D4 58 C4 F6 D8 98 A5 1B 1D 12 75 BB D2 A1 CD 60  .X........u....`
    000000C0  E8 4A 80 D0 B5 A6 F3 3F 45 38 C3 22 96 74 5B 0B  .J.....?E8.".t[.
    000000D0  4B F7 A5 C1 83 D8 D9 B4 1C 94 17 C7 ED 7D F5 23  K............}.#
    000000E0  8B A4 F0 F8 6A 3B 64 1F 33 0F 05 2E FF D6 FA B3  ....j;d.3.......
    000000F0  35 C4 EA C9 B6 28 19 0D 80 6A AF 04 E7 2B 9F C4  5....(...j...+..
Returned:  0 CKR_OK
Signed (data len=83, signature 256 bytes): rv=1
. . . . .

193: C_FindObjects
2017-10-08 13:47:57.510
[in] hSession = 0x7fb809428960
[in] ulMaxObjectCount = 0x1
[out] ulObjectCount = 0x1
Object 0x7fb8094202b0 matches
Returned:  0 CKR_OK

194: C_GetAttributeValue
2017-10-08 13:47:57.510
[in] hSession = 0x7fb809428960
[in] hObject = 0x7fb8094202b0
[in] pTemplate[1]: 
    CKA_KEY_TYPE          00007fff5414a8e8 / 8
[out] pTemplate[1]: 
    CKA_KEY_TYPE          CKK_RSA            
Returned:  0 CKR_OK

195: C_FindObjects
2017-10-08 13:47:57.510
[in] hSession = 0x7fb809428960
[in] ulMaxObjectCount = 0x1
[out] ulObjectCount = 0x0
Returned:  0 CKR_OK

196: C_FindObjectsFinal
2017-10-08 13:47:57.510
[in] hSession = 0x7fb809428960
Returned:  0 CKR_OK
Signature verified successfully: rv=1
. . . . .

With OpenSSL dgst CLI:

~/openssl-1.1/bin/openssl dgst -engine pkcs11 -keyform engine -sign 'pkcs11:token=Uri%20the%20Great;id=%02;type=private' -sha256 -sigopt rsa_padding_mode:pkcs1 -out t6400.dat.sig t6400.dat
engine "pkcs11" set.


*************** OpenSC PKCS#11 spy *****************
Loaded: "/Library/OpenSC/lib/opensc-pkcs11.dylib"

0: C_GetFunctionList
2017-10-08 14:01:02.027
Returned:  0 CKR_OK

1: C_Initialize
2017-10-08 14:01:02.029
[in] pInitArgs = 0x7fc94360afd0
     flags: 2
       CKF_OS_LOCKING_OK
Returned:  0 CKR_OK

2: C_GetSlotList
2017-10-08 14:01:02.928
[in] tokenPresent = 0x0
[out] pSlotList: 
Count is 1
[out] *pulCount = 0x1
Returned:  0 CKR_OK

3: C_GetSlotList
2017-10-08 14:01:02.929
[in] tokenPresent = 0x0
[out] pSlotList: 
Slot 0
[out] *pulCount = 0x1
Returned:  0 CKR_OK
. . . . .

99: C_GetAttributeValue
2017-10-08 14:01:05.369
[in] hSession = 0x7fc943604110
[in] hObject = 0x7fc94351dac0
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007fc943641030 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  True
Returned:  0 CKR_OK

100: C_SignInit
2017-10-08 14:01:05.369
[in] hSession = 0x7fc943604110
pMechanism->type=CKM_RSA_PKCS                 
[in] hKey = 0x7fc94351dac0
Returned:  0 CKR_OK
Enter PKCS#11 key PIN for SIGN key:

101: C_Login
2017-10-08 14:01:07.554
[in] hSession = 0x7fc943604110
[in] userType = CKU_CONTEXT_SPECIFIC
. . . . .
Returned:  0 CKR_OK

102: C_Sign
2017-10-08 14:01:07.588
[in] hSession = 0x7fc943604110
[in] pData[ulDataLen] 00007fff593ae470 / 32
    00000000  1A D4 85 99 2B F3 57 85 F7 F9 F9 AD 95 2F A0 AD  ....+.W....../..
    00000010  5E ED C3 54 8B BD D0 4D 43 83 0A 65 99 31 6D 9E  ^..T...MC..e.1m.
[out] pSignature[*pulSignatureLen] 00007fc944004400 / 256
    00000000  45 20 B4 53 5C CC F6 BF 98 38 2E E6 DB 42 15 AF  E .S\....8...B..
    00000010  F4 34 A9 D9 21 07 9A 43 7C C8 6B 66 28 6B 52 2D  .4..!..C|.kf(kR-
    00000020  77 68 9A 96 6F 5C FD 1F CC A1 D4 F3 A8 5D 4B 4D  wh..o\.......]KM
    00000030  D6 AB FB 50 2D 09 6F 42 59 77 E1 E5 8B FB 54 02  ...P-.oBYw....T.
    00000040  1C 96 F3 74 30 AA E5 73 C4 16 89 B2 A5 54 C4 A8  ...t0..s.....T..
    00000050  4E B2 A2 71 97 97 22 FB 6F F0 53 50 78 C9 0B E3  N..q..".o.SPx...
    00000060  86 E1 D6 60 56 9B 7B A3 F2 56 32 6F 5B B6 89 7A  ...`V.{..V2o[..z
    00000070  92 CE A2 7E E4 99 9C 66 CF 49 80 11 64 C7 FE 16  ...~...f.I..d...
    00000080  E1 8C DD 16 41 0D 11 54 58 FE B6 2A CB 25 B3 0F  ....A..TX..*.%..
    00000090  16 4D 9A AA 83 99 D7 9A 0E 0F AF 84 32 24 69 FA  .M..........2$i.
    000000A0  7D ED 45 0D 49 3B D0 B8 F9 7D B8 C8 4E ED FE 3C  }.E.I;...}..N..<
    000000B0  65 12 61 A1 10 33 C9 8D 0B CB 67 A7 A9 5F EE EB  e.a..3....g.._..
    000000C0  4B 41 95 D8 FD 09 6B 15 1A 42 5E 5E 55 22 D1 FC  KA....k..B^^U"..
    000000D0  6B C2 76 46 FD CA 82 B3 81 95 57 9D 2C EF 63 48  k.vF......W.,.cH
    000000E0  6E 21 8E 1C 63 12 4F F6 94 55 38 96 84 02 A6 B9  n!..c.O..U8.....
    000000F0  C9 F8 C1 F0 27 38 32 9B 23 94 33 18 25 08 49 85  ....'82.#.3.%.I.
Returned:  0 CKR_OK
$ ~/openssl-1.1/bin/openssl dgst -engine pkcs11 -keyform engine -verify 'pkcs11:token=Uri%20the%20Great;id=%02;type=public' -sha256 -sigopt rsa_padding_mode:pkcs1 -signature t6400.dat.sig t6400.dat
engine "pkcs11" set.


*************** OpenSC PKCS#11 spy *****************
Loaded: "/Library/OpenSC/lib/opensc-pkcs11.dylib"

0: C_GetFunctionList
2017-10-08 14:02:58.363
Returned:  0 CKR_OK

1: C_Initialize
2017-10-08 14:02:58.365
[in] pInitArgs = 0x7fe28ad063d0
     flags: 2
       CKF_OS_LOCKING_OK
Returned:  0 CKR_OK
. . . . .
76: C_FindObjectsFinal
2017-10-08 14:02:59.311
[in] hSession = 0x7fe28ad258c0
Returned:  0 CKR_OK

77: C_GetAttributeValue
2017-10-08 14:02:59.311
[in] hSession = 0x7fe28ad258c0
[in] hObject = 0x7fe28ad1d900
[in] pTemplate[1]: 
    CKA_MODULUS           0000000000000000 / 0
[out] pTemplate[1]: 
    CKA_MODULUS           0000000000000000 / 256
Returned:  0 CKR_OK

78: C_GetAttributeValue
2017-10-08 14:02:59.311
[in] hSession = 0x7fe28ad258c0
[in] hObject = 0x7fe28ad1d900
[in] pTemplate[1]: 
    CKA_MODULUS           00007fe28ae2ba40 / 256
[out] pTemplate[1]: 
    CKA_MODULUS           00007fe28ae2ba40 / 256
    00000000  BF 03 6F 94 56 56 89 D1 91 8B 1D F5 63 7F 8F 5C  ..o.VV......c.\
    00000010  94 09 0D 67 0D C4 A8 B3 AB 6D 94 4C 03 67 4E 4D  ...g.....m.L.gNM
    00000020  B6 1D 3B 2A 55 9B 13 86 49 96 9F C1 0E AE 65 70  ..;*U...I.....ep
    00000030  51 48 FD E2 EB 4C 33 1D 9F 3A 57 75 8A 3D 5F 0E  QH...L3..:Wu.=_.
    00000040  34 FA 76 85 31 43 FC 87 F1 D4 6B 04 2A FE 54 3F  4.v.1C....k.*.T?
    00000050  85 C1 A2 1A AD 93 3A 8A 94 22 BD 9F 4A 20 EA FB  ......:.."..J ..
    00000060  97 34 89 96 B9 C8 44 B2 C2 6A C8 E6 72 40 55 FB  .4....D..j..r@U.
    00000070  CF BF D0 89 51 95 7A 70 1F 6B 94 0B A0 96 48 AD  ....Q.zp.k....H.
    00000080  C6 E2 80 BA 7D 63 C1 08 6B F4 8C 92 AD 48 E1 BF  ....}c..k....H..
    00000090  64 76 D3 6E BC 7E 12 58 EA A2 FA 67 21 CF A6 3D  dv.n.~.X...g!..=
    000000A0  07 F1 B3 54 EA 94 8F 10 66 C0 7C 30 ED 5C 42 B0  ...T....f.|0.\B.
    000000B0  9A 15 02 2E 71 C4 77 4E D9 9F 12 56 2E 18 15 0B  ....q.wN...V....
    000000C0  05 A2 84 5F 7A 67 E0 13 2C A8 8B 77 54 19 20 48  ..._zg..,..wT. H
    000000D0  C4 5A A8 D0 17 42 4A 6D 73 75 AF 97 D1 71 44 7D  .Z...BJmsu...qD}
    000000E0  F9 F8 A8 D8 E5 34 49 C0 FB 32 37 AE A6 60 F5 4A  .....4I..27..`.J
    000000F0  52 ED EC EA 97 83 46 D9 0A 34 51 19 60 BD 5E EB  R.....F..4Q.`.^.
Returned:  0 CKR_OK

79: C_GetAttributeValue
2017-10-08 14:02:59.311
[in] hSession = 0x7fe28ad258c0
[in] hObject = 0x7fe28ad1d900
[in] pTemplate[1]: 
    CKA_PUBLIC_EXPONENT   0000000000000000 / 0
[out] pTemplate[1]: 
    CKA_PUBLIC_EXPONENT   0000000000000000 / 3
Returned:  0 CKR_OK

80: C_GetAttributeValue
2017-10-08 14:02:59.311
[in] hSession = 0x7fe28ad258c0
[in] hObject = 0x7fe28ad1d900
[in] pTemplate[1]: 
    CKA_PUBLIC_EXPONENT   00007fe28ae2c140 / 3
[out] pTemplate[1]: 
    CKA_PUBLIC_EXPONENT   00007fe28ae2c140 / 3
    00000000  01 00 01                                         ...             
Returned:  0 CKR_OK
Verification Failure
$

@mouse07410
Copy link
Contributor Author

And for comparison, this is the "good" output from my fork:

$ ~/openssl-1.1/bin/openssl dgst -engine pkcs11 -keyform engine -sign 'pkcs11:token=Uri%20the%20Great;id=%02;type=private' -sha256 -sigopt rsa_padding_mode:pkcs1 -out t6400.dat.sig t6400.dat
engine "pkcs11" set.


*************** OpenSC PKCS#11 spy *****************
Loaded: "/Library/OpenSC/lib/opensc-pkcs11.dylib"

0: C_GetFunctionList
2017-10-08 14:25:29.705
Returned:  0 CKR_OK

1: C_Initialize
2017-10-08 14:25:29.706
[in] pInitArgs = 0x7fe2fce0ce40
     flags: 2
       CKF_OS_LOCKING_OK
Returned:  0 CKR_OK
. . . . .

99: C_GetAttributeValue
2017-10-08 14:25:33.131
[in] hSession = 0x7fe2fce11990
[in] hObject = 0x7fe2fcf332b0
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007fe2fce11200 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  True
Returned:  0 CKR_OK

100: C_SignInit
2017-10-08 14:25:33.131
[in] hSession = 0x7fe2fce11990
pMechanism->type=CKM_RSA_PKCS                 
[in] hKey = 0x7fe2fcf332b0
Returned:  0 CKR_OK
Enter PKCS#11 key PIN for SIGN key:

101: C_Login
2017-10-08 14:25:41.037
[in] hSession = 0x7fe2fce11990
[in] userType = CKU_CONTEXT_SPECIFIC
. . . . .       
Returned:  0 CKR_OK

102: C_Sign
2017-10-08 14:25:41.070
[in] hSession = 0x7fe2fce11990
[in] pData[ulDataLen] 00007fe2fce11cb0 / 51
    00000000  30 31 30 0D 06 09 60 86 48 01 65 03 04 02 01 05  010...`.H.e.....
    00000010  00 04 20 1A D4 85 99 2B F3 57 85 F7 F9 F9 AD 95  .. ....+.W......
    00000020  2F A0 AD 5E ED C3 54 8B BD D0 4D 43 83 0A 65 99  /..^..T...MC..e.
    00000030  31 6D 9E                                         1m.             
[out] pSignature[*pulSignatureLen] 00007fe2fd800000 / 256
    00000000  00 17 B5 05 55 07 1E 7D 60 75 01 0A ED AD 48 3F  ....U..}`u....H?
    00000010  63 C8 52 8B E2 5A B5 5A 47 0E F8 10 A9 CA F6 6D  c.R..Z.ZG......m
    00000020  AA 15 20 04 51 23 54 04 54 CC 60 F7 8C 66 B3 91  .. .Q#T.T.`..f..
    00000030  A8 8E 30 90 97 75 14 D2 22 E6 1D 6C E7 FB FF F3  ..0..u.."..l....
    00000040  33 FC 8E 20 87 BD 8A EA 38 3A F0 A0 2D 95 2C 25  3.. ....8:..-.,%
    00000050  30 D0 0A C6 E1 BB 3F B5 2B 93 CA 42 83 22 FF 69  0.....?.+..B.".i
    00000060  FB 29 A1 4F A1 F0 10 DC EE B6 ED D5 D0 7C 28 ED  .).O.........|(.
    00000070  7C DC 13 B1 73 42 98 7F A3 8B 37 EC 72 56 DB 96  |...sB...7.rV..
    00000080  DD AF CB CC 2C 8C B7 86 85 7D 45 64 F2 65 8C 8E  ....,....}Ed.e..
    00000090  31 E1 1B 95 33 7F 7A 08 02 E3 E5 DE AF 2D 3A 3F  1...3z......-:?
    000000A0  9B 0A 8A 51 F0 70 BC AF 14 34 D9 1C B1 AC 6E 3D  ...Q.p...4....n=
    000000B0  7A E8 51 AB FD 9C E7 2A 3E 82 2E 66 36 67 8D 79  z.Q....*>..f6g.y
    000000C0  47 C4 DB C7 0D 17 C7 3C 6E 13 FF 5E 4B 28 EC A0  G......<n..^K(..
    000000D0  A9 40 4F ED 6F F8 C4 46 34 14 A4 92 E3 F7 5A 46  .@O.o..F4.....ZF
    000000E0  FD AC CE DB B8 A4 3E A3 F4 45 DB 4D 8F 59 95 2D  ......>..E.M.Y.-
    000000F0  81 F9 0F 90 04 4C BB 27 1A 66 0C 41 A8 CC 3D F9  .....L.'.f.A..=.
Returned:  0 CKR_OK

$ ~/openssl-1.1/bin/openssl dgst -engine pkcs11 -keyform engine -verify 'pkcs11:token=Uri%20the%20Great;id=%02;type=public' -sha256 -sigopt rsa_padding_mode:pkcs1 -signature t6400.dat.sig t6400.dat
engine "pkcs11" set.


*************** OpenSC PKCS#11 spy *****************
Loaded: "/Library/OpenSC/lib/opensc-pkcs11.dylib"

0: C_GetFunctionList
2017-10-08 14:25:48.907
Returned:  0 CKR_OK
. . . . .

78: C_GetAttributeValue
2017-10-08 14:25:49.855
[in] hSession = 0x7fa3d952ca30
[in] hObject = 0x7fa3d962d980
[in] pTemplate[1]: 
    CKA_MODULUS           00007fa3d9638df0 / 256
[out] pTemplate[1]: 
    CKA_MODULUS           00007fa3d9638df0 / 256
    00000000  BF 03 6F 94 56 56 89 D1 91 8B 1D F5 63 7F 8F 5C  ..o.VV......c.\
    00000010  94 09 0D 67 0D C4 A8 B3 AB 6D 94 4C 03 67 4E 4D  ...g.....m.L.gNM
    00000020  B6 1D 3B 2A 55 9B 13 86 49 96 9F C1 0E AE 65 70  ..;*U...I.....ep
    00000030  51 48 FD E2 EB 4C 33 1D 9F 3A 57 75 8A 3D 5F 0E  QH...L3..:Wu.=_.
    00000040  34 FA 76 85 31 43 FC 87 F1 D4 6B 04 2A FE 54 3F  4.v.1C....k.*.T?
    00000050  85 C1 A2 1A AD 93 3A 8A 94 22 BD 9F 4A 20 EA FB  ......:.."..J ..
    00000060  97 34 89 96 B9 C8 44 B2 C2 6A C8 E6 72 40 55 FB  .4....D..j..r@U.
    00000070  CF BF D0 89 51 95 7A 70 1F 6B 94 0B A0 96 48 AD  ....Q.zp.k....H.
    00000080  C6 E2 80 BA 7D 63 C1 08 6B F4 8C 92 AD 48 E1 BF  ....}c..k....H..
    00000090  64 76 D3 6E BC 7E 12 58 EA A2 FA 67 21 CF A6 3D  dv.n.~.X...g!..=
    000000A0  07 F1 B3 54 EA 94 8F 10 66 C0 7C 30 ED 5C 42 B0  ...T....f.|0.\B.
    000000B0  9A 15 02 2E 71 C4 77 4E D9 9F 12 56 2E 18 15 0B  ....q.wN...V....
    000000C0  05 A2 84 5F 7A 67 E0 13 2C A8 8B 77 54 19 20 48  ..._zg..,..wT. H
    000000D0  C4 5A A8 D0 17 42 4A 6D 73 75 AF 97 D1 71 44 7D  .Z...BJmsu...qD}
    000000E0  F9 F8 A8 D8 E5 34 49 C0 FB 32 37 AE A6 60 F5 4A  .....4I..27..`.J
    000000F0  52 ED EC EA 97 83 46 D9 0A 34 51 19 60 BD 5E EB  R.....F..4Q.`.^.
Returned:  0 CKR_OK

79: C_GetAttributeValue
2017-10-08 14:25:49.855
[in] hSession = 0x7fa3d952ca30
[in] hObject = 0x7fa3d962d980
[in] pTemplate[1]: 
    CKA_PUBLIC_EXPONENT   0000000000000000 / 0
[out] pTemplate[1]: 
    CKA_PUBLIC_EXPONENT   0000000000000000 / 3
Returned:  0 CKR_OK

80: C_GetAttributeValue
2017-10-08 14:25:49.855
[in] hSession = 0x7fa3d952ca30
[in] hObject = 0x7fa3d962d980
[in] pTemplate[1]: 
    CKA_PUBLIC_EXPONENT   00007fa3d96190d0 / 3
[out] pTemplate[1]: 
    CKA_PUBLIC_EXPONENT   00007fa3d96190d0 / 3
    00000000  01 00 01                                         ...             
Returned:  0 CKR_OK
Verified OK

@mtrojnar
Copy link
Member

mtrojnar commented Oct 8, 2017

Why doesn't it work with simple RSA PKCS1 padding, and only one card and not with other cards? Also, the signed value is different in failed and successful tests.

Maybe it's something obvious and I can't see it simply because it's too late... Anyway, I have rewritten the code to make it fairly clear and it should be easy to spot the bug.

@mtrojnar mtrojnar added the bug label Oct 8, 2017
@dengert
Copy link
Member

dengert commented Oct 8, 2017

In the bad one, you are signing just the hash:

[in] pData[ulDataLen] 00007fff593ae470 / 32
    00000000  1A D4 85 99 2B F3 57 85 F7 F9 F9 AD 95 2F A0 AD  ....+.W....../..
    00000010  5E ED C3 54 8B BD D0 4D 43 83 0A 65 99 31 6D 9E  ^..T...MC..e.1m.

In the good one you are signing the digest:

[in] pData[ulDataLen] 00007fe2fce11cb0 / 51
    00000000  30 31 30 0D 06 09 60 86 48 01 65 03 04 02 01 05  010...`.H.e.....
    00000010  00 04 20 1A D4 85 99 2B F3 57 85 F7 F9 F9 AD 95  .. ....+.W......
    00000020  2F A0 AD 5E ED C3 54 8B BD D0 4D 43 83 0A 65 99  /..^..T...MC..e.
    00000030  31 6D 9E          

@mouse07410
Copy link
Contributor Author

Why doesn't it work with simple RSA PKCS1 padding, and only one card and not with other cards?

I have only PIV-compatible cards, and a couple of HSM devices. All I can say is that it looks like when the token supports only raw RSA, there's a problem (potentially related to how the fallback is handled, and what it is falling back on). When the token can do the padding internally, it works.

@dengert so what should be signed is this ASN.1 structure, right?

$ dumpasn1 sig.bin
  0  49: SEQUENCE {
  2  13:   SEQUENCE {
  4   9:     OBJECT IDENTIFIER sha-256 (2 16 840 1 101 3 4 2 1)
 15   0:     NULL
       :     }
 17  32:   OCTET STRING
       :     1A D4 85 99 2B F3 57 85 F7 F9 F9 AD 95 2F A0 AD
       :     5E ED C3 54 8B BD D0 4D 43 83 0A 65 99 31 6D 9E
       :   }

0 warnings, 0 errors.

Note that both "good" and "bad" examples were created by OpenSSL with identical invocations...

@dengert
Copy link
Member

dengert commented Oct 9, 2017

Right. pkcs1 padding signs the ASN1 digest which includes the hash. With PSS padding, it takes just the hash. (In opensc, the asn1 with the digest are hard coded, so they just concatenate them with the hash.)

I would suggest your run the debugger, break on pkcs11_try_pkey_rsa_sign then step through it and look at the lengths and what EVP_MD_size(sig_md) You could also break on pkey_rsa_sign to see if it
the original code.

Or add some fprintf statements to see what is is doing.

Not in the original "proof of concept" code, only PSS was handled. All other was handled by the orig_pkey_rsa_sign. There it does for pkcs1 padding.

147 ret = RSA_sign(EVP_MD_type(rctx->md),
148                           tbs, tbslen, sig, &sltmp, rsa);

@mouse07410
Copy link
Contributor Author

mouse07410 commented Oct 9, 2017

...in the original "proof of concept" code, only PSS was handled. All other was handled by the orig_pkey_rsa_sign. There it does for pkcs1 padding.

So my fork that essentially uses your "proof of concept" code, has the fallback to orig_pkey_rsa_sign() that apparently did the right thing for RSA-PKCS1. Which is why my fork works.

And the current master tries to do it all on its own, and fails to ASN.1-encode the hash with the algorithm (which depends on the actual hash used) before sending it for signing.

To solve, one would create 5 "prefixes", one for each allowed hash (with accommodation for its length), right? SHA-1, SHA256, SHA384, SHA512.

Also, I recall you mentioning that engine may advertise a mechanism that is not supported (entirely) by hardware. I checked. Here's what I have for the NEO (PIV-compliant):

Supported mechanisms:
  SHA-1, digest
  SHA256, digest
  SHA384, digest
  SHA512, digest
  MD5, digest
  RIPEMD160, digest
  GOSTR3411, digest
  ECDSA, keySize={256,256}, hw, sign, other flags=0x1800000
  ECDH1-COFACTOR-DERIVE, keySize={256,256}, hw, derive, other flags=0x1800000
  ECDH1-DERIVE, keySize={256,256}, hw, derive, other flags=0x1800000
  RSA-X-509, keySize={1024,3072}, hw, decrypt, sign, verify
  RSA-PKCS, keySize={1024,3072}, hw, decrypt, sign, verify
  SHA1-RSA-PKCS, keySize={1024,3072}, sign, verify
  SHA256-RSA-PKCS, keySize={1024,3072}, sign, verify
  SHA384-RSA-PKCS, keySize={1024,3072}, sign, verify
  SHA512-RSA-PKCS, keySize={1024,3072}, sign, verify
  MD5-RSA-PKCS, keySize={1024,3072}, sign, verify
  RIPEMD160-RSA-PKCS, keySize={1024,3072}, sign, verify

And here's what HSM provides (note that pretty much everything except raw digests is in HW):

Supported mechanisms:
  RSA-PKCS, keySize={2048,4096}, hw, decrypt, sign
  SHA1-RSA-PKCS, keySize={2048,4096}, hw, decrypt, sign
  SHA256-RSA-PKCS, keySize={2048,4096}, hw, decrypt, sign
  SHA384-RSA-PKCS, keySize={2048,4096}, hw, decrypt, sign
  SHA512-RSA-PKCS, keySize={2048,4096}, hw, decrypt, sign
  RSA-PKCS-PSS, keySize={2048,4096}, hw, sign
  SHA1-RSA-PKCS-PSS, keySize={2048,4096}, hw, sign
  SHA256-RSA-PKCS-PSS, keySize={2048,4096}, hw, sign
  SHA384-RSA-PKCS-PSS, keySize={2048,4096}, hw, sign
  SHA512-RSA-PKCS-PSS, keySize={2048,4096}, hw, sign
  RSA-PKCS-KEY-PAIR-GEN, keySize={2048,4096}, hw, generate_key_pair
  ECDSA-KEY-PAIR-GEN, keySize={256,521}, hw, generate_key_pair, other flags=0x1500000
  SHA-1-HMAC, keySize={1,512}, hw, sign, verify
  SHA256-HMAC, keySize={1,512}, hw, sign, verify
  SHA384-HMAC, keySize={1,1024}, hw, sign, verify
  SHA512-HMAC, keySize={1,1024}, hw, sign, verify
  ECDSA, keySize={256,521}, hw, sign, other flags=0x1500000
  ECDSA-SHA1, keySize={256,521}, hw, sign, other flags=0x1500000
  RSA-PKCS-OAEP, keySize={2048,4096}, hw, decrypt
  mechtype-0x80000004, keySize={128,256}, hw, encrypt, decrypt, wrap, unwrap
  ECDSA-SHA256, keySize={256,521}, hw, sign, other flags=0x1500000
  ECDSA-SHA384, keySize={256,521}, hw, sign, other flags=0x1500000
  ECDSA-SHA512, keySize={256,521}, hw, sign, other flags=0x1500000
  SHA-1, digest
  SHA256, digest
  SHA384, digest
  SHA512, digest
  GENERIC-SECRET-KEY-GEN, keySize={1,1024}, hw, generate

@dengert One thing puzzles me here. Originally, the pkcs11 engine (libp11) was able to do RSA-PKCS1 and RSA-PSS on the PIV tokens presumably because it would fall back onto software padding and request RSA-X-509 from the token itself. But I see that even the working "proof of concept" code had CKR_OK from the PIV token on C_SignInit(CKM_RSA_PKCS), and it did not stop it from creating the correct digest structure.

Now we got an HSM that cannot do RSA-X-509, but supports internal padding. So the engine now passes raw hash to the HSM token, and it works fine:

. . . . .
95: C_GetAttributeValue
2017-10-08 21:42:44.669
[in] hSession = 0x0
[in] hObject = 0x30301
[in] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  00007fea8d41bfd0 / 1
[out] pTemplate[1]: 
    CKA_ALWAYS_AUTHENTICATE  False
Returned:  0 CKR_OK

96: C_SignInit
2017-10-08 21:42:44.669
[in] hSession = 0x0
pMechanism->type=CKM_RSA_PKCS                 
[in] hKey = 0x30301
Returned:  0 CKR_OK

97: C_Sign
2017-10-08 21:42:44.670
[in] hSession = 0x0
[in] pData[ulDataLen] 00007fea8d500000 / 32
    00000000  5A AF 60 23 0D F3 22 09 F9 8A 80 D4 6D 74 CE 8F  Z.`#..".....mt..
    00000010  9B 0A C9 F4 20 65 8C B2 00 14 61 3D FF 03 F6 92  .... e....a=....
[out] pSignature[*pulSignatureLen] 00007fea8d5570e0 / 384
    00000000  43 1A 52 C9 7B 82 BD 9F AB 6C 11 DE E3 58 6F 9E  C.R.{....l...Xo.
    00000010  24 76 6B 50 E1 C8 62 A8 04 C5 E1 15 05 23 82 20  $vkP..b......#. 
    00000020  E2 20 6A AA A3 64 E7 2F EF 12 40 95 E1 05 BB C4  . j..d./..@.....
    00000030  B1 FC F4 2F 5B B3 29 9A 94 4D D9 B7 93 3F A4 26  .../[.)..M...?.&
    00000040  32 2D F3 50 B9 D8 08 87 04 EE 24 65 D2 A2 59 71  2-.P......$e..Yq
    00000050  23 3A 09 C8 F7 B3 0F 08 A8 8E 64 EB 0A D1 19 7E  #:........d....~
    00000060  5E C4 86 A7 F8 8E 4F DC 04 F7 BE A0 1A 1E DC 07  ^.....O.........
    00000070  B2 0A 97 66 E3 F9 A7 BF 8A 75 DD 58 CE BC A2 B4  ...f.....u.X....
    00000080  EA 60 FC B9 9D 02 FC C3 C9 FE A2 03 02 BE 4F 4F  .`............OO
    00000090  26 11 14 2A A9 B3 98 B9 F5 E8 AB 8C 0E 07 58 9D  &..*..........X.
    000000A0  B9 C9 EB 85 99 A7 A1 C4 24 32 E0 B6 88 89 CA ED  ........$2......
    000000B0  3B CA 06 3B 35 4F B9 5A D0 AC 00 7D 57 BC B4 14  ;..;5O.Z...}W...
    000000C0  1A 0A B4 AB 66 73 7F 1B D7 DA C2 65 CD BE BE 19  ....fs....e....
    000000D0  65 F4 0E E8 8B D9 31 93 42 F0 14 2C 63 5A 9C 9F  e.....1.B..,cZ..
    000000E0  51 BD 53 2E D5 72 4E E3 F4 BE 13 FB EC 41 A3 17  Q.S..rN......A..
    000000F0  59 5C F6 F6 F8 54 DC B0 D6 98 F9 66 D2 C3 B0 4C  Y\...T.....f...L
    00000100  DF 7D 44 90 4C DA 07 4D 9D C5 60 B0 F4 A5 A8 89  .}D.L..M..`.....
    00000110  43 7C B7 DF D0 ED ED 95 CE C7 D4 1E 23 08 4E 27  C|..........#.N'
    00000120  B6 CC 3D BB BE 0F 02 33 CE 5E 9A 7C A7 C0 5A BD  ..=....3.^.|..Z.
    00000130  D4 EA 51 21 ED 23 B8 3A 1B F6 83 3D 1F 5E 90 A0  ..Q!.#.:...=.^..
    00000140  8B 7E D0 2D F9 0A FC A1 6C 43 BB DC 68 C1 E1 23  .~.-....lC..h..#
    00000150  36 8F 25 25 12 1E 61 5F 45 2E 2A 93 B2 8A 24 95  6.%%..a_E.*...$.
    00000160  00 EF 8D ED 9C 7F C1 B1 07 20 2C 1A C7 6F 97 35  ........ ,..o.5
    00000170  1F 9D 98 4F 35 DE 6C 4A 41 FF 2B 62 E4 F9 CB C8  ...O5.lJA.+b....
Returned:  0 CKR_OK
Signed (data len=32, signature 384 bytes): rv=1
. . . . .
Signature verified successfully: rv=1

But when the engine tries to do the same with a PIV token (that also says CKR_OK to CKM_RSA_PKCS mechanism) it fails:

. . . . .
100: C_SignInit
2017-10-08 21:48:12.378
[in] hSession = 0x7fc1b2515ee0
pMechanism->type=CKM_RSA_PKCS                 
[in] hKey = 0x7fc1b2509a10
Returned:  0 CKR_OK
Enter PKCS#11 key PIN for SIGN key:

101: C_Login
. . . . .
Returned:  0 CKR_OK

102: C_Sign
2017-10-08 21:48:17.341
[in] hSession = 0x7fc1b2515ee0
[in] pData[ulDataLen] 00007fc1b2412ca0 / 32
    00000000  B6 74 27 71 37 15 4B 6D FF FC AB 35 39 41 2D 33  .t'q7.Km...59A-3
    00000010  2E 18 7E 84 0D 75 7C EB 20 FB 57 82 55 59 93 29  ..~..u|. .W.UY.)

the input for signing is not converted to the ASN.1 Digest structure, so even though it is signed

[out] pSignature[*pulSignatureLen] 00007fc1b2519df0 / 256
    00000000  6D 7A A0 95 F9 37 91 A8 A5 18 CE FF 6E FC 00 A8  mz...7......n...
    00000010  6F 73 E9 E9 6B 70 29 C1 5F BB AB CA 64 8B A3 E3  os..kp)._...d...
    00000020  72 40 61 6C 05 D7 0F 87 ED 84 87 6A 25 42 A4 FE  r@al.......j%B..
    00000030  D5 AD AF 54 A8 0F 9E D0 D2 26 04 20 F9 69 8F 58  ...T.....&. .i.X
    00000040  21 C0 0A E4 4F C6 E8 8F DA B1 87 94 02 B3 B8 F8  !...O...........
    00000050  97 0F FC 34 6E 8A 05 96 7F 56 CB 07 90 A4 5A 11  ...4n...V....Z.
    00000060  82 83 7C 9B E6 13 DF C1 6F AF D7 C4 23 11 C7 65  ..|.....o...#..e
    00000070  37 63 E8 A0 A9 14 5B 8A 82 7C 23 96 28 76 F3 1B  7c....[..|#.(v..
    00000080  D7 0F C4 10 D4 6F 1A 6F 5B D7 E5 35 0C 69 EA EB  .....o.o[..5.i..
    00000090  3B 1E 38 05 88 7A 7C A8 3B 62 F5 58 5E AA 3E 48  ;.8..z|.;b.X^.>H
    000000A0  E7 F1 DC A0 1A 3E 4D A5 68 CF 4D B0 5C 39 98 7F  .....>M.h.M.\9.
    000000B0  48 A3 10 F1 79 F1 66 3F 21 42 1C 9D F6 E2 AE D9  H...y.f?!B......
    000000C0  8B AD 48 3F EE 45 68 57 F1 17 1E 73 85 6E 09 EE  ..H?.EhW...s.n..
    000000D0  1E E5 55 8C 9E 3B 00 2F 9F 23 69 F6 D7 DB 2D 83  ..U..;./.#i...-.
    000000E0  FF 78 29 AA 0B 37 6B 88 64 3B B5 FF A7 74 4A 69  .x)..7k.d;...tJi
    000000F0  29 72 1B 43 27 85 70 49 D1 20 D8 74 C3 F9 24 CE  )r.C'.pI. .t..$.
Returned:  0 CKR_OK
Signed (data len=32, signature 256 bytes): rv=1
. . . . . .

it fails verification:

140736337826752:error:04091068:rsa routines:int_rsa_verify:bad signature:crypto/rsa/rsa_sign.c:220:
Verification failed! (rv=0 olen=256)

My conjecture (based on your explanation) is:

  • PIV can only do "raw" RSA-PKCS on-board (everything else like SHA384-RSA-PKCS requires software assist), so for hashed inputs it requires the ASN.1 structure prepared for it.
  • HSM does everything on-board, so it can take raw hash and build the ASN.1 structure around it internally.

What do you think the solution should be? Pass SHA256-RSA-PKCS to the token instead of RSA-PKCS in hope that it would cause a fallback to the correct software encoder?

@mtrojnar did you change behavior of what the "proof of concept" code used as orig_pkey_rsa_sign()? If so, would it be possible to return it to the old behavior? The "proof of concept" code works with both PIV and HSM, supporting both RSA-PKCS and RSA-PSS paddings correctly.

P.S. @mtrojnar you might like to know that your current master appears to do RSA-OAEP encryption on PIV tokens. Fallback there seems to work fine.

@dengert
Copy link
Member

dengert commented Oct 9, 2017

At times in our discussion the terms "token", "on-board", "PKCS#11 module", "hardware" and "software".

Different 'PKCS#11 modules" can present a different list of support mechanisms even when using the same "hardware token". In your list of mechanisms, I assume the PIV was using the opensc-pkcs11 module, and the HSM was using the Yubico PKCS#11 module.

The CKF_HW flag can be misleading for a compound operation such as RSA-PKCS.

opensc-pkcs11 reports: RSA-PKCS, keySize={1024,3072}, hw, decrypt, sign, verify
Knowing the capabilities of the PIV, I know that the card (hardware token) only supports a single RSA operation that is used for both decryption and signing. When used with C_Sign, take input date, pad it using PKCS in the opensc-pkcs11 module then do a RSA-X-509 (RAW) operation. When used with C_Decrypt, do a RSA-X-509 on the input then remove the padding (while verifying the padding looks correct) then return the unpadded result.

So although the CKF_HW is set, part of the operation (padding) must be done in software. And the PIV hardware can not do public key operations, so a verify must be all in software.

The same holds for the SHA*-RSA-PKCS mechanisms, the SHA* part must be done in software, because the PIV hardware does not support it. and the PKCS must be done in software as well. and the CKF_HW flag is not set.

I am not as familiar with the HSM as you are. But noting that it does not support RSA-X-509, but does support RSA-PKCS implies either (1) that the padding is done only in the hardware or (2) the PKCS#11 module is doing the padding in software and the card does support a RSA RAW operation but the module does not advertise it. (From conversations you had with Yubico, (1) is the case.)

The HSM also says it supports SHA*-RSA-PKCS for example
SHA256-RSA-PKCS-PSS, keySize={2048,4096}, hw, sign
But does the hardware actually support doing all of the operation in hardware? The CKF_HW is set, but PKCS#11 is ambiguous in its meaning. What does Yubico say?

The point of all of this is: PKCS#11 modules implement a lot of software that the application could have done itself to make it easier on the application so it can just stick to making PKCS#11 calls. OpenSC added the digest mechanisms to make it easier. It looks like the Yubico PKCS#11 module added them too. Note that neither of these set the CKF_HW flag on these single operation mechanisms So my speculation is the Yubico HSM does not support the digest operations in hardware.

If that is the case, there is little or no advantage in trying to have the software in the PKCS#11 module do the hashing vs having the caller do the hashing in software.

As to some of your speculations:
PKCS#11 2.40 2.1.6 PKCS #1 v1.5 RSA
"This mechanism corresponds only to the part of PKCS #1 v1.5 that involves RSA; it does not compute a message digest or a DigestInfo encoding as specified for the md2withRSAEncryption and md5withRSAEncryption algorithms in PKCS #1 v1.5"

In other words the caller passes in whatever they want to be padded It does not have to be a digest.

PKCS#11 2.40 2.1.14 PKCS #1 v1.5 RSA signature with MD2, MD5, SHA-1, SHA-256, SHA-
384, SHA-512, RIPE-MD 128 or RIPE-MD 160
"Likewise, the PKCS #1 v1.5 RSA signature with SHA-256, SHA-384, and SHA-512 mechanisms, denoted
CKM_SHA256_RSA_PKCS, CKM_SHA384_RSA_PKCS, and CKM_SHA512_RSA_PKCS respectively,
perform the same operations using the SHA-256, SHA-384 and SHA-512 hash functions with the object
identifiers sha256WithRSAEncryption, sha384WithRSAEncryption and sha512WithRSAEncryption
respectively."

Here it says it does comply with PKCS #1 v1.5 and computes the hash and digestInfo.

@mtrojnar
So it is the caller of C_Sign using RSA-PKCS responsibility to pass in a digest info as specified by PKCS #1 v1.5 RSA signature when using RSA-PKCS.

@mouse07410
Copy link
Contributor Author

mouse07410 commented Oct 9, 2017

@dengert currently the code appears to send to the token DigestInfo for RSA-PKCS, and a raw hash for RSA-PSS. Do you think it should send DigestInfo in both cases?

But noting that it does not support RSA-X-509, but does support RSA-PKCS implies either (1) that the padding is done only in the hardware or (2) the PKCS#11 module is doing the padding in software and the card does support a RSA RAW operation but the module does not advertise it. (From conversations you had with Yubico, (1) is the case.)

I'm pretty certain that (1) is the case. They planned to have it certified, and cited security concerns when I asked to add raw RSA support in case somebody wants it.

The HSM also says it supports SHA*-RSA-PKCS for example
SHA256-RSA-PKCS-PSS, keySize={2048,4096}, hw, sign
But does the hardware actually support doing all of the operation in hardware? The CKF_HW is set, but PKCS#11 is ambiguous in its meaning. What does Yubico say?

I did not ask. If you think it's beneficial, I will ask them. But from our point of view, we're only dealing with the PKCS#11 interface module - so even if they (contrary to what I want to believe :) do part of the padding in their software, it won't affect what we need to pass to it for PSS signature. Correct?

If that is the case, there is little or no advantage in trying to have the software in the PKCS#11 module do the hashing vs having the caller do the hashing in software.

I'm only trying to avoid the "Unimplemented digest" error when OpenSSL (misguidedly, IMHO) tries to offload all the operations to the engine. I'm currently working with OpenSSL team attempting to resolve this problem, but having "belt and suspenders" has always been my strategy. ;-)

And I see no harm in having the engine advertise support for digests (and offloading them back to OpenSSL). Am I wrong here?

mtrojnar added a commit that referenced this issue Oct 9, 2017
This commit reverts attempts to use EVP_PKEY for more than just PSS.
@mtrojnar
Copy link
Member

mtrojnar commented Oct 9, 2017

Thank you. I agree with your assessment. It should be fixed now.

@dengert
Copy link
Member

dengert commented Oct 9, 2017

@mouse07410 For PSS only the hash is sent, along with the parameters.

PKCS#11 2.40 2.1.o PKCS #1 RSA PSS
"This mechanism corresponds only to the part of PKCS #1 that involves block formatting and RSA, given a hash value; it does not compute a hash value on the message to be signed."

@mouse07410
Copy link
Contributor Author

mouse07410 commented Oct 9, 2017

Using OpenSSL with openssl/openssl#4503 applied, and modifying your code with

diff --git a/src/eng_front.c b/src/eng_front.c
index 9633fe0..6d6638c 100644
--- a/src/eng_front.c
+++ b/src/eng_front.c
@@ -194,12 +194,16 @@ static EVP_PKEY *load_pubkey(ENGINE *engine, const char *s_key_id,
 static EVP_PKEY *load_privkey(ENGINE *engine, const char *s_key_id,
                UI_METHOD *ui_method, void *callback_data)
 {
-       ENGINE_CTX *ctx;
+       ENGINE_CTX *ctx = NULL;
+       EVP_PKEY   *pkey = NULL;
 
        ctx = get_ctx(engine);
        if (ctx == NULL)
                return 0;
-       return ctx_load_privkey(ctx, s_key_id, ui_method, callback_data);
+       pkey = ctx_load_privkey(ctx, s_key_id, ui_method, callback_data);
+       if (pkey)
+  #if OPENSSL_VERSION_NUMBER < 0x10100000L
+               pkey->engine = engine;
+  #else
+  #if defined(EVP_F_EVP_PKEY_SET1_ENGINE)
+               EVP_PKEY_set1_engine(pkey, engine);
+  #endif /* EVP_F_EVP_PKEY_SET1_ENGINE */
+  #endif
+       return pkey;
 }
 
 static int engine_ctrl(ENGINE *engine, int cmd, long i, void *p, void (*f) ())

based on Steve Henson's newly added method EVP_PKEY_set1_engine(), both RSA-PKCS and RSA-PSS seem to work fine with both PIV and HSM devices.

Since it's unclear when the above PR gets merged, and how long it would take for it to percolate to the stable versions, it might be nice if we could find a way to tell whether the given/installed OpenSSL version has this method or not. Determining it at the libp11 compile time should be good enough, IMHO.

Thank you!

P.S. Now - to RSA-OAEP encryption. ;-)

Update
I've also tested the above patch to src/eng_front.c with OpenSSL-1.0.2-stable. It worked fine.
@mtrojnar I'd appreciate if you could apply this fix.

@mtrojnar
Copy link
Member

@mouse07410 I will apply your fix. I'm glad that now you know that it is needed #176 (comment). 😆

@mouse07410
Copy link
Contributor Author

mouse07410 commented Oct 10, 2017

@mouse07410 I will apply your fix. I'm glad that now you know that it is needed

Thank you!! 😉

More than that - I now know why, where, and how! 🤡

And I hope that this openssl/openssl#4503 (comment) would be merged soon by the OpenSSL team.

Ironically, OpenSSL-1.0.2 can function correctly without changes, thanks to EVP_PKEY not being opaque. ;-)

Update
Had a silly typo - not sure how it could get into the running code. 😱
Anyway, OpenSSL version number was wrong in the patch I posted. Not it is correct there, and in the proposed PR #181

@mouse07410
Copy link
Contributor Author

I think this issue is fixed. Will check on another machine this evening, and (hopefully ;) close it.

@mouse07410
Copy link
Contributor Author

mouse07410 commented Oct 11, 2017

Well, not quite. One small problem remained.

Accessor methods EVP_PKEY_meth_get_sign() and others from that group have been added to OpenSSL-1.0.2m-dev. So the check against OpenSSL-.1.1.x causes the compilation to fail.

Update
Because when compiled under OPENSSL_VERSION_NUMBER == 0x100020d0L you get double definition - one "normal", and one local "static" that was supposed to compensate for the absence of the method. So the proposed PR or something like it is necessary, and will manifest itself so as soon as 1.0.2m hits the road.

#182 fixes it.

@mtrojnar
Copy link
Member

#182 is merged

fabled added a commit to fabled/libp11 that referenced this issue Mar 20, 2021
The long term lock keeping was originally added in commit e81e335
"NULL sig support OpenSC#178" to support querying the size of the signature
with sig=NULL. However, this commit was immediately followed up
by 7a1fca4 "EVP_PKEY_FLAG_AUTOARGLEN for EVP_PKEY_meth_new()" which
refers to same issue too.

The EVP_PKEY_FLAG_AUTOARGLEN makes OpenSSL core handle sig=NULL
case before calling the algorithm specific sign function. Thus we
never get the sig=NULL call in the current code. Thus the original
hack is unneeded.

This effectively reverts e81e335 and adds an error handling if
sig=NULL would happen.
fabled added a commit to fabled/libp11 that referenced this issue Mar 20, 2021
The long term lock keeping was originally added in commit e81e335
"NULL sig support OpenSC#178" to support querying the size of the signature
with sig=NULL. However, this commit was immediately followed up
by 7a1fca4 "EVP_PKEY_FLAG_AUTOARGLEN for EVP_PKEY_meth_new()" which
refers to same issue too.

The EVP_PKEY_FLAG_AUTOARGLEN makes OpenSSL core handle sig=NULL
case before calling the algorithm specific sign function. Thus we
never get the sig=NULL call in the current code. Thus the original
hack is unneeded.

This effectively reverts e81e335 and adds an error handling if
sig=NULL would happen.
fabled added a commit to fabled/libp11 that referenced this issue Mar 20, 2021
The long term lock keeping was originally added in commit e81e335
"NULL sig support OpenSC#178" to support querying the size of the signature
with sig=NULL. However, this commit was immediately followed up
by 7a1fca4 "EVP_PKEY_FLAG_AUTOARGLEN for EVP_PKEY_meth_new()" which
refers to same issue too.

The EVP_PKEY_FLAG_AUTOARGLEN makes OpenSSL core handle sig=NULL
case before calling the algorithm specific sign function. Thus we
never get the sig=NULL call in the current code. Thus the original
hack is unneeded.

This effectively reverts e81e335 and adds an error handling if
sig=NULL would happen.
mtrojnar pushed a commit that referenced this issue Apr 11, 2021
The long term lock keeping was originally added in commit e81e335
"NULL sig support #178" to support querying the size of the signature
with sig=NULL. However, this commit was immediately followed up
by 7a1fca4 "EVP_PKEY_FLAG_AUTOARGLEN for EVP_PKEY_meth_new()" which
refers to same issue too.

The EVP_PKEY_FLAG_AUTOARGLEN makes OpenSSL core handle sig=NULL
case before calling the algorithm specific sign function. Thus we
never get the sig=NULL call in the current code. Thus the original
hack is unneeded.

This effectively reverts e81e335 and adds an error handling if
sig=NULL would happen.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants