コード例 #1
0
// =========================================================================
// Cypher driver init function
// driverInfo - The structure to be initialized
NTSTATUS
ImpCypherDriverExtDetailsInit_v3(
    IN OUT CYPHER_DRIVER_INFO_v3* driverInfo
)
{
    NTSTATUS status = STATUS_SUCCESS;
    int idx = -1;

    DEBUGOUTCYPHERIMPL(DEBUGLEV_ENTER, (TEXT("ImpCypherDriverExtDetailsInit_v3\n")));


    // -- POPULATE DRIVER IDENTIFICATION --
    FREEOTFE_MEMZERO(driverInfo->DriverTitle, sizeof(driverInfo->DriverTitle));
    FREEOTFE_MEMCPY(
                  driverInfo->DriverTitle,
                  DRIVER_TITLE,
                  strlen(DRIVER_TITLE)
                 );

    driverInfo->DriverGUID = DRIVER_GUID;
    driverInfo->DriverVersionID = DRIVER_CYPHER_VERSION;


    // -- POPULATE CYPHERS SUPPORTED --
    driverInfo->CypherCount = CYPHERS_SUPPORTED;
    driverInfo->CypherDetails = FREEOTFE_MEMCALLOC(
                                                   sizeof(CYPHER_v3),
                                                   driverInfo->CypherCount
                                                  );


    // -- CAST5 --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->CypherDetails[idx].Title, MAX_CYPHER_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_CAST5,
                  strlen(DRIVER_CIPHER_TITLE_CAST5)
                 );

    driverInfo->CypherDetails[idx].Mode              = CYPHER_MODE_CBC;
    driverInfo->CypherDetails[idx].KeySizeUnderlying = 128;
    driverInfo->CypherDetails[idx].BlockSize         = (cast5_desc.block_length * 8);
    driverInfo->CypherDetails[idx].VersionID         = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID        = CIPHER_GUID_CAST5;
    driverInfo->CypherDetails[idx].KeySizeRequired   = driverInfo->CypherDetails[idx].KeySizeUnderlying;


    DEBUGOUTCYPHERIMPL(DEBUGLEV_EXIT, (TEXT("ImpCypherDriverExtDetailsInit_v3\n")));

    return status;
}
コード例 #2
0
// =========================================================================
// Hash driver init function
// driverInfo - The structure to be initialized
NTSTATUS
ImpHashDriverExtDetailsInit(
    IN OUT HASH_DRIVER_INFO* driverInfo
)
{
    NTSTATUS status = STATUS_SUCCESS;
    int idx = -1;

    DEBUGOUTHASHIMPL(DEBUGLEV_ENTER, (TEXT("ImpHashDriverExtDetailsInit\n")));


    // -- POPULATE DRIVER IDENTIFICATION --
    FREEOTFE_MEMZERO(driverInfo->DriverTitle, sizeof(driverInfo->DriverTitle));
    FREEOTFE_MEMCPY(
                  driverInfo->DriverTitle,
                  DRIVER_TITLE,
                  strlen(DRIVER_TITLE)
                 );

    driverInfo->DriverGUID = DRIVER_GUID;
    driverInfo->DriverVersionID = DRIVER_HASH_VERSION;


    // -- POPULATE HASHES SUPPORTED --
    driverInfo->HashCount = HASHES_SUPPORTED;
    driverInfo->HashDetails = FREEOTFE_MEMCALLOC(
                                                 sizeof(HASH),
                                                 driverInfo->HashCount
                                                );


    // -- Null --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->HashDetails[idx].Title, MAX_HASH_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->HashDetails[idx].Title,
                  DRIVER_HASH_TITLE_NULL,
                  strlen(DRIVER_HASH_TITLE_NULL)
                 );

    driverInfo->HashDetails[idx].Length = -1;
    driverInfo->HashDetails[idx].BlockSize = -1;
    driverInfo->HashDetails[idx].VersionID = DRIVER_HASH_IMPL_VERSION;
    driverInfo->HashDetails[idx].HashGUID = HASH_GUID_NULL;


    DEBUGOUTHASHIMPL(DEBUGLEV_EXIT, (TEXT("ImpHashDriverExtDetailsInit\n")));

    return status;
}
コード例 #3
0
// =========================================================================
// Copy contents of CYPHER_DRIVER_INFO_v3 struct to CYPHER_DRIVER_INFO_v1
// struct
// ! WARNING !
void
CopyCYPHER_DRIVER_INFO_v1ToCYPHER_DRIVER_INFO_v3(
    IN     CYPHER_DRIVER_INFO_v1*  Source,
    OUT    CYPHER_DRIVER_INFO_v3*  Dest
)
{
    unsigned int i;

    Dest->DriverGUID = Source->DriverGUID;

    FREEOTFE_MEMZERO(Dest->DriverTitle, sizeof(Dest->DriverTitle));
    FREEOTFE_MEMCPY(
                    Dest->DriverTitle,
                    Source->DriverTitle,
                    strlen(Source->DriverTitle)
                   );

    Dest->DriverVersionID = Source->DriverVersionID;
    Dest->CypherCount = Source->CypherCount;

    Dest->CypherDetails = FREEOTFE_MEMCALLOC( 
                                             Source->CypherCount,
                                             sizeof(Dest->CypherDetails[0])
                                            );
    for (i = 0; i < Source->CypherCount; i++)
        {
        CopyCYPHER_v1ToCYPHER_v3(
                                 &(Source->CypherDetails[i]),
                                 &(Dest->CypherDetails[i])
                                );
        }
}
コード例 #4
0
// =========================================================================
// Hash function
// driverInfo - The structure to be cleared down
NTSTATUS
ImpHashHashData(
    IN      GUID* HashGUID,
    IN      unsigned int DataLength,  // In bits
    IN      FREEOTFEBYTE* Data,
    IN OUT  unsigned int* HashLength,  // In bits
    OUT     FREEOTFEBYTE* Hash
)
{
    NTSTATUS status = STATUS_SUCCESS;
    WCHAR* tmpGUIDStr;

    DEBUGOUTHASHIMPL(DEBUGLEV_ENTER, (TEXT("ImpHashHashData\n")));
    if (IsEqualGUID(&HASH_GUID_NULL, HashGUID))
        {
        if (*HashLength < DataLength)
            {
            DEBUGOUTHASHIMPL(DEBUGLEV_ERROR, (TEXT("output hash length buffer too small (got: %d; need: %d)\n"),
                *HashLength,
                DataLength
                ));
            status = STATUS_BUFFER_TOO_SMALL;
            }
        else
            {
            FREEOTFE_MEMZERO(
                          Hash,
                          ((*HashLength) / 8)  // Convert bits to bytes
                         );

            FREEOTFE_MEMCPY(            
                          Hash,
                          Data,
                          (DataLength / 8)  // Convert bits to bytes
                         );

            *HashLength = DataLength;
            }
            
        }
    else
        {
        DEBUGOUTHASHIMPL(DEBUGLEV_ERROR, (TEXT("Driver doesn't recognise GUID\n")));
        GUIDToWCHAR(HashGUID, &tmpGUIDStr);
        DEBUGOUTHASHIMPL(DEBUGLEV_INFO, (TEXT("Hash passed in: %ls\n"), tmpGUIDStr));
        SecZeroAndFreeWCHARMemory(tmpGUIDStr);
        status = STATUS_INVALID_PARAMETER;
        }
        
    DEBUGOUTHASHIMPL(DEBUGLEV_EXIT, (TEXT("ImpHashHashData\n")));
      
    return status;
}
コード例 #5
0
// =========================================================================
// Internal function to carry out actual XOR encryption
NTSTATUS
_xor_data(
    IN      int KeyLength,  // In bits
    IN      FREEOTFEBYTE* Key,
    IN      int DataLength,  // In bytes
    IN      FREEOTFEBYTE* InData,
    OUT     FREEOTFEBYTE* OutData
)
{
    NTSTATUS status = STATUS_SUCCESS;
    int i;
    int keyOffset;
    int keyLenBytes;

    DEBUGOUTCYPHERIMPL(DEBUGLEV_ENTER, (TEXT("_xor_data\n")));

    keyLenBytes = (KeyLength / 8);
    // Sanity check, just in case we were passed an empty password!
    if (keyLenBytes != 0)
        {
        keyOffset = 0;
        for(i = 0; i < DataLength; i++, keyOffset++)
            {
            if (keyOffset >= keyLenBytes)
                {
                keyOffset = 0;
                }

            OutData[i] = InData[i] ^ Key[keyOffset];
            }
        }
    else
        {
        // No password? Just copy the data from the input buffer to the output
        FREEOTFE_MEMCPY(
                      OutData,
                      InData,
                      DataLength
                     );
        }

    DEBUGOUTCYPHERIMPL(DEBUGLEV_EXIT, (TEXT("_xor_data\n")));

    return status;
}
コード例 #6
0
// =========================================================================
// Copy contents of CYPHER_v3 struct to CYPHER_v1 struct
void
CopyCYPHER_v3ToCYPHER_v1(
    IN     CYPHER_v3*  Source,
    OUT    CYPHER_v1*  Dest
)
{
    FREEOTFE_MEMZERO(Dest->Title, sizeof(Dest->Title));
    FREEOTFE_MEMCPY(
                    Dest->Title,
                    Source->Title,
                    strlen(Source->Title)
                   );

    Dest->BlockSize         = Source->BlockSize;
    Dest->VersionID         = Source->VersionID;
    Dest->CypherGUID        = Source->CypherGUID;
    Dest->KeySizeUnderlying = Source->KeySizeRequired;
    Dest->Mode              = Source->Mode;
}
コード例 #7
0
// =========================================================================
// Copy contents of CYPHER_v1 struct to CYPHER_v3 struct
void
CopyCYPHER_v1ToCYPHER_v3(
    IN     CYPHER_v1*  Source,
    OUT    CYPHER_v3*  Dest
)
{
    FREEOTFE_MEMZERO(Dest->Title, sizeof(Dest->Title));
    FREEOTFE_MEMCPY(
                    Dest->Title,
                    Source->Title,
                    strlen(Source->Title)
                   );

    Dest->BlockSize         = Source->BlockSize;
    Dest->VersionID         = Source->VersionID;
    Dest->CypherGUID        = Source->CypherGUID;
    Dest->KeySizeUnderlying = Source->KeySizeUnderlying;
    Dest->Mode              = Source->Mode;

    // Values which don't exist in the earlier struct...
    Dest->KeySizeRequired   = Dest->KeySizeUnderlying;
}
コード例 #8
0
// =========================================================================
// Cypher driver init function
// driverInfo - The structure to be initialized
NTSTATUS
ImpCypherDriverExtDetailsInit_v3(
    IN OUT CYPHER_DRIVER_INFO_v3* driverInfo
)
{
    NTSTATUS status = STATUS_SUCCESS;
    int idx = -1;

    DEBUGOUTCYPHERIMPL(DEBUGLEV_ENTER, (TEXT("ImpCypherDriverExtDetailsInit_v3\n")));


    // -- POPULATE DRIVER IDENTIFICATION --
    FREEOTFE_MEMZERO(driverInfo->DriverTitle, sizeof(driverInfo->DriverTitle));
    FREEOTFE_MEMCPY(
                  driverInfo->DriverTitle,
                  DRIVER_TITLE,
                  strlen(DRIVER_TITLE)
                 );

    driverInfo->DriverGUID = DRIVER_GUID;
    driverInfo->DriverVersionID = DRIVER_CYPHER_VERSION;


    // -- POPULATE CYPHERS SUPPORTED --
    driverInfo->CypherCount = CYPHERS_SUPPORTED;
    driverInfo->CypherDetails = FREEOTFE_MEMCALLOC(
                                                   sizeof(CYPHER_v3),
                                                   driverInfo->CypherCount
                                                  );


    // -- Twofish-256 XTS --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->CypherDetails[idx].Title, MAX_CYPHER_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_256_XTS,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_256_XTS)
                 );

    driverInfo->CypherDetails[idx].Mode              = CYPHER_MODE_XTS;
    driverInfo->CypherDetails[idx].KeySizeUnderlying = 256;
    driverInfo->CypherDetails[idx].BlockSize         = TWOFISH_BLOCK_SIZE;
    driverInfo->CypherDetails[idx].VersionID         = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID        = CIPHER_GUID_TWOFISH_256_XTS;
    driverInfo->CypherDetails[idx].KeySizeRequired   = (2 * driverInfo->CypherDetails[idx].KeySizeUnderlying);

    // -- Twofish-192 XTS --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->CypherDetails[idx].Title, MAX_CYPHER_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_192_XTS,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_192_XTS)
                 );

    driverInfo->CypherDetails[idx].Mode              = CYPHER_MODE_XTS;
    driverInfo->CypherDetails[idx].KeySizeUnderlying = 192;
    driverInfo->CypherDetails[idx].BlockSize         = TWOFISH_BLOCK_SIZE;
    driverInfo->CypherDetails[idx].VersionID         = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID        = CIPHER_GUID_TWOFISH_192_XTS;
    driverInfo->CypherDetails[idx].KeySizeRequired   = (2 * driverInfo->CypherDetails[idx].KeySizeUnderlying);

    // -- Twofish-128 XTS --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->CypherDetails[idx].Title, MAX_CYPHER_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_128_XTS,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_128_XTS)
                 );

    driverInfo->CypherDetails[idx].Mode              = CYPHER_MODE_XTS;
    driverInfo->CypherDetails[idx].KeySizeUnderlying = 128;
    driverInfo->CypherDetails[idx].BlockSize         = TWOFISH_BLOCK_SIZE;
    driverInfo->CypherDetails[idx].VersionID         = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID        = CIPHER_GUID_TWOFISH_128_XTS;
    driverInfo->CypherDetails[idx].KeySizeRequired   = (2 * driverInfo->CypherDetails[idx].KeySizeUnderlying);


    // -- Twofish-256 CBC --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->CypherDetails[idx].Title, MAX_CYPHER_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_256_CBC,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_256_CBC)
                 );

    driverInfo->CypherDetails[idx].Mode              = CYPHER_MODE_CBC;
    driverInfo->CypherDetails[idx].KeySizeUnderlying = 256;
    driverInfo->CypherDetails[idx].BlockSize         = TWOFISH_BLOCK_SIZE;
    driverInfo->CypherDetails[idx].VersionID         = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID        = CIPHER_GUID_TWOFISH_256_CBC;
    driverInfo->CypherDetails[idx].KeySizeRequired   = driverInfo->CypherDetails[idx].KeySizeUnderlying;

    // -- Twofish-192 CBC --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->CypherDetails[idx].Title, MAX_CYPHER_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_192_CBC,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_192_CBC)
                 );

    driverInfo->CypherDetails[idx].Mode              = CYPHER_MODE_CBC;
    driverInfo->CypherDetails[idx].KeySizeUnderlying = 192;
    driverInfo->CypherDetails[idx].BlockSize         = TWOFISH_BLOCK_SIZE;
    driverInfo->CypherDetails[idx].VersionID         = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID        = CIPHER_GUID_TWOFISH_192_CBC;
    driverInfo->CypherDetails[idx].KeySizeRequired   = driverInfo->CypherDetails[idx].KeySizeUnderlying;

    // -- Twofish-128 CBC --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->CypherDetails[idx].Title, MAX_CYPHER_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_128_CBC,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_128_CBC)
                 );

    driverInfo->CypherDetails[idx].Mode              = CYPHER_MODE_CBC;
    driverInfo->CypherDetails[idx].KeySizeUnderlying = 128;
    driverInfo->CypherDetails[idx].BlockSize         = TWOFISH_BLOCK_SIZE;
    driverInfo->CypherDetails[idx].VersionID         = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID        = CIPHER_GUID_TWOFISH_128_CBC;
    driverInfo->CypherDetails[idx].KeySizeRequired   = driverInfo->CypherDetails[idx].KeySizeUnderlying;


    DEBUGOUTCYPHERIMPL(DEBUGLEV_EXIT, (TEXT("ImpCypherDriverExtDetailsInit_v3\n")));

    return status;
}
コード例 #9
0
// =========================================================================
// This is the PBKDF2 PRF function "F"  
// The PRF used is HMAC
NTSTATUS
PBKDF2_F(
    IN      PDataHashFn FnHash,
    IN      GUID HashGUID,
    IN      HASH HashDetails,
    IN      unsigned int PLength,  // In bits
    IN      unsigned char* P,
    IN      unsigned int SLength,  // In bits
    IN      unsigned char* S,
    IN      unsigned int c,
    IN      unsigned int i,
    OUT     unsigned char* T_
)
{
    NTSTATUS status;
    unsigned char* U_;
    unsigned char* tmpU_Buffer;
    unsigned char* saltAndCount;
    unsigned int hLen;  // In *bytes*
    unsigned int hLenBits;  // In *Bits*
    unsigned int actualHLenBits;  // In *bits*
    unsigned int saltAndCountSizeBytes;  // In *bytes*
    unsigned int j, k;


    DEBUGOUTKDFDRV(DEBUGLEV_ENTER, ("PBKDF2_F\n"));


    status = STATUS_SUCCESS;

    U_ = NULL;
    tmpU_Buffer = NULL;
    saltAndCount = NULL;


    // From PKCS#5:

    // function F is defined as the exclusive-or sum of the
    // first c iterates of the underlying pseudorandom function PRF
    // applied to the password P and the concatenation of the salt S
    // and the block index i:
    //
    //           F (P, S, c, i) = U_1 \xor U_2 \xor ... \xor U_c
    //
    // where
    //           U_1 = PRF (P, S || INT (i)) ,
    //           U_2 = PRF (P, U_1) ,
    //           ...
    //           U_c = PRF (P, U_{c-1}) .
    //
    // Here, INT (i) is a four-octet encoding of the integer i, most
    // significant octet first.


    DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("Iterations requested: %d\n", c));

    // This is PBKDF2 based on HMAC - the HMAC function returns the same
    // number of bytes as is in the hash it uses
    hLen = (HashDetails.Length / 8);
    hLenBits = HashDetails.Length;

    // Convert bits to bytes, and add 4 (specified in PKCS #5) for the "i"
    saltAndCountSizeBytes = ((SLength / 8) + 4);
    saltAndCount = FREEOTFE_MEMALLOC(saltAndCountSizeBytes);
    FREEOTFE_MEMCPY(
                    saltAndCount,
                    S,
                    (SLength / 8)
                    );
    // Concatenate the salt
    // Note: *Bitwise* AND :)
    saltAndCount[ (SLength / 8)   ] = ((i & 0xFF000000) / 0x01000000);
    saltAndCount[((SLength / 8)+1)] = ((i & 0x00FF0000) / 0x00010000);
    saltAndCount[((SLength / 8)+2)] = ((i & 0x0000FF00) / 0x00000100);
    saltAndCount[((SLength / 8)+3)] = ((i & 0x000000FF) / 0x00000001);

    U_ = FREEOTFE_MEMALLOC(hLen);
    tmpU_Buffer = FREEOTFE_MEMALLOC(hLen);

    // Process U_1
    if (NT_SUCCESS(status))
        {
        actualHLenBits = hLenBits;
        DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("First HMAC: SLength = %d\n", SLength));
        DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("First HMAC: actualHLenBits = %d\n", actualHLenBits));
        if (!(NT_SUCCESS(ImplMACHMAC(
                                    FnHash,
                                    HashGUID,
                                    HashDetails,
                                    -1,  // Retrieve full HMAC
                                    PLength,
                                    P,
                                    (saltAndCountSizeBytes * 8), // In *bits*
                                    saltAndCount,

                                    &actualHLenBits,  // In bits
                                    U_
                                ))))
            {
            DEBUGOUTKDFDRV(DEBUGLEV_ERROR, ("First call to HMAC function \"F\" failed.\n"));
            status = STATUS_INTERNAL_ERROR;
            }
        else
            {
            // Sanity check
            if (actualHLenBits != hLenBits)
                {
                DEBUGOUTKDFDRV(DEBUGLEV_ERROR, ("HMAC function didn't return expected number of bits?!\n"));
                status = STATUS_INTERNAL_ERROR;
                }
            else
                {
                // Copy to output buffer - note that this will be XORd if
                // there's more c>1
                FREEOTFE_MEMCPY(
                                T_,
                                U_,
                                (actualHLenBits / 8)
                                );
                }
            }
        }


    // Process subsequent U_n
    if (NT_SUCCESS(status))
        {
        for(j = 2; j <= c; j++)
            {
            actualHLenBits = hLenBits;
            DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("Subsequent HMAC: actualHLenBits = %d\n", actualHLenBits));
            if (!(NT_SUCCESS(ImplMACHMAC(
                                        FnHash,
                                        HashGUID,
                                        HashDetails,
                                        -1,  // Retrieve full HMAC
                                        PLength,
                                        P,
                                        hLenBits,  // In bits
                                        U_,

                                        &actualHLenBits,  // In bits
                                        tmpU_Buffer
                                    ))))
                {
                DEBUGOUTKDFDRV(DEBUGLEV_ERROR, ("Call to HMAC function \"F\" failed.\n"));
                status = STATUS_INTERNAL_ERROR;
                break;
                }
            else
                {
                // Move from temp buffer to U_ buffer
                DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("Copying (%d)\n", hLen));
                FREEOTFE_MEMCPY(
                            U_,
                            tmpU_Buffer,
                            hLen
                            );

                // XOR with previous iteration
                DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("XORing...\n"));
                for(k = 0; k < hLen; k++)
                    {
                    T_[k] ^= U_[k];
                    }
                DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("OK.\n"));
                }
            }
        }


    // Note: No need to set the output "T_" explicitly, as this is done during
    //       processing


    if (tmpU_Buffer != NULL)
        {
        SecZeroMemory(tmpU_Buffer, hLen);
        FREEOTFE_FREE(tmpU_Buffer);
        }
    if (U_ != NULL)
        {
        SecZeroMemory(U_, hLen);
        FREEOTFE_FREE(U_);
        }
    if (saltAndCount != NULL)
        {
        SecZeroMemory(saltAndCount, saltAndCountSizeBytes);
        FREEOTFE_FREE(saltAndCount);
        }



    DEBUGOUTKDFDRV(DEBUGLEV_EXIT, ("PBKDF2_F\n"));

    return status;
}
コード例 #10
0
// =========================================================================
// Generate PBKDF2 key based on HMAC
NTSTATUS
ImplKDFPBKDF2(
    IN      PDataHashFn FnHash,
    IN      GUID HashGUID,
    IN      HASH HashDetails,
    IN      unsigned int PLength,  // In bits
    IN      unsigned char* P,
    IN      unsigned int SLength,  // In bits
    IN      unsigned char* S,
    IN      unsigned int c,  // Iterations
    IN      int dkLenBits,  // In *bits*

    IN OUT  unsigned int* DerivedKeyLength,  // In bits
    OUT     unsigned char* DerivedKey
)
{
    NTSTATUS status;

    unsigned int i;

    unsigned int l;
//    unsigned int r;  // In *bytes*
    unsigned int dkLen;  // In *bytes*
    unsigned int hLen;  // In *bytes*

    unsigned char* T_;
    unsigned int T_SizeBytes; // In *bytes*


    DEBUGOUTKDFDRV(DEBUGLEV_ENTER, ("ImplKDFPBKDF2\n"));

    status = STATUS_SUCCESS;

    T_ = NULL;
    T_SizeBytes = 0;


    // Sanity check
    // This should be picked up by the caller; this is belt & braces
    if (
        (HashDetails.BlockSize <= 0) ||
        (HashDetails.Length <= 0)
       )
        {
        DEBUGOUTKDFDRV(DEBUGLEV_ERROR, ("PBKDF2 implementation called with a hash that has an undefined/zero length/blocksize\n"));
        status = STATUS_INTERNAL_ERROR;
        }
    else
        {
        // This is PBKDF2 based on HMAC - the HMAC function returns the same
        // number of bytes as is in the hash it uses
        hLen = (HashDetails.Length / 8);
        }


    if (dkLenBits < 0)
        {
        dkLenBits = DEFAULT_PBKDF2_KEY_SIZE;
        }
    dkLen = (dkLenBits / 8);
    DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("dkLenBits = %d bits\n", dkLenBits));
    DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("dkLen = %d bytes\n", dkLen));


    // Sanity check
    // This should be picked up by the caller; this is belt & braces
    if ((unsigned int)dkLenBits > *DerivedKeyLength)
        {
        // The output buffer can store the requested number of bits, right?
        // Note that dkLenBits can be -ve to indicate the full key length is to be
        // returned
        DEBUGOUTKDFDRV(DEBUGLEV_ERROR, ("Requested number of bits is larger than supplied buffer\n"));
        status = STATUS_BUFFER_TOO_SMALL;
        }


    // Step 1
    // 1. If dkLen > (2^32 - 1) * hLen, output "derived key too long" and
    //    stop.

    DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("PBKDF2 Step 1: n/a; skipped...\n"));
    // (Step skipped - because dkLen is an integer, it can never be more
    // than 2^(31-1) - far less than (2^32 - 1) * hLen)


    // Step 2
    // 2. Let l be the number of hLen-octet blocks in the derived key,
    //    rounding up, and let r be the number of octets in the last
    //    block:
    //
    //              l = CEIL (dkLen / hLen) ,
    //              r = dkLen - (l - 1) * hLen .
    //
    //    Here, CEIL (x) is the "ceiling" function, i.e. the smallest
    //    integer greater than, or equal to, x.
    if (NT_SUCCESS(status))
        {
        DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("PBKDF2 Step 2: Executing...\n"));
        // Note: div always rounds down towards zero
        l = (dkLen / hLen);
        // Because div always rounds down towards zero, we may need to increment it
        // by one
        if (dkLen > (l * hLen))
            {
            l++;
            }


        DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("dkLen = %d bytes\n", dkLen));
        DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("hLen = %d bytes\n", hLen));
        DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("l = %d\n", l));
//        r = dkLen - ((l - 1) * hLen);
//        DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("r = %d bytes\n", r));
        }




    // Step 3
    // 3. For each block of the derived key apply the function F
    if (NT_SUCCESS(status))
        {
        DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("PBKDF2 Step 3: Executing...\n"));
        T_SizeBytes = (hLen * l);
        T_ = FREEOTFE_MEMALLOC(T_SizeBytes);

        for(i = 1; i<=l; i++)
            {
            DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("Loop: i = %d\n", i));
            if (!(NT_SUCCESS(PBKDF2_F(
                                    FnHash,
                                    HashGUID,
                                    HashDetails,

                                    PLength,
                                    P,
                                    SLength,
                                    S,
                                    c,
                                    i,

                                    // This is correct (-1), as our loop starts
                                    // from 1
                                    &T_[((i-1) * hLen)]
                                ))))
                {
                DEBUGOUTKDFDRV(DEBUGLEV_ERROR, ("Call to PBKDF2 function \"F\" failed.\n"));
                status = STATUS_INTERNAL_ERROR;
                break;
                }
            }
        }



    // Step 4
    // 4. Concatenate the blocks and extract the first dkLen octets to
    //    produce a derived key DK:
    //
    //              DK = T_1 || T_2 ||  ...  || T_l<0..r-1>
    if (NT_SUCCESS(status))
        {
        DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("PBKDF2 Step 4: Executing...\n"));
        FREEOTFE_MEMCPY(
                      DerivedKey,
                      T_,
                      (dkLenBits / 8)
                     );
        }


    // Step 5
    // 5. Output the derived key DK.
    if (NT_SUCCESS(status))
        {
        DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("PBKDF2 Step 5: Executing...\n"));
        *DerivedKeyLength = dkLenBits;
        }


    // Cleanup...
    DEBUGOUTKDFDRV(DEBUGLEV_INFO, ("Freeing off any used buffers...\n"));

    if (T_ != NULL)
        {
        SecZeroMemory(T_, T_SizeBytes);
        FREEOTFE_FREE(T_);
        }

    DEBUGOUTKDFDRV(DEBUGLEV_EXIT, ("ImplKDFPBKDF2\n"));

    return status;
}
コード例 #11
0
// =========================================================================
// Generate block IV: Hashed block ID
NTSTATUS
GenerateBlockIV_HashedSectorID(
    IN      DEVICE_CONTEXT* devContext,
    IN      LARGE_INTEGER blockID,
    IN      unsigned int blockIDBits,  // The number of bits in blockID to be used
                                       // Set to either 32 or 64 bits
    IN      unsigned int blockIVLength,  // The size of the required IV (and length of
	                                     // "blockIV"), in bits
    OUT     unsigned char* blockIV  // Pointer to where the IV should be written
                                    // Note: Caller must pre-initialise to 0x00s
)
{
    NTSTATUS status;
    unsigned char hashOutput[FREEOTFE_MAX_HASH_LENGTH / 8];  // Divide by 8 to get bytes from bits
    unsigned int hashLength;

    DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_ENTER, (TEXT("GenerateBlockIV_HashedSectorID\n")));

    status = STATUS_SUCCESS;

    // Generate the IV...
    hashLength = sizeof(hashOutput) * 8;  // Multiply by 8 to get size of buffer in *bits*

    DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("%d bit block IDs being used\n"), blockIDBits));
    if (blockIDBits == 32)
        {
        // Only use the LSB 32 bits        
        status = DataHash(
                          &(devContext->IVHash),
                          blockIDBits,  // Size in bits
                          (FREEOTFEBYTE*)&(blockID.LowPart),
                          &hashLength,  // Size in bits
                          (FREEOTFEBYTE*)&hashOutput
                         );
        }
    else if (blockIDBits == 64)
        {
        // Use the full 64-bit block ID
        status = DataHash(
                          &(devContext->IVHash),
                          blockIDBits,  // Size in bits
                          (FREEOTFEBYTE*)&blockID,
                          &hashLength,  // Size in bits
                          (FREEOTFEBYTE*)&hashOutput
                         );
        }
    else
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("blockIDBits must be set to either 32 or 64 (set to: %d)\n"), blockIDBits));
        status = STATUS_INTERNAL_ERROR; 
        }


    if (!(NT_SUCCESS(status)))
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Failed to hash block ID to form IV.\n")));
        }
    else
        {
        // Copy the first 'n' bits of the hash to be the block IV
        FREEOTFE_MEMCPY(            
                      blockIV,
                      &hashOutput,
                      ((min(blockIVLength, hashLength)) / 8)  // Divide by 8 to get bytes from bits
                      );
        }


    DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_EXIT, (TEXT("GenerateBlockIV_HashedSectorID\n")));

    return status;
}
コード例 #12
0
// =========================================================================
// Generate block IV: ESS_IV
// From Linux's dm_crypt kernel source (drivers/md/dm-crypt.c):
//  * ess_iv: "encrypted sector|salt initial vector", the sector number is
//  *         encrypted with the bulk cipher using a salt as key. The salt
//  *         should be derived from the bulk cipher's key via hashing.
// i.e.:
//   Let salt = malloc(IV length) bits of memory (This is done when first mounting)
//   Set salt to be hash(key) (This is done when first mounting)
//   Encrypt the n-bit block ID using the above salt as the key
//     - Note: Linux's dm-crypt volumes use 64 bit block IDs
//   Use the result as the IV
NTSTATUS
GenerateBlockIV_ESSIV(
    IN      DEVICE_CONTEXT* devContext,
    IN      LARGE_INTEGER blockID,
    IN      unsigned int blockIDBits,  // The number of bits in blockID to be used
                                        // Set to either 32 or 64 bits
    IN      unsigned int blockIVLength,  // The size of the required IV (and length of
	                                      // "blockIV"), in bits
    OUT     unsigned char* blockIV  // Pointer to where the IV should be written
                                     // Note: Caller must pre-initialise to 0x00s
)
{
    NTSTATUS status;
    unsigned char cypherInput[FREEOTFE_MAX_CYPHER_BLOCKSIZE / 8];  // Divide by 8 to get bytes from bits
    unsigned char cypherOutput[FREEOTFE_MAX_CYPHER_BLOCKSIZE / 8];  // Divide by 8 to get bytes from bits
    unsigned int encryptLengthBytes;
    unsigned int useBitsFromHash;


    DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_ENTER, (TEXT("GenerateBlockIV_ESSIV\n")));

    status = STATUS_SUCCESS;

    // Generate the IV...
    DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("%d bit block IDs being used\n"), blockIDBits));
    DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("Block ID is: %lld\n"), blockID.QuadPart));
    FREEOTFE_MEMZERO(&cypherInput, sizeof(cypherInput));
    if (blockIDBits == 32)
        {
        // Cast the IV (unsigned cast) as a ptr to a ULONG, then dereference to set
        *(ULONG*)cypherInput                 = blockID.LowPart;
        }
    else if (blockIDBits == 64)
        {
        // Cast the IV (unsigned cast) as a ptr to a ULONG, then dereference to set
        *(ULONG*)cypherInput                 = blockID.LowPart;
        // Cast the IV (unsigned cast) as a ptr to a ULONG, then dereference to set
        // The IV is offset by sizeof(ULONG), since the IV is in unsigned chars,
        // before it is cast
        *(ULONG*)(cypherInput+sizeof(ULONG)) = blockID.HighPart;
        }
    else
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("blockIDBits must be set to either 32 or 64 (set to: %d)\n"), blockIDBits));
        status = STATUS_INTERNAL_ERROR; 
        }

    encryptLengthBytes = (devContext->IVCypher.Details.BlockSize / 8);
    // Allow for IV cyphers with a variable length blocksize
    if (devContext->IVCypher.Details.BlockSize < 0) 
        {
        encryptLengthBytes = (blockIDBits / 8);
        }

    if (NT_SUCCESS(status))
        {
        // Note: We use a NULL IV for this encryption

        if (devContext->IVCypher.FnEncryptSector != NULL) 
            {
		    status = devContext->IVCypher.FnEncryptSector(
                                                    &devContext->IVCypher.CypherGUID,
                                                    blockID,
                                                    devContext->EncryptionBlockSize,
                                                    devContext->ESSIVKeyLength,
                                                    (char*)devContext->ESSIVKey,
                                                    (char*)devContext->ESSIVKeyASCII,
                                                    0,
                                                    NULL,
                                                    encryptLengthBytes,
                                                    (char*)&cypherInput,
                                                    (char*)&cypherOutput
                                                   );
            }
        else if (devContext->IVCypher.FnEncrypt != NULL) 
            {
		    status = devContext->IVCypher.FnEncrypt(
                                                    &devContext->IVCypher.CypherGUID,
                                                    devContext->ESSIVKeyLength,
                                                    (char*)devContext->ESSIVKey,
                                                    (char*)devContext->ESSIVKeyASCII,
                                                    0,
                                                    NULL,
                                                    encryptLengthBytes,
                                                    (char*)&cypherInput,
                                                    (char*)&cypherOutput
                                                   );
            }
        else
            {
            DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("No encryption function?!\n")));
            status = STATUS_INVALID_PARAMETER;
            }

        if (!(NT_SUCCESS(status)))
            {
            DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("ESSIV encrypt failed\n")));
            }

        }


    if (!(NT_SUCCESS(status)))
        {
        DEBUGOUTMAINDRV(DEBUGLEV_ERROR, (TEXT("Failed to ESSIV to form IV.\n")));
        }
    else
        {
        // The number of useful bits we can take from the hash
        useBitsFromHash = (min(blockIVLength, (encryptLengthBytes * 8)));
        DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_INFO, (TEXT("Number of useful bits from cypher: %d\n"), useBitsFromHash));

        // If the block IV is larger than the number of bits the hash returns, ensure that
        // the remainder of the block IV is blanked
        if (useBitsFromHash < blockIVLength)
            {
            FREEOTFE_MEMZERO(blockIV, (blockIVLength / 8));
            }
                                                
        // Copy the first 'n' bits of the hash to be the block IV
        FREEOTFE_MEMCPY(            
                      blockIV,
                      &cypherOutput,
                      (useBitsFromHash / 8)  // Divide by 8 to get bytes from bits
                      );
        }

    DEBUGOUTMAINDRV(DEBUGLEV_VERBOSE_EXIT, (TEXT("GenerateblockIV_ESSIV\n")));

    return status;
}
コード例 #13
0
// =========================================================================
// Generate HMAC
NTSTATUS
ImplMACHMAC(
    IN      PDataHashFn FnHash,
    IN      GUID HashGUID,
    IN      HASH HashDetails,
    IN      int tBits,  // In *bits*
    IN      unsigned int KLength,  // In bits
    IN      unsigned char* K,
    IN      unsigned int textLength,  // In bits
    IN      unsigned char* text,

    IN OUT  unsigned int* MACLength,  // In bits
    OUT     unsigned char* MAC
)
{
    NTSTATUS status;

    unsigned int KLengthBytes;  // In *bytes*

    unsigned int B;  // In *bytes*
    unsigned int i;
    unsigned char* Kzero;
    
    unsigned char* step2TmpBuf;
    unsigned char* step4OutBuf;
    unsigned char* step5OutBuf;
    unsigned char* step6OutBuf;
    unsigned char* step7OutBuf;
    unsigned char* step8OutBuf;
    unsigned char* step9OutBuf;

    unsigned int step2TmpBufSize;  // In *bytes*
    unsigned int step5OutBufSize;  // In *bytes*
    unsigned int step6OutBufSize;  // In *bytes*
    unsigned int step8OutBufSize;  // In *bytes*
    unsigned int step9OutBufSize;  // In *bytes*

    unsigned int step6ValidBits;
    unsigned int step9ValidBits;

    unsigned int hashValidBits;
    unsigned int hashUseLenBytes;

    unsigned int outputBits;


    DEBUGOUTMACDRV(DEBUGLEV_ENTER, ("ImplMACHMAC\n"));

    status = STATUS_SUCCESS;

    Kzero = NULL;

    step4OutBuf = NULL;
    step5OutBuf = NULL;
    step6OutBuf = NULL;
    step7OutBuf = NULL;
    step8OutBuf = NULL;
    step9OutBuf = NULL;

    // Sanity checks
    // This should be picked up by the caller; this is belt & braces
    if (
        (HashDetails.BlockSize <= 0) ||
        (HashDetails.Length <= 0)
       )
        {
        DEBUGOUTMACDRV(DEBUGLEV_ERROR, ("HMAC implementation called with a hash that has an undefined blocksize/output\n"));
        status = STATUS_INTERNAL_ERROR;
        }


    B = (HashDetails.BlockSize / 8);
    KLengthBytes = (KLength / 8);


    // Compute the HMAC...

    // ---------
    // FIPS-198 Steps 1-3
    // i.e. Set Kzero to be a "B" length string
    if (NT_SUCCESS(status))
        {
        Kzero = FREEOTFE_MEMALLOC(B);    

        if (KLengthBytes == B)
            {
            // Step 1
            DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 1: Executing...\n"));
            // Set K0 = K
            FREEOTFE_MEMCPY(
                            Kzero,
                            K,
                            B
                           );
            DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 2: n/a; skipped\n"));
            DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 3: n/a; skipped\n"));
            }
        else if (KLengthBytes > B)
            {
            // Step 2
            DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 1: n/a; skipped\n"));
            DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 2: Executing...\n"));
            // Hash K to get a hashlength string, then pad out to B bytes
            // with NULLs
            step2TmpBufSize = (HashDetails.Length / 8);   // Divide by 8 to get bytes from bits
            hashValidBits = HashDetails.Length;  // In *bits*
            DEBUGOUTMACDRV(DEBUGLEV_INFO, ("Allocating tmp buffer (%d bytes)...\n", step2TmpBufSize));
            step2TmpBuf = FREEOTFE_MEMALLOC(step2TmpBufSize);

            status = FnHash(
					        &HashGUID,
					        KLength,
					        K,
					        &hashValidBits,
					        step2TmpBuf
                        );
            if (!(NT_SUCCESS(status)))
                {
                DEBUGOUTMACDRV(DEBUGLEV_ERROR, ("HMAC Step 2: Call to hash driver failed\n"));
                status = STATUS_INTERNAL_ERROR;
                }
            else
                {
                hashUseLenBytes = min(B, (hashValidBits / 8));
                DEBUGOUTMACDRV(DEBUGLEV_INFO, ("Hash output: %d bits (%d bytes)...\n", hashValidBits, (hashValidBits / 8)));
                DEBUGOUTMACDRV(DEBUGLEV_INFO, ("Using first %d bytes...\n", hashUseLenBytes));
                // Copy the hash value to K0
                FREEOTFE_MEMCPY(
                    Kzero,
                    step2TmpBuf,
                    hashUseLenBytes
                    );
                DEBUGOUTMACDRV(DEBUGLEV_INFO, ("Step 2 Kzero: Padding end with NULLs (%d bytes of nulls)...\n", (B - hashUseLenBytes)));
                // Pad K0 with NULLs
                SecZeroMemory(&Kzero[hashUseLenBytes], (B - hashUseLenBytes));
                }            

            DEBUGOUTMACDRV(DEBUGLEV_INFO, ("Zeroing and freeing hash buffer\n"));
            SecZeroMemory(step2TmpBuf, step2TmpBufSize);
            FREEOTFE_FREE(step2TmpBuf);
            DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 3: n/a; skipped\n"));
            }
        else
            {
            // Step 3
            DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 1: n/a; skipped\n"));
            DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 2: n/a; skipped\n"));
            DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 3: Executing...\n"));
            FREEOTFE_MEMCPY(
                Kzero,
                K,
                KLengthBytes
                );
            DEBUGOUTMACDRV(DEBUGLEV_INFO, ("Step 3 Kzero: Padding end with NULLs (%d bytes of nulls)...\n", (B - KLengthBytes)));
            // Pad K0 with NULLs
            SecZeroMemory(&Kzero[KLengthBytes], (B - KLengthBytes));
            }
        }

    // ---------
    // FIPS-198 Step 4
    // XOR K0 with ipad (0x36)
    if (NT_SUCCESS(status))
        {
        DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 4: Executing...\n"));
        step4OutBuf = FREEOTFE_MEMALLOC(B);
        for (i = 0; i < B; i++)
            {
            step4OutBuf[i] = Kzero[i] ^ 0x36;
            }
        }


    // ---------
    // FIPS-198 Step 5
    // Append input text onto the end of the output from step 4
    if (NT_SUCCESS(status))
        {
        DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 5: Executing...\n"));
        step5OutBufSize = (B + (textLength / 8));
        step5OutBuf = FREEOTFE_MEMALLOC(step5OutBufSize);
        FREEOTFE_MEMCPY(
            step5OutBuf,
            step4OutBuf,
            B
            );
        FREEOTFE_MEMCPY(
            &step5OutBuf[B],
            text,
            (textLength / 8)
            );
        }

    // ---------
    // FIPS-198 Step 6
    // Apply H to the output from step 5
    if (NT_SUCCESS(status))
        {
        DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 6: Executing...\n"));
        step6ValidBits = HashDetails.Length;
        step6OutBufSize = (step6ValidBits / 8);
        step6OutBuf = FREEOTFE_MEMALLOC(step6OutBufSize);
        status = FnHash(
					    &HashGUID,
					    (step5OutBufSize * 8),
					    step5OutBuf,
					    &step6ValidBits,
					    step6OutBuf
                    );
        }

    // ---------
    // FIPS-198 Step 7
    // XOR K0 with opad (0x5C)
    if (NT_SUCCESS(status))
        {
        DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 7: Executing...\n"));
        step7OutBuf = FREEOTFE_MEMALLOC(B);
        for (i = 0; i < B; i++)
            {
            step7OutBuf[i] = Kzero[i] ^ 0x5C;
            }
        }

    // ---------
    // FIPS-198 Step 8
    // Append the result from step 6 to step 7
    if (NT_SUCCESS(status))
        {
        DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 8: Executing...\n"));
        step8OutBufSize = (B + (step6ValidBits / 8));
        step8OutBuf = FREEOTFE_MEMALLOC(step8OutBufSize);
        FREEOTFE_MEMCPY(
            step8OutBuf,
            step7OutBuf,
            B
            );
        FREEOTFE_MEMCPY(
            &step8OutBuf[B],
            step6OutBuf,
            (step6ValidBits / 8)
            );
        }

    // ---------
    // FIPS-198 Step 9
    // Apply H to the output from step 8
    if (NT_SUCCESS(status))
        {
        DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 9: Executing...\n"));
        step9ValidBits = HashDetails.Length;
        step9OutBufSize = (step9ValidBits / 8);
        step9OutBuf = FREEOTFE_MEMALLOC(step9OutBufSize);
        status = FnHash(
					    &HashGUID,
					    (step8OutBufSize * 8),
					    step8OutBuf,
					    &step9ValidBits,
					    step9OutBuf
                    );
        }


    // ---------
    // FIPS-198 Step 10
    // Select the leftmost t bytes of output from step 9
    if (NT_SUCCESS(status))
        {
        DEBUGOUTMACDRV(DEBUGLEV_INFO, ("HMAC Step 10: Executing...\n"));
        // Truncate, if necessary, to tBits of data
        if (tBits >= 0)
            {
            outputBits = tBits;
            }
        else
            {
            outputBits = step9ValidBits;
            }

        // Sanity check on the buffer...
        if (*MACLength < outputBits)
            {
            DEBUGOUTMACDRV(DEBUGLEV_ERROR, ("Buffer too small; supplied %d bits, need %d bits\n", MACLength, outputBits));
            status = STATUS_BUFFER_TOO_SMALL;
            }
        else
            {
            // Copy the appropriate number of bits to the output buffer
            FREEOTFE_MEMCPY(
                MAC,
                step9OutBuf,
                (outputBits / 8)  // Convert to bytes
                );
            *MACLength = outputBits;
            }

        }


    // Cleanup...
    DEBUGOUTMACDRV(DEBUGLEV_INFO, ("Freeing off any used buffers...\n"));

    if (step9OutBuf != NULL)
        {
        SecZeroMemory(step9OutBuf, step9OutBufSize);
        FREEOTFE_FREE(step9OutBuf);
        }
    if (step8OutBuf != NULL)
        {
        SecZeroMemory(step8OutBuf, step8OutBufSize);
        FREEOTFE_FREE(step8OutBuf);
        }
    if (step7OutBuf != NULL)
        {
        SecZeroMemory(step7OutBuf, B);
        FREEOTFE_FREE(step7OutBuf);
        }
    if (step6OutBuf != NULL)
        {
        SecZeroMemory(step6OutBuf, step6OutBufSize);
        FREEOTFE_FREE(step6OutBuf);
        }
    if (step5OutBuf != NULL)
        {
        SecZeroMemory(step5OutBuf, step5OutBufSize);
        FREEOTFE_FREE(step5OutBuf);
        }
    if (step4OutBuf != NULL)
        {
        SecZeroMemory(step4OutBuf, B);
        FREEOTFE_FREE(step4OutBuf);
        }
    if (Kzero != NULL)
        {
        SecZeroMemory(Kzero, B);
        FREEOTFE_FREE(Kzero);
        }
    

    DEBUGOUTMACDRV(DEBUGLEV_EXIT, ("ImplMACHMAC\n"));

    return status;
}
コード例 #14
0
// =========================================================================
// Generate a key based on the hash of the salted password
NTSTATUS
ImplKDFHashSaltedPassword(
    IN      PDataHashFn FnHash,
    IN      GUID HashGUID,
    IN      unsigned int Iterations,
    IN      unsigned int PasswordLength,  // In bits
    IN      unsigned char* Password,
    IN      unsigned int SaltLength,  // In bits
    IN      unsigned char* Salt,

    IN OUT  unsigned int* DerivedKeyLength,  // In bits
    OUT     unsigned char* DerivedKey
)
{
    NTSTATUS status;
    unsigned char* tmpBuffer;
    unsigned int tmpBufferSizeBytes;
    unsigned char* tmpIterateBuffer;
    unsigned int tmpIterateBufferSizeBytes;
    unsigned int i;

    DEBUGOUTKDFDRV(DEBUGLEV_ENTER, ("ImplKDFHashSaltedPassword\n"));


    tmpBufferSizeBytes = ((PasswordLength + SaltLength) / 8);
    tmpBuffer = FREEOTFE_MEMALLOC(tmpBufferSizeBytes);    

    // Add the salt onto the end of the password before hashing the combined
    // password/salt
    FREEOTFE_MEMCPY(
        tmpBuffer,
        Password,
        (PasswordLength / 8)
        );
    FREEOTFE_MEMCPY(
        &tmpBuffer[(PasswordLength / 8)],
        Salt,
        (SaltLength / 8)
        );

    status = FnHash(
					&HashGUID,
					(tmpBufferSizeBytes * 8),  // Get bits from bytes
					tmpBuffer,
					DerivedKeyLength,
					DerivedKey
                   );
    if (!(NT_SUCCESS(status)))
        {
        DEBUGOUTKDFDRV(DEBUGLEV_ERROR, ("First KDF call to hash driver failed\n"));
        }
    else
        {
        // Iterate, if needed...
        if (Iterations >= 2)
            {
            tmpIterateBufferSizeBytes = (*DerivedKeyLength / 8);
            tmpIterateBuffer = FREEOTFE_MEMALLOC(tmpIterateBufferSizeBytes);
            for (i = 2; i <= Iterations; i++)
                {
                // Copy to temp buffer...
                FREEOTFE_MEMCPY(
                    tmpIterateBuffer,
                    DerivedKey,
                    tmpIterateBufferSizeBytes
                    );

                // Only pass a buffer that we can copy back into
                // Note: This value should never be bigger than the original
                //       value passed in, otherwise the original hash would
                //       fail
                *DerivedKeyLength = (tmpIterateBufferSizeBytes * 8);

                // Hash temp buffer...
                status = FnHash(
					            &HashGUID,
					            (tmpIterateBufferSizeBytes * 8),  // Get bits from bytes
					            tmpIterateBuffer,
					            DerivedKeyLength,
					            DerivedKey
                            );

                if (!(NT_SUCCESS(status)))
                    {
                    DEBUGOUTKDFDRV(DEBUGLEV_ERROR, ("Subsequent KDF call to hash driver failed\n"));
                    break;
                    }

                }

            SecZeroMemory(tmpIterateBuffer, tmpIterateBufferSizeBytes);
            FREEOTFE_FREE(tmpIterateBuffer);
            }
        }



    // Note: No need to explicitly set *MACLength as FnHash does this for us

    SecZeroMemory(tmpBuffer, tmpBufferSizeBytes);
    FREEOTFE_FREE(tmpBuffer);


    DEBUGOUTKDFDRV(DEBUGLEV_EXIT, ("ImplKDFHashSaltedPassword\n"));

    return status;
}
コード例 #15
0
// =========================================================================
// Cypher driver init function
// driverInfo - The structure to be initialized
NTSTATUS
ImpCypherDriverExtDetailsInit_v3(
    IN OUT CYPHER_DRIVER_INFO_v3* driverInfo
)
{
    NTSTATUS status = STATUS_SUCCESS;
    int idx = -1;
    int blockSizeBits;

    DEBUGOUTCYPHERIMPL(DEBUGLEV_ENTER, (TEXT("ImpCypherDriverExtDetailsInit_v3\n")));

    blockSizeBits = (twofish_desc.block_length * 8);

    // -- POPULATE DRIVER IDENTIFICATION --
    FREEOTFE_MEMZERO(driverInfo->DriverTitle, sizeof(driverInfo->DriverTitle));
    FREEOTFE_MEMCPY(
                  driverInfo->DriverTitle,
                  DRIVER_TITLE,
                  strlen(DRIVER_TITLE)
                 );

    driverInfo->DriverGUID = DRIVER_GUID;
    driverInfo->DriverVersionID = DRIVER_CYPHER_VERSION;


    // -- POPULATE cyphers SUPPORTED --
    driverInfo->CypherCount = CYPHERS_SUPPORTED;
    driverInfo->CypherDetails = FREEOTFE_MEMCALLOC(
                                                   sizeof(CYPHER_v3),
                                                   driverInfo->CypherCount
                                                  );


    // -- Twofish-256 CBC --
    idx++;
    FREEOTFE_MEMZERO(
                     driverInfo->CypherDetails[idx].Title,
                     sizeof(driverInfo->CypherDetails[idx].Title)
                    );
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_256_CBC,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_256_CBC)
                 );

    driverInfo->CypherDetails[idx].BlockSize  = blockSizeBits;
    driverInfo->CypherDetails[idx].VersionID  = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID = CIPHER_GUID_TWOFISH_256_CBC;
    DetermineCypherDetails(
                           &driverInfo->CypherDetails[idx].CypherGUID,
                           &driverInfo->CypherDetails[idx].KeySizeUnderlying,
                           &driverInfo->CypherDetails[idx].Mode
                          );
    driverInfo->CypherDetails[idx].KeySizeRequired = 
                            driverInfo->CypherDetails[idx].KeySizeUnderlying;

    // -- Twofish-256 XTS --
    idx++;
    FREEOTFE_MEMZERO(
                     driverInfo->CypherDetails[idx].Title,
                     sizeof(driverInfo->CypherDetails[idx].Title)
                    );
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_256_XTS,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_256_XTS)
                 );

    driverInfo->CypherDetails[idx].BlockSize  = blockSizeBits;
    driverInfo->CypherDetails[idx].VersionID  = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID = CIPHER_GUID_TWOFISH_256_XTS;
    DetermineCypherDetails(
                           &driverInfo->CypherDetails[idx].CypherGUID,
                           &driverInfo->CypherDetails[idx].KeySizeUnderlying,
                           &driverInfo->CypherDetails[idx].Mode
                          );
    driverInfo->CypherDetails[idx].KeySizeRequired = 
                            (2 * driverInfo->CypherDetails[idx].KeySizeUnderlying);

    // -- Twofish-256 LRW --
    idx++;
    FREEOTFE_MEMZERO(
                     driverInfo->CypherDetails[idx].Title,
                     sizeof(driverInfo->CypherDetails[idx].Title)
                    );
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_256_LRW,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_256_LRW)
                 );

    driverInfo->CypherDetails[idx].BlockSize  = blockSizeBits;
    driverInfo->CypherDetails[idx].VersionID  = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID = CIPHER_GUID_TWOFISH_256_LRW;
    DetermineCypherDetails(
                           &driverInfo->CypherDetails[idx].CypherGUID,
                           &driverInfo->CypherDetails[idx].KeySizeUnderlying,
                           &driverInfo->CypherDetails[idx].Mode
                          );
    driverInfo->CypherDetails[idx].KeySizeRequired = 
                            driverInfo->CypherDetails[idx].KeySizeUnderlying + 
                            driverInfo->CypherDetails[idx].BlockSize;

    // -- Twofish-192 CBC --
    idx++;
    FREEOTFE_MEMZERO(
                     driverInfo->CypherDetails[idx].Title,
                     sizeof(driverInfo->CypherDetails[idx].Title)
                    );
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_192_CBC,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_192_CBC)
                 );

    driverInfo->CypherDetails[idx].BlockSize  = blockSizeBits;
    driverInfo->CypherDetails[idx].VersionID  = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID = CIPHER_GUID_TWOFISH_192_CBC;
    DetermineCypherDetails(
                           &driverInfo->CypherDetails[idx].CypherGUID,
                           &driverInfo->CypherDetails[idx].KeySizeUnderlying,
                           &driverInfo->CypherDetails[idx].Mode
                          );
    driverInfo->CypherDetails[idx].KeySizeRequired = 
                            driverInfo->CypherDetails[idx].KeySizeUnderlying;

    // -- Twofish-192 XTS --
    idx++;
    FREEOTFE_MEMZERO(
                     driverInfo->CypherDetails[idx].Title,
                     sizeof(driverInfo->CypherDetails[idx].Title)
                    );
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_192_XTS,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_192_XTS)
                 );

    driverInfo->CypherDetails[idx].BlockSize  = blockSizeBits;
    driverInfo->CypherDetails[idx].VersionID  = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID = CIPHER_GUID_TWOFISH_192_XTS;
    DetermineCypherDetails(
                           &driverInfo->CypherDetails[idx].CypherGUID,
                           &driverInfo->CypherDetails[idx].KeySizeUnderlying,
                           &driverInfo->CypherDetails[idx].Mode
                          );
    driverInfo->CypherDetails[idx].KeySizeRequired = 
                            (2 * driverInfo->CypherDetails[idx].KeySizeUnderlying);

    // -- Twofish-192 LRW --
    idx++;
    FREEOTFE_MEMZERO(
                     driverInfo->CypherDetails[idx].Title,
                     sizeof(driverInfo->CypherDetails[idx].Title)
                    );
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_192_LRW,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_192_LRW)
                 );

    driverInfo->CypherDetails[idx].BlockSize  = blockSizeBits;
    driverInfo->CypherDetails[idx].VersionID  = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID = CIPHER_GUID_TWOFISH_192_LRW;
    DetermineCypherDetails(
                           &driverInfo->CypherDetails[idx].CypherGUID,
                           &driverInfo->CypherDetails[idx].KeySizeUnderlying,
                           &driverInfo->CypherDetails[idx].Mode
                          );
    driverInfo->CypherDetails[idx].KeySizeRequired = 
                            driverInfo->CypherDetails[idx].KeySizeUnderlying + 
                            driverInfo->CypherDetails[idx].BlockSize;

    // -- Twofish-128 CBC --
    idx++;
    FREEOTFE_MEMZERO(
                     driverInfo->CypherDetails[idx].Title,
                     sizeof(driverInfo->CypherDetails[idx].Title)
                    );
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_128_CBC,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_128_CBC)
                 );

    driverInfo->CypherDetails[idx].BlockSize  = blockSizeBits;
    driverInfo->CypherDetails[idx].VersionID  = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID = CIPHER_GUID_TWOFISH_128_CBC;
    DetermineCypherDetails(
                           &driverInfo->CypherDetails[idx].CypherGUID,
                           &driverInfo->CypherDetails[idx].KeySizeUnderlying,
                           &driverInfo->CypherDetails[idx].Mode
                          );
    driverInfo->CypherDetails[idx].KeySizeRequired = 
                            driverInfo->CypherDetails[idx].KeySizeUnderlying;

    // -- Twofish-128 XTS --
    idx++;
    FREEOTFE_MEMZERO(
                     driverInfo->CypherDetails[idx].Title,
                     sizeof(driverInfo->CypherDetails[idx].Title)
                    );
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_128_XTS,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_128_XTS)
                 );

    driverInfo->CypherDetails[idx].BlockSize  = blockSizeBits;
    driverInfo->CypherDetails[idx].VersionID  = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID = CIPHER_GUID_TWOFISH_128_XTS;
    DetermineCypherDetails(
                           &driverInfo->CypherDetails[idx].CypherGUID,
                           &driverInfo->CypherDetails[idx].KeySizeUnderlying,
                           &driverInfo->CypherDetails[idx].Mode
                          );
    driverInfo->CypherDetails[idx].KeySizeRequired = 
                            (2 * driverInfo->CypherDetails[idx].KeySizeUnderlying);

    // -- Twofish-128 LRW --
    idx++;
    FREEOTFE_MEMZERO(
                     driverInfo->CypherDetails[idx].Title,
                     sizeof(driverInfo->CypherDetails[idx].Title)
                    );
    FREEOTFE_MEMCPY(
                  driverInfo->CypherDetails[idx].Title,
                  DRIVER_CIPHER_TITLE_TWOFISH_128_LRW,
                  strlen(DRIVER_CIPHER_TITLE_TWOFISH_128_LRW)
                 );

    driverInfo->CypherDetails[idx].BlockSize  = blockSizeBits;
    driverInfo->CypherDetails[idx].VersionID  = DRIVER_CYPHER_IMPL_VERSION;
    driverInfo->CypherDetails[idx].CypherGUID = CIPHER_GUID_TWOFISH_128_LRW;
    DetermineCypherDetails(
                           &driverInfo->CypherDetails[idx].CypherGUID,
                           &driverInfo->CypherDetails[idx].KeySizeUnderlying,
                           &driverInfo->CypherDetails[idx].Mode
                          );
    driverInfo->CypherDetails[idx].KeySizeRequired = 
                            driverInfo->CypherDetails[idx].KeySizeUnderlying + 
                            driverInfo->CypherDetails[idx].BlockSize;


    DEBUGOUTCYPHERIMPL(DEBUGLEV_EXIT, (TEXT("ImpCypherDriverExtDetailsInit_v3\n")));

    return status;
}
コード例 #16
0
// =========================================================================
// Hash driver init function
// driverInfo - The structure to be initialized
NTSTATUS
ImpHashDriverExtDetailsInit(
    IN OUT HASH_DRIVER_INFO* driverInfo
)
{
    NTSTATUS status = STATUS_SUCCESS;
    int idx = -1;

    DEBUGOUTHASHIMPL(DEBUGLEV_ENTER, (TEXT("ImpHashDriverExtDetailsInit\n")));


    // -- POPULATE DRIVER IDENTIFICATION --
    FREEOTFE_MEMZERO(driverInfo->DriverTitle, sizeof(driverInfo->DriverTitle));
    FREEOTFE_MEMCPY(
                  driverInfo->DriverTitle,
                  DRIVER_TITLE,
                  strlen(DRIVER_TITLE)
                 );

    driverInfo->DriverGUID = DRIVER_GUID;
    driverInfo->DriverVersionID = DRIVER_HASH_VERSION;


    // -- POPULATE HASHES SUPPORTED --
    driverInfo->HashCount = HASHES_SUPPORTED;
    driverInfo->HashDetails = FREEOTFE_MEMCALLOC(
                                                 sizeof(HASH),
                                                 driverInfo->HashCount
                                                );


    // -- SHA-512 --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->HashDetails[idx].Title, MAX_HASH_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->HashDetails[idx].Title,
                  DRIVER_HASH_TITLE_SHA512,
                  strlen(DRIVER_HASH_TITLE_SHA512)
                 );

    driverInfo->HashDetails[idx].Length = (sha512_desc.hashsize * 8);
    driverInfo->HashDetails[idx].BlockSize = (sha512_desc.blocksize * 8);
    driverInfo->HashDetails[idx].VersionID = DRIVER_HASH_IMPL_VERSION;
    driverInfo->HashDetails[idx].HashGUID = HASH_GUID_SHA512;

    // -- SHA-384 --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->HashDetails[idx].Title, MAX_HASH_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->HashDetails[idx].Title,
                  DRIVER_HASH_TITLE_SHA384,
                  strlen(DRIVER_HASH_TITLE_SHA384)
                 );

    driverInfo->HashDetails[idx].Length = (sha384_desc.hashsize * 8);
    driverInfo->HashDetails[idx].BlockSize = (sha384_desc.blocksize * 8);
    driverInfo->HashDetails[idx].VersionID = DRIVER_HASH_IMPL_VERSION;
    driverInfo->HashDetails[idx].HashGUID = HASH_GUID_SHA384;

    // -- SHA-256 --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->HashDetails[idx].Title, MAX_HASH_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->HashDetails[idx].Title,
                  DRIVER_HASH_TITLE_SHA256,
                  strlen(DRIVER_HASH_TITLE_SHA256)
                 );

    driverInfo->HashDetails[idx].Length = (sha256_desc.hashsize * 8);
    driverInfo->HashDetails[idx].BlockSize = (sha256_desc.blocksize * 8);
    driverInfo->HashDetails[idx].VersionID = DRIVER_HASH_IMPL_VERSION;
    driverInfo->HashDetails[idx].HashGUID = HASH_GUID_SHA256;

    // -- SHA-224 --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->HashDetails[idx].Title, MAX_HASH_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->HashDetails[idx].Title,
                  DRIVER_HASH_TITLE_SHA224,
                  strlen(DRIVER_HASH_TITLE_SHA224)
                 );

    driverInfo->HashDetails[idx].Length = (sha224_desc.hashsize * 8);
    driverInfo->HashDetails[idx].BlockSize = (sha224_desc.blocksize * 8);
    driverInfo->HashDetails[idx].VersionID = DRIVER_HASH_IMPL_VERSION;
    driverInfo->HashDetails[idx].HashGUID = HASH_GUID_SHA224;

    // -- SHA-1 --
    idx++;
    FREEOTFE_MEMZERO(driverInfo->HashDetails[idx].Title, MAX_HASH_TITLE);
    FREEOTFE_MEMCPY(
                  driverInfo->HashDetails[idx].Title,
                  DRIVER_HASH_TITLE_SHA1,
                  strlen(DRIVER_HASH_TITLE_SHA1)
                 );

    driverInfo->HashDetails[idx].Length = (sha1_desc.hashsize * 8);
    driverInfo->HashDetails[idx].BlockSize = (sha1_desc.blocksize * 8);
    driverInfo->HashDetails[idx].VersionID = DRIVER_HASH_IMPL_VERSION;
    driverInfo->HashDetails[idx].HashGUID = HASH_GUID_SHA1;


    DEBUGOUTHASHIMPL(DEBUGLEV_EXIT, (TEXT("ImpHashDriverExtDetailsInit\n")));
    return status;
}