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