КриптоПро CSP  

Управление алгоритмами и параметрами RFC 4357

Управление алгоритмами и параметрами RFC 4357 в СКЗИ КриптоПро CSP.

В СКЗИ КриптоПро CSP используются алгоритмы низкого уровня и параметры российских криптографических стандартов, определенные в RFC 4357.

В данном разделе приводятся основные способы использования функций СКЗИ для управления этими элементами.

Пункт RFC 4357 Управление с помощью СКЗИ КриптоПро CSP
2.1. GOST 28147-89 CBC Mode
	    
DWORD dwMode = CRYPT_MODE_CBC;
CPSetKeyParam(hProv, hSessionKey, KP_MODE, (BYTE*)& dwMode, 0);
	
2.2. GOST 28147-89 Padding Modes: Zero padding
	    
DWORD dwPadding = ZERO_PADDING;
CPSetKeyParam(hProv, hSessionKey, KP_PADDING, (BYTE*)& dwPadding, 0);
	
2.2. GOST 28147-89 Padding Modes: PKCS#5 padding
	    
DWORD dwPadding = PKCS5_PADDING;
CPSetKeyParam(hProv, hSessionKey, KP_PADDING, (BYTE*)& dwPadding, 0);
	
2.2. GOST 28147-89 Padding Modes: Random padding
	    
DWORD dwPadding = RANDOM_PADDING;
CPSetKeyParam(hProv, hSessionKey, KP_PADDING, (BYTE*)& dwPadding, 0);
	
2.3.1. Null Key Meshing
	    
DWORD dwMixmodeon = 0;
CPSetKeyParam(hProv, hSessionKey, KP_MIXMODE, (BYTE*)& dwMixmodeon, 0);
	
2.3.2. CryptoPro Key Meshing
	    
DWORD dwMixmodeon = 1;
CPSetKeyParam(hProv, hSessionKey, KP_MIXMODE, (BYTE*)& dwMixmodeon, 0);
	
3. HMAC_GOSTR3411
	    
CPCreateHash(hProv, CALG_GR3411_HMAC, hSessionKey, 0, &hHMAC);
// ...
CPHashData(hProv, hHMAC, pbInput, dwInputLen, 0);
// ...
CPGetHashParam(hProv, hHMAC, HP_HASHVAL, pbHMAC, &cbHMAC, 0);
	
4. PRF_GOSTR3411

	    
CPCreateHash(hProv, CALG_TLS1PRF, hKey, 0, &hHash);
CPSetHashParam(hProv, hHash, HP_TLS1PRF_LABEL, pbLabel, 0));
CPSetHashParam(hProv, hHash, HP_TLS1PRF_SEED, pbSeed, 0));
CPGetHashParam(hProv, hHash, HP_HASHVAL, pbPRF, &cbPRF, 0));
	

В протоколе TLS PRF используется также для порождения сессионных ключей из мастер-ключа CALG_TLS1_MASTER и объекта хэширования CALG_TLS1_MASTER_HASH.

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

5.1. VKO GOST R 34.10-94 В КриптоПро CSP версий 3.6.1 и выше не поддерживается.
5.2. VKO GOST R 34.10-2001
	    
ALG_ID alg = CALG_G28147;
// ...
CPImportKey(hProvSender, pbKeyBlobResponder, dwBlobLenResponder, hSenderKey, 0, &hAgreeKey);
CPSetKeyParam(hProv, hAgreeKey, KP_IV, pbIV, 0);
CPSetKeyParam(hProv, hAgreeKey, KP_ALGID, (BYTE*)&alg, 0);
	
6.1. GOST 28147-89 Key Wrap
	    
ALG_ID alg = CALG_SIMPLE_EXPORT;
// ...
CPSetKeyParam(hProv, hExportKey, KP_ALGID, (LPBYTE)&alg, 0);
// ...
CPExportKey(hProv, hWrappedKey, hExportKey, PRIVATEKEYBLOB, 0, (BYTE*)pbKeyBlob, &dwKeyBlobLen);
	
6.2. GOST 28147-89 Key Unwrap
	    
ALG_ID alg = CALG_SIMPLE_EXPORT;
// ...
CPSetKeyParam(hProv, hImportKey, KP_ALGID, (LPBYTE)&alg, 0);
// ...
CPImportKey(hProv, (BYTE*)pbKeyBlob, dwKeyBlobLen, hImportKey, 0, &hUnwrappedKey);
	
6.3. CryptoPro Key Wrap
	    
ALG_ID alg = CALG_PRO_EXPORT;
// ...
CPSetKeyParam(hProv, hExportKey, KP_ALGID, (LPBYTE)&alg, 0);
// ...
CPExportKey(hProv, hWrappedKey, hExportKey, PRIVATEKEYBLOB, 0, (BYTE*)pbKeyBlob, &dwKeyBlobLen);
	
6.4. CryptoPro Key Unwrap
	    
ALG_ID alg = CALG_PRO_EXPORT;
// ...
CPSetKeyParam(hProv, hImportKey, KP_ALGID, (LPBYTE)&alg, 0);
// ...
CPImportKey(hProv, (BYTE*)pbKeyBlob, dwKeyBlobLen, hImportKey, 0, &hUnwrappedKey);
	
6.5. CryptoPro KEK Diversification Algorithm Производится в рамках «6.3. CryptoPro Key Wrap» и «6.4. CryptoPro Key Unwrap».
7. Secret Key Diversification
	    
BYTE* DiversData;// Указатель на диверсифицирующую последовательность.
DWORD dwDiversLen;// Длина диверсифицирующей последовательности.
LPCRYPT_DIVERSBLOB Blob;
DWORD dwBlobLen;
// ...
dwBlobLen = sizeof(CRYPT_DIVERSBLOBHEADER)+sizeof(BLOBHEADER)+dwDiversLen;
Blob->DiversBlobHeader.BlobHeader.bType = (BYTE)DIVERSKEYBLOB;
Blob->DiversBlobHeader.BlobHeader.bVersion = (BYTE)BLOB_VERSION;
Blob->DiversBlobHeader.BlobHeader.reserved = (WORD)0;
Blob->DiversBlobHeader.BlobHeader.aiKeyAlg = CALG_G28147;
Blob->DiversBlobHeader.aiDiversAlgId = CALG_PRO_DIVERS;
Blob->DiversBlobHeader.dwDiversMagic = DIVERS_MAGIC;
Blob->DiversBlobHeader.cbDiversData = dwDiversLen;
CopyMemory(Blob->bDiversData,Diversdata,dwDiversLen);
CPImportKey(hProv, (BYTE*)pbDivers, dwBlobLen, hKey, 0, &hDiversKey);
	
8. Algorithm Parameters
  • id-Gost28147-89-TestParamSet
  • id-Gost28147-89-CryptoPro-A-ParamSet
  • id-Gost28147-89-CryptoPro-B-ParamSet
  • id-Gost28147-89-CryptoPro-C-ParamSet
  • id-Gost28147-89-CryptoPro-D-ParamSet

Установка: CPSetKeyParam(hProv, hSessionKey, KP_OID, (BYTE*) oid,0));

  • szOID_Gost28147_89_TestParamSet
  • szOID_Gost28147_89_CryptoPro_A_ParamSet
  • szOID_Gost28147_89_CryptoPro_B_ParamSet
  • szOID_Gost28147_89_CryptoPro_C_ParamSet
  • szOID_Gost28147_89_CryptoPro_D_ParamSet

8. Algorithm Parameters

  • id-GostR3411-94-TestParamSet
  • id-GostR3411-94-CryptoProParamSet

Установка: CPSetHashParam(hProv, hHash, HP_OID, (BYTE*)oid, 0));

  • szOID_GostR3411_94_TestParamSet
  • szOID_GostR3411_94_CryptoProParamSet

8. Algorithm Parameters

  • id-GostR3410-94-TestParamSet
  • id-GostR3410-94-CryptoPro-A-ParamSet
  • id-GostR3410-94-CryptoPro-B-ParamSet
  • id-GostR3410-94-CryptoPro-C-ParamSet
  • id-GostR3410-94-CryptoPro-D-ParamSet
  • id-GostR3410-94-CryptoPro-XchA-ParamSet
  • id-GostR3410-94-CryptoPro-XchB-ParamSet
  • id-GostR3410-94-CryptoPro-XchC-ParamSet

В КриптоПро CSP версий 3.6.1 и выше не поддерживается.

8. Algorithm Parameters

  • id-GostR3410-2001-TestParamSet
  • id-GostR3410-2001-CryptoPro-A-ParamSet
  • id-GostR3410-2001-CryptoPro-B-ParamSet
  • id-GostR3410-2001-CryptoPro-C-ParamSet
  • id-GostR3410-2001-CryptoPro-XchA-ParamSet
  • id-GostR3410-2001-CryptoPro-XchB-ParamSet

Установка: CPSetKeyParam(hProv, hPrivKey, KP_OID, (BYTE*) oid,0));

  • szOID_GostR3410_2001_TestParamSet
  • szOID_GostR3410_2001_CryptoPro_A_ParamSet
  • szOID_GostR3410_2001_CryptoPro_B_ParamSet
  • szOID_GostR3410_2001_CryptoPro_C_ParamSet
  • szOID_GostR3410_2001_CryptoPro_XchA_ParamSet
  • szOID_GostR3410_2001_CryptoPro_XchB_ParamSet

Вычисление PRF (к пункту "4. PRF_GOSTR3411")

	    
void GR3411_HMAC_(HCRYPTPROV hCont,HCRYPTKEY hKey,DATA_BLOB *pData,DWORD cData,BYTE *pbDigest,DWORD *pdwDigestLen)
{
    unsigned int i;
    HCRYPTHASH hHmac;
    DWORD q=32;

    if(!CPCreateHash(hCont, CALG_GR3411_HMAC,hKey,0,&hHmac)) 
        HandleError("Error in CreateHash");

    for (i=0;i<cData;i++)
        if(!CPHashData(hCont, hHmac,(LPBYTE)pData[i].pbData,pData[i].cbData,0)) 
            HandleError("Error during CPHashData");

    if(!CPGetHashParam(hCont, hHmac, HP_HASHVAL, (LPBYTE)pbDigest, &q, 0))
        HandleError("Error during CPGetHashParam");

    *pdwDigestLen = q;
     CPDestroyHash(hCont, hHmac);
}

void
GR3411_PRF (
    HCRYPTPROV  hCont,
    HCRYPTKEY   hKey,
    DATA_BLOB   *pData,
    DWORD        cData,
    BYTE        *pbDigest,
    DWORD       dwDigestLen)
{
    BYTE A1[32];
    DWORD hmac_len = sizeof(A1);
    LPBYTE out = pbDigest;
    DWORD olen = dwDigestLen;
    HRESULT res = S_OK;
    DATA_BLOB * pExtData = malloc((cData+1)*sizeof(DATA_BLOB));

    GR3411_HMAC_(hCont, hKey, pData, cData, A, &hmac_len);
    pExtData->pbData = A;
    pExtData->cbData = hmac_len;
    CopyMemory (pExtData+1, pData, cData*sizeof(DATA_BLOB));
    while(olen>hmac_len)
    {
        GR3411_HMAC_ (hCont, hKey, pExtData, 1+cData, out, &hmac_len);
        out+=hmac_len;
        olen-=hmac_len;
        GR3411_HMAC_(hCont, hKey, pExtData, 1, A, &hmac_len);
    }
    GR3411_HMAC_ (hCont, hKey, pExtData, 1+cData, A, &hmac_len);
    CopyMemory (out, A, olen);
    free(pExtData);
}