0

I'm using Pkcs#11 with the NCryptoki dll to use our HSM and manage the keys.

Why is this code giving me, sometimes, the error 145 (CKR_OPERATION_NOT_INITIALIZED)? I'm trying to avoid it, but I am still missing something... This error happens randomly when calling the session.Encrypt().

static public byte[] Crypto(Key key, byte[] input, bool encrypt, Mechanism mech, string command)
{
    //Session session = openSession();
    var tupla = openSessionTupla();
    var session = tupla.Item1;
    try
    {

        Utility.Logger("Crypto encrypt " + encrypt.ToSafeString() + " mech " + mech.ToSafeString(), command);

        if (encrypt)
        {
            session.EncryptInit(mech, key);
            byte[] enc = session.Encrypt(input);
            session.EncryptFinal();
            session.Logout();
            session.Close();
            tupla.Item2.Finalize(IntPtr.Zero);
            return enc;
        }
        else
        {
            session.DecryptInit(mech, key);
            byte[] decriptata = session.Decrypt(input);
            session.DecryptFinal();
            session.Logout();
            session.Close();
            tupla.Item2.Finalize(IntPtr.Zero);
            return decriptata;
        }
    }
    catch (Exception e)
    {
        session.Logout();
        session.Close();
        tupla.Item2.Finalize(IntPtr.Zero);
        Utility.Logger("Crypto " + e.ToSafeString(), command);
        return null;
    }

}

Where openSessionTupla is

public static Tuple<Session, Cryptoki> openSessionTupla()
{
    Cryptoki.Licensee = Settings.LICENSEE;
    Cryptoki.ProductKey = Settings.PRODUCTKEY;
    Cryptoki cryptoki = new Cryptoki(Settings.PATH);
    //Console.WriteLine(Settings.PATH);
    //Console.WriteLine(Settings.SessionKey);
    cryptoki.Initialize();
    SlotList slots = cryptoki.Slots;
    if (slots.Count == 0)
    {
        //Console.WriteLine("No slot available");
        return null;
    }
    // Gets the first slot available
    Slot slot = slots[0];
    if (!slot.IsTokenPresent)
    {
        //Console.WriteLine("No token inserted in the slot: " + slots[0].Info.Description);
        return null;
    }
    Token token = slot.Token;
    var flags = token.Info.Flags;
    //token.Info.Flags = 1609;
    Session session = token.OpenSession(Session.CKF_SERIAL_SESSION | Session.CKF_RW_SESSION,
                            null,
                            null);

    int nRes = session.Login(Session.CKU_USER, Settings.SessionKey);

    return new Tuple<Session, Cryptoki>(session, cryptoki);
}
Piero Alberto
  • 3,823
  • 6
  • 56
  • 108
  • 1
    Can your PKCS#11 be configured to write logs? Maybe it could be helpful to know the reason of the error – Egl Nov 20 '17 at 15:33
  • @Egl Can you tell me how to do it using the NCryptoki? I'm a newbie here and I think there is a documentation lack... – Piero Alberto Nov 20 '17 at 15:39
  • 2
    You can use PKCS11-LOGGER to log all PKCS#11 calls. See [Troubleshooting Pkcs11Interop with PKCS11-LOGGER](https://github.com/Pkcs11Interop/Pkcs11Interop/blob/4.0.0/doc/TROUBLESHOOTING.md) for a quick howto. Just replace free Pkcs11Interop with non-free NCryptoki when reading. – jariq Nov 20 '17 at 21:46
  • @jariq I don't understand your last sentence. What do you mean with "Just replace free Pkcs11Interop with non-free NCryptoki when reading"? – Piero Alberto Nov 21 '17 at 07:08
  • Linked document describes how to use pkcs11-logger with Pkcs11Interop library which is an alternative to NCryptoki. You will need to adjust your thinking/reading to that fact. – jariq Nov 21 '17 at 09:16
  • So, I can't log with NCryptoki..... – Piero Alberto Nov 21 '17 at 09:58
  • I don't know if you can log with just NCryptoki but you surely can log with "pkcs11-logger and NCryptoki". – jariq Nov 21 '17 at 10:58
  • 2
    It seems that pkcs11-logger is a wrapper that allows you to log the pkcs11 calls. So, your program will have to load pkcs11-logger library instead of NCryptoki library. And you have to define some environment variables in order to let pkcs11-logger know which is the real pkcs11 library it has to call to (in your case, NCryptoki). According to jariq comment, it seems that these environment variables are PKCS11_LOGGER_LIBRARY_PATH, PKCS11_LOGGER_LOG_FILE_PATH and PKCS11_LOGGER_FLAGS – Egl Nov 21 '17 at 15:12
  • Got it.... I will try. Is there already an examply with pkcs-11-logger and cryptoki? – Piero Alberto Nov 22 '17 at 07:22
  • @jariq can you please look here https://stackoverflow.com/questions/47569311/pkcs11interop-read-key-value-from-hsm – Piero Alberto Nov 30 '17 at 08:54

1 Answers1

0

Maybe the call to session.EncryptInit(mech, key) returns an error. this is why the subsequent call to Encrypt returns CKR_OPERATION_NOT_INITIALIZED

You should write:

long nRes = session.EncryptInit(mech, key);
if(nRer != 0) {
// manage the error
}
else {
    byte[] enc = session.Encrypt(input);
    session.EncryptFinal();
}
Ugo Chirico
  • 347
  • 3
  • 6