Exemple #1
0
void FillBlock(const block* prev_block, const block* ref_block, block* next_block, const uint64_t* Sbox) {
    block blockR;
    CopyBlock(&blockR,ref_block);
    XORBlock(&blockR,prev_block);
    block block_tmp;
    CopyBlock(&block_tmp, &blockR);

    uint64_t x = 0;
    if (Sbox != NULL) {
        x = blockR.v[0] ^ blockR.v[ARGON2_WORDS_IN_BLOCK - 1];
        for (int i = 0; i < 6 * 16; ++i) {
            uint32_t x1 = x >> 32;
            uint32_t x2 = x & 0xFFFFFFFF;
            uint64_t y = Sbox[x1 & ARGON2_SBOX_MASK];
            uint64_t z = Sbox[(x2 & ARGON2_SBOX_MASK) + ARGON2_SBOX_SIZE / 2];
            x = (uint64_t) x1 * (uint64_t) x2;
            x += y;
            x ^= z;
        }
    }
// =========================================================================
// Decryption function
// Note: PlaintextLength must be set to the size of the PlaintextData buffer on
//       entry; on exit, this will be set to the size of the buffer used.
NTSTATUS
ImpCypherDecryptSectorData(
    IN      GUID* CypherGUID,
    IN      LARGE_INTEGER SectorID,  // Indexed from zero
    IN      int SectorSize, // In bytes
    IN      int KeyLength,  // In bits
    IN      FREEOTFEBYTE* Key,
    IN      char* KeyASCII,  // ASCII representation of "Key"
    IN      int IVLength,  // In bits
    IN      FREEOTFEBYTE* IV,
    IN      int CyphertextLength,  // In bytes
    IN      FREEOTFEBYTE* CyphertextData,
    OUT     FREEOTFEBYTE* PlaintextData
)
{
    NTSTATUS status = STATUS_SUCCESS;
    // Null IV in case we're not given an IV
    char zeroIV[FREEOTFE_MAX_CYPHER_BLOCKSIZE];
    int i;
    INTEGER_128 blockID128;
    int errnum;
    TWOFISH(CONTEXT) context;

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

    if (
          (IsEqualGUID(&CIPHER_GUID_TWOFISH_256_XTS, CypherGUID)) ||
          (IsEqualGUID(&CIPHER_GUID_TWOFISH_192_XTS, CypherGUID)) ||
          (IsEqualGUID(&CIPHER_GUID_TWOFISH_128_XTS, CypherGUID)) 
         )
        {
        // Generate index in correct format
        // XTS uses:
        //   *) The sector index (i.e. the number of N-bit sectors)
        //   *) The first sector is sector 0
        //   *) Littleendian format
        LARGE_INTEGER__To__INTEGER_128_LittleEndian(
                                            SectorID,
                                            blockID128
                                           );

        if ((errnum = xts_decrypt(
                              &context,
                              &(TWOFISH(set_key)),
                              &(TWOFISH(encrypt)),
                              &(TWOFISH(decrypt)),
                              ((KeyLength/2)),
                              Key, 
                              ((KeyLength/2)),
                              &(Key[(KeyLength/2)/8]),
                              CyphertextData, 
                              CyphertextLength, 
                              PlaintextData, 
                              blockID128
                             )) != CRYPT_OK)
            {
            DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unable to decrypt block (errnum: %d)\n"), errnum));
            status = STATUS_UNSUCCESSFUL;
            } 

        }
    else if (
          (IsEqualGUID(&CIPHER_GUID_TWOFISH_256_CBC, CypherGUID)) ||
          (IsEqualGUID(&CIPHER_GUID_TWOFISH_192_CBC, CypherGUID)) ||
          (IsEqualGUID(&CIPHER_GUID_TWOFISH_128_CBC, CypherGUID)) 
         )
        {
        // Handle situation where a NULL/zero length IV is passed in
        if ( (IVLength == 0) || (IV == NULL) )
            {
            FREEOTFE_MEMZERO(&zeroIV, sizeof(zeroIV));
            IV = (char*)&zeroIV;
            }


        // Process data using CBC mode
        //
        // CBC Mode DECRYPT:
        // *) Setup key
        // *) For each block...
        //     *) Decrypt cyphertext with key
        //     *) XOR output plaintext with IV
        //     *) IV = Cyphertext data

        // Note: "dec" specified; we're DECRYPTING
        TWOFISH(set_key)(&context, Key, KeyLength, dec);
        for (i=0; i < CyphertextLength; i += (TWOFISH_BLOCK_SIZE / 8))
            {
            TWOFISH(decrypt)(&context, CyphertextData+i, PlaintextData+i);
            XORBlock(PlaintextData+i, IV, PlaintextData+i, (TWOFISH_BLOCK_SIZE / 8));
            IV = CyphertextData+i;
            }

        }
    else
        {
        DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unsupported cipher GUID passed in.\n")));
        status = STATUS_INVALID_PARAMETER;
        }

    SecZeroMemory(&context, sizeof(context));


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

    return status;
}
// =========================================================================
// Decryption function
// Note: PlaintextLength must be set to the size of the PlaintextData buffer on
//       entry; on exit, this will be set to the size of the buffer used.
NTSTATUS
ImpCypherDecryptSectorData(
    IN      GUID* CypherGUID,
    IN      LARGE_INTEGER SectorID,  // Indexed from zero
    IN      int SectorSize, // In bytes
    IN      int KeyLength,  // In bits
    IN      FREEOTFEBYTE* Key,
    IN      char* KeyASCII,  // ASCII representation of "Key"
    IN      int IVLength,  // In bits
    IN      FREEOTFEBYTE* IV,
    IN      int CyphertextLength,  // In bytes
    IN      FREEOTFEBYTE* CyphertextData,
    OUT     FREEOTFEBYTE* PlaintextData
)
{
    NTSTATUS status = STATUS_SUCCESS;
    // Null IV in case we're not given an IV
    char zeroIV[FREEOTFE_MAX_CYPHER_BLOCKSIZE];
    int i;
    CONTEXT context;

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

    if (
          (IsEqualGUID(&CIPHER_GUID_CAST6_256_CBC, CypherGUID)) ||
          (IsEqualGUID(&CIPHER_GUID_CAST6_224_CBC, CypherGUID)) ||
          (IsEqualGUID(&CIPHER_GUID_CAST6_192_CBC, CypherGUID)) ||
          (IsEqualGUID(&CIPHER_GUID_CAST6_160_CBC, CypherGUID)) ||
          (IsEqualGUID(&CIPHER_GUID_CAST6_128_CBC, CypherGUID)) 
         )
        {
        // Handle situation where a NULL/zero length IV is passed in
        if ( (IVLength == 0) || (IV == NULL) )
            {
            FREEOTFE_MEMZERO(&zeroIV, sizeof(zeroIV));
            IV = (char*)&zeroIV;
            }


        // Process data using CBC mode
        //
        // CBC Mode DECRYPT:
        // *) Setup key
        // *) For each block...
        //     *) Decrypt cyphertext with key
        //     *) XOR output plaintext with IV
        //     *) IV = Cyphertext data

        // Note: "dec" specified; we're DECRYPTING
        set_key(&context, (u4byte *)Key, KeyLength);
        for (i=0; i < CyphertextLength; i += (CAST6_BLOCK_SIZE / 8))
            {
            decrypt(&context, (u4byte *)(CyphertextData+i), (u4byte *)(PlaintextData+i));
            XORBlock(PlaintextData+i, IV, PlaintextData+i, (CAST6_BLOCK_SIZE / 8));
            IV = CyphertextData+i;
            }

        }
    else
        {
        DEBUGOUTCYPHERIMPL(DEBUGLEV_ERROR, (TEXT("Unsupported cipher GUID passed in.\n")));
        status = STATUS_INVALID_PARAMETER;
        }

    SecZeroMemory(&context, sizeof(context));


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

    return status;
}