C_EncryptInit

CK_RV C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)


Параметры:    

  • hSession (in) – дескриптор сеанса.
  • pMechanism (in) – указатель на механизм. Идентификатор механизма задается в поле mechanism.
  • hKey (in) – дескриптор ключа зашифрования.

Инициализирует операцию зашифрования. Поддерживается аппаратное и программное шифрование.

Особенности приложений GOST:

  • Шифрование на СКЗИ с защитой ключа (рекомендуемый режим)

Для шифрования на СКЗИ с защитой ключа используется виртуальный секретный ключ. Дескриптор этого ключа получается путем поиска объекта типа CKO_SECRET_KEY с атрибутом CKA_ID, равным значению "VSKO_ID". Важно отметить, что на данном этапе сам ключевой материал отсутствует в памяти СКЗИ. Ключ должен быть предварительно сгенерирован и экспортирован с помощью функции C_WrapKey() или импортирован с помощью C_UnwrapKey(). Как только ключевой материал появляется в памяти СКЗИ, атрибут CKA_KT2_KEY_ACTIVE устанавливается в значение CK_TRUE. После завершения операции шифрования ключ удаляется из памяти устройства, а атрибут CKA_KT2_KEY_ACTIVE сбрасывается в значение CK_FALSE.

  • Шифрование с использованием сессионных ключей

Шифрование с использованием сессионных ключей может выполняться на ключах, предварительно сгенерированных функцией C_GenerateKey() или импортированных в сессию с помощью функции C_CreateObject().
Атрибут CKA_TOKEN сессионных ключей имеет значение CK_FALSE.

Также для механизма шифрования CKM_GOST28147 доступен атрибут CKA_KT2_KEY_MESHING. Если его значение — CK_TRUE, применяется алгоритм усложнения ключей в соответствии с ГОСТ 28147–89 (RFC 4357, п. 2.3.2).

Поддерживаются следующие механизмы для разных приложений:

  • GOST версии 2.5.5
    • CKM_GOST28147_ECB (0x00001221) – механизм для симметричного шифра в режиме ECB по стандарту ГОСТ 28147–89.
    • CKM_GOST28147 (0x00001222) – механизм для симметричного шифра в режиме CFB по стандарту ГОСТ 28147–89.
  • GOST версии 2.5.9
    • CKM_MAGMA_CBC                (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x023)    шифрование по алгоритму Магма в режиме сцепления блоков шифротекста
    • CKM_MAGMA_CTR                (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x020)    шифрование по алгоритму Магма в режиме гаммирования
    • CKM_MAGMA_CFB                (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x022)    шифрование по алгоритму Магма в режиме обратной загрузке шифротекста
    • CKM_MAGMA_CTR_ACPKM    (CK_VENDOR_PKCS11_RU_TEAM_TC26 |0x036UL) шифрование по алгоритму Магма в режиме гаммирования с преобразованием ключа
    • CKM_MAGMA_OFB                (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x022)    шифрование по алгоритму Магма в режиме обратной загрузке выходных данных
  • GOST версии 2.5.13
    • CKM_MAGMA_CBC                   (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x023)    шифрование по алгоритму Магма в режиме сцепления блоков шифротекста
    • CKM_MAGMA_CTR                   (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x020)    шифрование по алгоритму Магма в режиме гаммирования
    • CKM_MAGMA_CFB                   (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x022)    шифрование по алгоритму Магма в режиме обратной загрузке шифротекста
    • CKM_MAGMA_CTR_ACPKM       (CK_VENDOR_PKCS11_RU_TEAM_TC26 |0x036UL) шифрование по алгоритму Магма в режиме гаммирования с преобразованием ключа
    • CKM_MAGMA_OFB                   (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x022)    шифрование по алгоритму Магма в режиме обратной загрузке выходных данных
    • CKM_KUZNECHIK_CBC             (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x01E)    шифрование по алгоритму Кузнечик в режиме сцепления блоков шифротекста
    • CKM_KUZNECHIK_CTR             (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x01B)    шифрование по алгоритму Кузнечик в режиме гаммирования
    • CKM_KUZNECHIK_CFB             (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x01C)    шифрование по алгоритму Кузнечик в режиме обратной загрузке шифротекста
    • CKM_KUZNECHIK_CTR_ACPKM (CK_VENDOR_PKCS11_RU_TEAM_TC26 |0x032UL)    шифрование по алгоритму Кузнечик в режиме гаммирования с преобразованием ключа
    • CKM_KUZNECHIK_OFB             (CK_VENDOR_PKCS11_RU_TEAM_TC26 | 0x01D)    шифрование по алгоритму Кузнечик в режиме обратной загрузке выходных данных
  • PKI
    • CKM_RSA_PKCS (0x00000001) – механизм для ассиметричного шифра RSA. Также используется для ЭП.
    • CKM_RSA_PKCS_OAEP (0x00000009) – механизм для ассиметричного шифра RSA с использованием OAEP.
    • CKM_DES3_ECB (0x00000132) – механизм для симметричного шифра triple-DES в режиме ECB.
    • CKM_DES3_CBC (0x00000133) – механизм для симметричного шифра triple-DES в режиме CBC.
    • CKM_AES_ECB (0x00001081) – механизм для симметричного шифра AES в режиме ECB.
    • CKM_AES_CBC (0x00001082) – механизм для симметричного шифра AES в режиме CBC.

Запускается в режимах:


Результат:    

  • CKR_CRYPTOKI_NOT_INITIALIZED – функция не может быть выполнена, т.к. библиотека еще не была инициализирована (см. C_Initialize()).
  • CKR_DEVICE_ERROR – возникла проблема с токеном и/или слотом.
  • CKR_DEVICE_MEMORY – памяти токена недостаточно для данной операции.
  • CKR_DEVICE_REMOVED – токен был изъят из слота.
  • CKR_FUNCTION_CANCELED – функция была отменена в момент исполнения.
  • CKR_FUNCTION_FAILED – выполнение функции было прервано или она не может быть выполнена.
  • CKR_GENERAL_ERROR – общий сбой при работе с библиотекой.
  • CKR_HOST_MEMORY – компьютер, на котором запущена библиотека, не имеет достаточно памяти для выполнения функции.
  • CKR_KEY_FUNCTION_NOT_PERMITTED – атрибуты ключа не позволяют его использование данным образом.
  • CKR_KEY_HANDLE_INVALID – недопустимый дескриптор ключа.
  • CKR_KEY_SIZE_RANGE – размер ключа лежит за пределами, поддерживаемыми библиотекой.
  • CKR_KEY_TYPE_INCONSISTENT – данный ключ невозможно использовать с указанным механизмом.
  • CKR_MECHANISM_INVALID – недопустимый механизм.
  • CKR_MECHANISM_PARAM_INVALID – недопустимый параметр механизма.
  • CKR_OK – функция выполнена успешно.
  • CKR_OPERATION_ACTIVE – на устройстве уже есть активная операция, что не позволяет начать новую операцию.
  • CKR_PIN_EXPIRED – срок действия указанного PIN-кода истек.
  • CKR_SESSION_CLOSED – сеанс был закрыт в момент выполнения функции.
  • CKR_SESSION_HANDLE_INVALID – недопустимый дескриптор сеанса.
  • CKR_USER_NOT_LOGGED_IN – действие не может быть выполнено, т.к. пользователь не залогинен.

Совет: Полный список ошибок см. в приложении.

C_Encrypt

CK_RV C_Encrypt(CK_SESSION_HANDLE hSessionCK_BYTE_PTR pDataCK_ULONG ulDataLenCK_BYTE_PTR pEncryptedDataCK_ULONG_PTR pulEncryptedDataLen)


Параметры:    

  • hSession (in) – дескриптор сеанса.
  • pData (in) – указатель на исходные данные.
  • ulDataLen (in) – размер данных.
  • pEncryptedData (out) – указатель на зашифрованные данные.
  • pulEncryptedDataLen (out) – размер зашифрованных данных.

Осуществляет единоразовое зашифрование, т.е зашифровывает только один блок данных. 

Предупреждение: При шифровании с использованием механизма CKM_GOST28147 длина данных должна быть кратной 8 байт.

Запускается в режимах:


Результат:    

  • CKR_ARGUMENTS_BAD – недопустимые аргументы.
  • CKR_BUFFER_TOO_SMALL – вывод функции слишком велик для предоставленного буфера.
  • CKR_CRYPTOKI_NOT_INITIALIZED – функция не может быть выполнена, т.к. библиотека еще не была инициализирована (см. C_Initialize()).
  • CKR_DATA_INVALID – недопустимые данные.
  • CKR_DATA_LEN_RANGE – недопустимый размер данных.
  • CKR_DEVICE_ERROR – возникла проблема с токеном и/или слотом.
  • CKR_DEVICE_MEMORY – памяти токена недостаточно для данной операции.
  • CKR_DEVICE_REMOVED – токен был изъят из слота.
  • CKR_FUNCTION_CANCELED – функция была отменена в момент исполнения.
  • CKR_FUNCTION_FAILED – выполнение функции было прервано или она не может быть выполнена.
  • CKR_GENERAL_ERROR – общий сбой при работе с библиотекой.
  • CKR_HOST_MEMORY – компьютер, на котором запущена библиотека, не имеет достаточно памяти для выполнения функции.
  • CKR_OK – функция выполнена успешно.
  • CKR_OPERATION_NOT_INITIALIZED – в указанном сеансе нет активной операции данного типа.
  • CKR_SESSION_CLOSED – сеанс был закрыт в момент выполнения функции.
  • CKR_SESSION_HANDLE_INVALID – недопустимый дескриптор сеанса.

Совет: Полный список ошибок см. в приложении.

C_EncryptUpdate

CK_RV C_EncryptUpdate(CK_SESSION_HANDLE hSessionCK_BYTE_PTR pPartCK_ULONG ulPartLenCK_BYTE_PTR pEncryptedPartCK_ULONG_PTR pulEncryptedPartLen)


Параметры:    

  • hSession (in) – дескриптор сеанса.
  • pPart (in) – указатель на блок исходных данных.
  • ulPartLen (in) – размер блока данных.
  • pEncryptedPart (out) – указатель на зашифрованный блок данных.
  • pulEncryptedPartLen (out) – размер зашифрованного блока данных.

Продолжает составную операцию зашифрования – зашифровывает очередной блок данных.

Запускается в режимах:

См. также: C_EncryptInit()C_Encrypt() и C_EncryptFinal().


Результат:    

  • CKR_ARGUMENTS_BAD – недопустимые аргументы.
  • CKR_BUFFER_TOO_SMALL – вывод функции слишком велик для предоставленного буфера.
  • CKR_CRYPTOKI_NOT_INITIALIZED – функция не может быть выполнена, т.к. библиотека еще не была инициализирована (см. C_Initialize()).
  • CKR_DATA_LEN_RANGE – недопустимый размер данных.
  • CKR_DEVICE_ERROR – возникла проблема с токеном и/или слотом.
  • CKR_DEVICE_MEMORY – памяти токена недостаточно для данной операции.
  • CKR_DEVICE_REMOVED – токен был изъят из слота.
  • CKR_FUNCTION_CANCELED – функция была отменена в момент исполнения.
  • CKR_FUNCTION_FAILED – выполнение функции было прервано или она не может быть выполнена.
  • CKR_GENERAL_ERROR – общий сбой при работе с библиотекой.
  • CKR_HOST_MEMORY – компьютер, на котором запущена библиотека, не имеет достаточно памяти для выполнения функции.
  • CKR_OK – функция выполнена успешно.
  • CKR_OPERATION_NOT_INITIALIZED – в указанном сеансе нет активной операции данного типа.
  • CKR_SESSION_CLOSED – сеанс был закрыт в момент выполнения функции.
  • CKR_SESSION_HANDLE_INVALID – недопустимый дескриптор сеанса.

Совет: Полный список ошибок см. в приложении.

C_EncryptFinal

CK_RV C_EncryptFinal(CK_SESSION_HANDLE hSessionCK_BYTE_PTR pLastEncryptedPartCK_ULONG_PTR pulLastEncryptedPartLen)


Параметры:    

  • hSession (in) – дескриптор сеанса.
  • pLastEncryptedPart (out) – последний зашифрованный блок.
  • pulLastEncryptedPartLen (out) – размер последнего зашифрованного блока.

Завершает составную операцию зашифрования.

Запускается в режимах:

См. также: C_EncryptInit()C_Encrypt() и C_EncryptUpdate().


Результат:    

  • CKR_ARGUMENTS_BAD – недопустимые аргументы.
  • CKR_BUFFER_TOO_SMALL – вывод функции слишком велик для предоставленного буфера.
  • CKR_CRYPTOKI_NOT_INITIALIZED – функция не может быть выполнена, т.к. библиотека еще не была инициализирована (см. C_Initialize()).
  • CKR_DATA_LEN_RANGE – недопустимый размер данных.
  • CKR_DEVICE_ERROR – возникла проблема с токеном и/или слотом.
  • CKR_DEVICE_MEMORY – памяти токена недостаточно для данной операции.
  • CKR_DEVICE_REMOVED – токен был изъят из слота.
  • CKR_FUNCTION_CANCELED – функция была отменена в момент исполнения.
  • CKR_FUNCTION_FAILED – выполнение функции было прервано или она не может быть выполнена.
  • CKR_GENERAL_ERROR – общий сбой при работе с библиотекой.
  • CKR_HOST_MEMORY – компьютер, на котором запущена библиотека, не имеет достаточно памяти для выполнения функции.
  • CKR_OK – функция выполнена успешно.
  • CKR_OPERATION_NOT_INITIALIZED – в указанном сеансе нет активной операции данного типа.
  • CKR_SESSION_CLOSED – сеанс был закрыт в момент выполнения функции.
  • CKR_SESSION_HANDLE_INVALID – недопустимый дескриптор сеанса.

Совет: Полный список ошибок см. в приложении.

Пример

<pre> &nbsp; ///////////////////
&nbsp; &nbsp; /// Открыть сессию
&nbsp; &nbsp; rv = CALL_P11(C_OpenSession(nGostSlotId, (CKF_SERIAL_SESSION | CKF_RW_SESSION), 0, 0, &amp;hSession));
&nbsp; &nbsp; CHECK_RES(rv, &quot;C_OpenSession&quot;);
&nbsp; &nbsp; printf(&quot;C_OpenSession - OK\n&quot;);
&nbsp; &nbsp; printf(&quot;Open session: ok\n&quot;);
 
&nbsp; &nbsp; //////////////////////////////////////////
&nbsp; &nbsp; /// Выполнить аутентификацию Пользователя
&nbsp; &nbsp; rv = CALL_P11(C_Login(hSession, CKU_USER, (CK_CHAR_PTR)PIN_DEFAULT_USER, (CK_ULONG)strlen(PIN_DEFAULT_USER)));
&nbsp; &nbsp; CHECK_RES(rv, &quot;C_Login&quot;);
&nbsp; &nbsp; printf(&quot;C_Login - OK\n&quot;);
 
&nbsp; &nbsp; ////////////////////////////////////
&nbsp; &nbsp; /// ищем виртуальный секретный ключ
&nbsp; &nbsp; rv = CALL_P11(C_FindObjectsInit(hSession, secretKeySearchTemplate, sizeof(secretKeySearchTemplate) / sizeof(CK_ATTRIBUTE)));
&nbsp; &nbsp; CHECK_RES(rv, &quot;C_FindObjectsInit&quot;);
&nbsp; &nbsp; printf(&quot;C_FindObjectsInit - OK\n&quot;);
 
&nbsp; &nbsp; /////////////////////////////
&nbsp; &nbsp; /// получаем найденные ключи
&nbsp; &nbsp; rv = CALL_P11(C_FindObjects(hSession, &amp;hVirtualSecretKey, 1, &amp;secretKeyCount));
&nbsp; &nbsp; CHECK_RES(rv, &quot;C_FindObjects&quot;);
&nbsp; &nbsp; printf(&quot;C_FindObjects - OK\n&quot;);
 
&nbsp; &nbsp; //////////////////////////////
&nbsp; &nbsp; /// завершаем операцию поиска
&nbsp; &nbsp; rv = CALL_P11(C_FindObjectsFinal(hSession));
&nbsp; &nbsp; CHECK_RES(rv, &quot;C_FindObjectsFinal&quot;);
&nbsp; &nbsp; printf(&quot;C_FindObjectsFinal - OK\n&quot;);
 
&nbsp; &nbsp; if (secretKeyCount != 1)
&nbsp; &nbsp; {
&nbsp; &nbsp; &nbsp; &nbsp; printf(&quot;Virtual secret key NOT found!\n&quot;);
&nbsp; &nbsp; &nbsp; &nbsp; goto end;
&nbsp; &nbsp; }
&nbsp; &nbsp; printf(&quot;Virtual secret key found!\n&quot;);
 
&nbsp; &nbsp; /////////////////////////////////////////
&nbsp; &nbsp; /// генерируем ключевую пару Отправителя
&nbsp; &nbsp; rv = CALL_P11(C_GenerateKeyPair(hSession,
&nbsp; &nbsp; &nbsp; &nbsp; &amp;generateMech,
&nbsp; &nbsp; &nbsp; &nbsp; senderPubKeyAttribs, sizeof(senderPubKeyAttribs) / sizeof(CK_ATTRIBUTE),
&nbsp; &nbsp; &nbsp; &nbsp; senderPrivKeyAttribs, sizeof(senderPrivKeyAttribs) / sizeof(CK_ATTRIBUTE),
&nbsp; &nbsp; &nbsp; &nbsp; &amp;hSenderPublicKey,
&nbsp; &nbsp; &nbsp; &nbsp; &amp;hSenderPrivateKey));
 
&nbsp; &nbsp; CHECK_RES(rv, &quot;C_GenerateKeyPair&quot;);
&nbsp; &nbsp; printf(&quot;C_GenerateKeyPair - OK\n&quot;);
&nbsp; &nbsp; printf(&quot;Sender key pair generation: ok\n&quot;);
 
&nbsp; &nbsp; ////////////////////////////////////////
&nbsp; &nbsp; /// генерируем ключевую пару Получателя
&nbsp; &nbsp; rv = CALL_P11(C_GenerateKeyPair(hSession,
&nbsp; &nbsp; &nbsp; &nbsp; &amp;generateMech,
&nbsp; &nbsp; &nbsp; &nbsp; receiverPubKeyAttribs, sizeof(receiverPubKeyAttribs) / sizeof(CK_ATTRIBUTE),
&nbsp; &nbsp; &nbsp; &nbsp; receiverPrivKeyAttribs, sizeof(receiverPrivKeyAttribs) / sizeof(CK_ATTRIBUTE),
&nbsp; &nbsp; &nbsp; &nbsp; &amp;hReceiverPublicKey,
&nbsp; &nbsp; &nbsp; &nbsp; &amp;hReceiverPrivateKey));
 
&nbsp; &nbsp; CHECK_RES(rv, &quot;C_GenerateKeyPair&quot;);
&nbsp; &nbsp; printf(&quot;C_GenerateKeyPair - OK\n&quot;);
&nbsp; &nbsp; printf(&quot;Receiver key pair generation: ok\n&quot;);
 
&nbsp; &nbsp; ///////////////////////////////
&nbsp; &nbsp; /// осуществляем экспорт ключа
&nbsp; &nbsp; memset(&amp;wrapParams, 0, sizeof(wrapParams));
&nbsp; &nbsp; wrapParams.hKey = hSenderPrivateKey;
&nbsp; &nbsp; wrappedKeyLen = sizeof(wrappedKey);
&nbsp; &nbsp; rv = CALL_P11(C_WrapKey(hSession, &amp;wrapMechanism, hReceiverPublicKey, hVirtualSecretKey, wrappedKey, &amp;wrappedKeyLen));
&nbsp; &nbsp; CHECK_RES(rv, &quot;C_WrapKey&quot;);
&nbsp; &nbsp; printf(&quot;C_WrapKey - OK\n&quot;);
&nbsp; &nbsp; printf(&quot;Wrapped key size: %lu\n&quot;, wrappedKeyLen);
 
&nbsp; &nbsp; /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
&nbsp; &nbsp; // Инициализировать операцию шифрования по алгоритму Магма (ГОСТ 34.12-2018, размер данных должен быть кратен 8)
&nbsp; &nbsp; rv = CALL_P11(C_EncryptInit(hSession, &amp;ckmEncDec, hVirtualSecretKey));
&nbsp; &nbsp; CHECK_RES(rv, &quot;C_EncryptInit&quot;);
&nbsp; &nbsp; printf(&quot;C_EncryptInit - OK\n&quot;);
 
&nbsp; &nbsp; /////////////////////////////////////////////////////
&nbsp; &nbsp; /// Определяем размер буфера для зашифрованных данных
&nbsp; &nbsp; rv = CALL_P11(C_Encrypt(hSession, buffer, sizeof(buffer), NULL_PTR, &amp;ulEncryptedLen));
&nbsp; &nbsp; CHECK_RES(rv, &quot;C_Encrypt&quot;);
&nbsp; &nbsp; printf(&quot;C_EncryptInit - OK\n&quot;);
 
&nbsp; &nbsp; // выделяем память для зашифрованных данных
&nbsp; &nbsp; pEncrypted = (CK_BYTE_PTR)malloc(ulEncryptedLen);
 
&nbsp; &nbsp; /////////////////////////
&nbsp; &nbsp; /// зашифровываем данные
&nbsp; &nbsp; rv = CALL_P11(C_Encrypt(hSession, buffer, sizeof(buffer), pEncrypted, &amp;ulEncryptedLen));
&nbsp; &nbsp; CHECK_RES(rv, &quot;C_Encrypt&quot;);
&nbsp; &nbsp; printf(&quot;C_EncryptInit - OK\n&quot;);
 
&nbsp; &nbsp; printf(&quot;Data encryption: ok!\n&quot;);</pre>