Функции зашифрования

C_EncryptInit, C_Encrypt, C_EncryptUpdate и C_EncryptFinal

Предупреждение

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

C_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
Параметры:
  • hSession (in) – дескриптор сеанса.
  • pMechanism (in) – указатель на механизм.
  • hKey (in) – дескриптор ключа зашифрования.

Инициализирует операцию зашифрования по ГОСТ 28147-89. Поддерживается как аппаратное, так и программное зашифрование.

Механизм зашифрования задаётся в поле mechanism структуры CK_MECHANISM. Для зашифрования библиотека Cryptoki поддерживает механизмы, перечисленные ниже.

  • Криптотокен
    • CKM_GOST28147 (0x00001221) – механизм для симметричного шифра в режиме ECB по стандарту ГОСТ 28147-89.
    • CKM_GOST28147 (0x00001222) – механизм для симметричного шифра в режиме CFB по стандарту ГОСТ 28147-89.
  • Laser
    • 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 – функция не может быть выполнена, т.к. библиотека Cryptoki еще не была инициализирована (см. 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 – размер ключа лежит за пределами, поддерживаемыми библиотекой Cryptoki.
  • 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_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) – размер зашифрованных данных.

Осуществляет единоразовое зашифрование, т.е зашифровывает только один блок данных. Шифрование выполняется по ГОСТ 28147-89.

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

Результат:
  • CKR_ARGUMENTS_BAD – недопустимые аргументы.
  • CKR_BUFFER_TOO_SMALL – вывод функции слишком велик для предоставленного буфера.
  • CKR_CRYPTOKI_NOT_INITIALIZED – функция не может быть выполнена, т.к. библиотека Cryptoki еще не была инициализирована (см. 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_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) – размер зашифрованного блока данных.

Продолжает составную операцию зашифрования – зашифровывает очередной блок данных (по ГОСТ 28147-89).

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

Результат:
  • CKR_ARGUMENTS_BAD – недопустимые аргументы.
  • CKR_BUFFER_TOO_SMALL – вывод функции слишком велик для предоставленного буфера.
  • CKR_CRYPTOKI_NOT_INITIALIZED – функция не может быть выполнена, т.к. библиотека Cryptoki еще не была инициализирована (см. 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_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 – функция не может быть выполнена, т.к. библиотека Cryptoki еще не была инициализирована (см. 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 – недопустимый дескриптор сеанса.

Совет

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

Пример использования

Для обеспечения успешного зашифрования данных, необходимо, чтобы функции в алгоритме были использованы в одной из следующих последовательностей:

Для единоразовой операции зашифрования Для составной операции зашифрования
  1. C_EncryptInit(),
  2. C_Encrypt().
  1. C_EncryptInit(),
  2. C_EncryptUpdate() (один или более раз),
  3. C_EncryptFinal().

Пример реализации зашифрования на языке C:

// дескриптор сессионного ключа PKCS#11
CK_OBJECT_HANDLE pkcs11SessionKeyHandle;
// механизм шифрования ГОСТ 28147-89
CK_MECHANISM pkcs11EncMechanism;
// открытый текст
CK_BYTE plainText[8];
// длина открытого текста
CK_ULONG plainTextLength = sizeof(plainText);
// текст, зашифрованный PKCS#11
CK_BYTE pkcs11EncText[8];
// длина текста, зашифрованного PKCS#11
CK_ULONG pkcs11EncTextLength = sizeof(pkcs11EncText);
// инициализационный вектор для шифрования
CK_BYTE encIV[8];

// устанавливаем механизм шифрования по ГОСТ 28147-89
pkcs11EncMechanism.mechanism = CKM_GOST28147;
pkcs11EncMechanism.pParameter = encIV;
pkcs11EncMechanism.ulParameterLen = sizeof(encIV);

// инициализируем операцию зашифрования
rv = C_EncryptInit(pkcs11SessionHandle, &pkcs11EncMechanism, pkcs11SessionKeyHandle);
if(rv != CKR_OK)
{
  throw runtime_error("C_EncryptInit failed.");
}

// зашифровываем открытый текст
rv = C_Encrypt(pkcs11SessionHandle, plainText, plainTextLength, pkcs11EncText, &pkcs11EncTextLength);
if(rv != CKR_OK)
{
  throw runtime_error("C_EncryptInit failed.");
}

Пример зашифрования для ОС Android на языке Java:

// дескриптор сессии
LongRef session = new LongRef();
// дескриптор сессионного ключа
LongRef sessionKeyHandle = new LongRef();
// механизм для шифрования данных
CKM encryptionMech = new CKM(CKM.GOST28147, null);
// шифруемое сообщение
byte[] plainData = new byte[32];
// зашифрованное сообщение
byte[] encryptedData = new byte[32];
// длинна сообщений
LongRef dataLength = new LongRef(encryptedData.length);

// инициализация шифрования
rv = C.EncryptInit(session.value, encryptionMech, sessionKeyHandle.value);
if(rv != CKR.OK)
{
        throw new CKRException("C.EncryptInit", rv);
}

// шифрование
rv = C.Encrypt(session.value, plainData, encryptedData, dataLength);
if(rv != CKR.OK)
{
        throw new CKRException("C.Encrypt", rv);
}