CloudHSM : Net.Pkcs11Interop.Common.Pkcs11Exception: Method C_DecryptInit returned 2147483674

1,436 views
Skip to first unread message

Arnaud Bertoli

unread,
Aug 11, 2016, 5:36:39 AM8/11/16
to Pkcs11Interop
Hi,

I use an HSM Safenet Luna on AWS (cloudhsm service) and I use PkcsInterop lib (3.0.1). Sometimes I can see a strange error code returned by C_DecryptInit  and C_Logout. The error code is 2147483674 (0x8000001A). I can't find this error code in pkcs11 documentation. This issue is very strange because It can appeared one day and disappeared the next day. And in this state our application is not able to find a key anymore. 

Sorry but I have not more information and no idea about the cause. It could be great if somebody knows the meaning of this error code.

Thanks for your help,
Arnaud

Jaroslav Imrich

unread,
Aug 14, 2016, 8:35:09 AM8/14/16
to Pkcs11Interop
Hello Arnaud,
 

I use an HSM Safenet Luna on AWS (cloudhsm service) and I use PkcsInterop lib (3.0.1). Sometimes I can see a strange error code returned by C_DecryptInit  and C_Logout. The error code is 2147483674 (0x8000001A). I can't find this error code in pkcs11 documentation.

PKCS#11 v2.20 specification states that "return values CKR_VENDOR_DEFINED (0x80000000) and above are permanently reserved for token vendors" so I guess it is safe to assume this is Luna specific error code. However I neither cannot find this particular value in CloudHSM documentation [0]. Did you try to ask Safenet support about it?

[0] http://cloudhsm-safenet-docs-5.3.s3-website-us-east-1.amazonaws.com/007-011136-006_lunasa_5-3_webhelp_rev-c/startpage.htm#reference/lunash/token-keycard_return-codes.htm

 
This issue is very strange because It can appeared one day and disappeared the next day. And in this state our application is not able to find a key anymore. 

Just guessing here but that sounds like a network related issue to me. Is your application reusing single PKCS#11 session for a long time? I don't know how Luna handles this internally but if you have a connection to a network HSM open for a long time and something goes down on a network path then unexpected results such as this one may occur. This is just a blind shot. Safenet support should know more.


Feel free to share more details and findings.

Regards, Jaroslav

Arnaud Bertoli

unread,
Aug 26, 2016, 12:08:19 PM8/26/16
to Pkcs11Interop
Hello Jaroslav,

Thanks for answer. I have not directly access to Safenet support only to Amazon. I have open a ticket but when I ask questions, answer are not very precise. However, I have some news. Recently we added multi-threading in our application. And I suppose that it is linked to the issue. I suppose that we don't manage well the sessions and I've started to read more carefully the pkcs11 standard to understand how to manage session inside a multi-threaded application.

To summary we have an application that receive some data and each time data are received a thread is created to verify a CMAC (and do other stuff after). I have read in pkcs11 that it is better to open one session by thread if each thread performs the same cryptographic operation.

So here what I have done :
1) At application startup : instantiate a pkcs11 to call C_Initialize (one call by application according to pkcs11 standard)
2) Inside the thread
- call a OpenSession followed by a login with normal user
- perfom cryptographics operations (FindObjects and Verify CMAC)
- log out and close the session.

This doesn't seems to work. I always got the error code (2147483674 ). So I have read a little more and I found that a call to C_Logout will change all the user sessions to public sessions. I also try to remove the call to Logout and it worked (i suppose ;)). Because I don't see this error anymore.

But, of course, I have another problem.  I try to send data to my application using a test program. And everytime, I have a few "mac not verified" because the FindObjects doesn't find the key. I use 4 tests programs sendind 10 datas each other in parallel. So 40 packets sends. And I always have 1 to 4 mac failure becaus eof key not found

So I have questions :
1) What do you think about the approach (one session by thread)?
2) Should I call C_Login one time or each time I open the session?
3) I have read that we can perfom only one cryptographic operation by session. So is it dangerous to call FindObjects and the verify CMAC in the same session?
4) Any idea about why the thread can't find the key sometimes?


Sorry for the long speech ;). I can give details if you want. I'm out of ideas now ;)

Regards,

Arnaud Bertoli

unread,
Aug 29, 2016, 6:09:31 AM8/29/16
to Pkcs11Interop
HI,

Some news. It seems that the application state has swiched from CKS_RO_USER_FUNCTIONS to CKS_RO_PUBLIC_SESSION. I have read it could be because CloseSession() has closed the last session linked to the token?

Jaroslav Imrich

unread,
Aug 29, 2016, 4:33:56 PM8/29/16
to Pkcs11Interop
Hello Arnaud,


So here what I have done :
1) At application startup : instantiate a pkcs11 to call C_Initialize (one call by application according to pkcs11 standard)

Single C_Initialize call is in most cases the best possible approach.

 
So I have read a little more and I found that a call to C_Logout will change all the user sessions to public sessions. I also try to remove the call to Logout and it worked (i suppose ;)). Because I don't see this error anymore.

As you already found out C_Login() and C_Logout() functions globally change state of all sessions. Skipping C_Logout() usually works because the last closed session will logout you anyway.

 
But, of course, I have another problem.  I try to send data to my application using a test program. And everytime, I have a few "mac not verified" because the FindObjects doesn't find the key. I use 4 tests programs sendind 10 datas each other in parallel. So 40 packets sends. And I always have 1 to 4 mac failure becaus eof key not found

As you have already found out when you close the last authenticated session you will need to reauthenticate. Key is not found most likely because it is a private object and your session is no longer authenticated.

 
1) What do you think about the approach (one session by thread)?

One of the primary functions of PKCS#11 sessions is operation (and thread) isolation. That means you should open new session for each thread (don't forget to close it).
 
2) Should I call C_Login one time or each time I open the session?

You can check session state and login only when needed or you can always call login and accept both CKR_OK and CKR_USER_ALREADY_LOGGED_IN as a successful return value.
 

3) I have read that we can perfom only one cryptographic operation by session. So is it dangerous to call FindObjects and the verify CMAC in the same session?

You surely can perform more operations in single session but only sequentially. You cannot perform more then one operation in single session in parallel.


 Regards, Jaroslav

Arnaud Bertoli

unread,
Sep 20, 2016, 5:07:39 AM9/20/16
to Pkcs11Interop
Hi,

Sorry for late answer. I was in holidays.It seems the errors we had (0x8000001A and "key not found") completely disappeared. Here a little summary if it can help other people.

:Prerequisites :
- you want to developp an application linked to a HSM Safenet Luna SA (I'm not sure it is valid for other HSM) using pkcs11
- you want to use multithreading inside this application
- each thread do the same cryptographic operations.

Rules to follow :
1) Open one session by thread and close it at the end. If you open one session for all threads you will have issues doing the same cryptographic operations in parallel inside the same session.
2) When you logged in, you are logged on all opened sessions (opened by your application of course) and you have access to all the private objects. So you can login only one time unless when the last session opened with the HSM is closed. In this case, if you try to open a session again, this session will be public so you will have to login again.
3) NEVER logout (or do it carefully): it will cause ALL the sessions to go in public state again.
4) Call C_Initialize (new Pkcs11()) only one time

In a technical point of view, you can do as you want.

 We choose to
- create a thread pool
- create a global HSMService containing a dictionnary (key, value) of sessions with the thread Id as key and the session as value.
- Each session has is own timer and is closed automatically when the timer expired (if the session is not used currently of course).
- Each time we need to do our cryptographic operation a thread is created and a session is opened if needed and added to the sessions list in our HSMService.

As said before it seems to work. Now we try to do some optimization. It seems that the operations time varies a lot. For example the first call (opensession, get key, crypto operation) time is 600 ms. But some time it takes 6 seconds.
We have some ideas. For example, we look for the key each time (200 ms). And the key is always the same so we can do it only one time.  Of course it does not explain everything.

One question, is the useOsLocking really mandatory ?

Hope this can help. Ask me if you need more details,


Regards,

Le jeudi 11 août 2016 11:36:39 UTC+2, Arnaud Bertoli a écrit :

Jaroslav Imrich

unread,
Sep 30, 2016, 3:57:00 PM9/30/16
to Pkcs11Interop
One question, is the useOsLocking really mandatory ?

In my experience it is. Search for CKF_OS_LOCKING_OK in PKCS#11 specification to read more about it.
 
Regards, Jaroslav
Reply all
Reply to author
Forward
0 new messages