NTSTATUS BlockCipherImp::setKey()

in unittest/lib/cng_imp_blockcipherpattern.cpp [108:221]


NTSTATUS BlockCipherImp<ImpXxx, AlgXxx, ModeXxx>::setKey( _In_reads_( cbKey ) PCBYTE pbKey, SIZE_T cbKey )
{
    NTSTATUS status = STATUS_SUCCESS;
    DWORD tmp, tmp2;
    BYTE blob[1024];
    ULONG cbBlob;
    static int keyType = 0;
    PBYTE   pKeyObject;
    DWORD   cbKeyObject;

    if( state.hKey != 0 )
    {
        CHECK( NT_SUCCESS( CngDestroyKeyFn( state.hKey ) ), "Could not destroy key" );
        state.hKey = 0;
        CHECK( *state.pMagic == 'ntft', "Magic marker overwritten" );
    }

    status = CngRc2KeySupport<AlgXxx>( state.hAlg, cbKey );
    if( !NT_SUCCESS( status ) )
    {
        goto Cleanup;
    }

    keyType = (keyType + 1) % 2;
    switch( keyType )
    {
    case 0:
        pKeyObject = &state.keyObjectBuffer[0];
        cbKeyObject = state.keyObjSize;
        break;
    case 1:
        pKeyObject = NULL;
        cbKeyObject = 0;
        break;
    default:
        CHECK( FALSE, "?" );
        goto Cleanup;
    }
    //iprint( "%c", '0' + keyType );

    CHECK( cbKeyObject <= sizeof( state.keyObjectBuffer ) - 4, "?" );
    state.pMagic = (ULONG *) &state.keyObjectBuffer[cbKeyObject];

    *state.pMagic = 'ntft';

    status = CngGenerateSymmetricKeyFn(
                            state.hAlg,
                            &state.hKey,
                            pKeyObject, cbKeyObject,
                            (PBYTE) pbKey, (ULONG) cbKey,
                            g_cngKeySizeFlag );

    if( !NT_SUCCESS( status ) )
    {
        return status;
    }

    if( (ModeXxx::flags & MODE_FLAG_CFB) != 0 )
    {
        tmp = (DWORD) g_modeCfbShiftParam;
        status = CngSetPropertyFn(
                    state.hKey,
                    BCRYPT_MESSAGE_BLOCK_LENGTH,
                    (PBYTE)&tmp,
                    sizeof( tmp ),
                    0 );
        if( !NT_SUCCESS( status ) )
        {
            CHECK( g_osVersion < 0x0602, "CFB parameter set-property failed on W8" );

            if( g_modeCfbShiftParam == 1 )
            {
                //
                // Original CFB implementation still works for shiftParam == 1
                //
                status = STATUS_SUCCESS;
            }
            goto Cleanup;
        }

        //
        // Tests below can be removed once it is in the CNG BVTs
        //
        tmp = 0;
        CHECK( NT_SUCCESS( CngGetPropertyFn(
                            state.hKey,
                            BCRYPT_MESSAGE_BLOCK_LENGTH,
                            (PBYTE)&tmp,
                            sizeof( tmp ),
                            &tmp2,
                            0 )),
                    "Error getting CFB shift param" );
        CHECK( tmp == g_modeCfbShiftParam, "?" );

    }

    //
    // Test the opaque blob import/export
    // Can be removed once this is part of the CNG BVTs
    //
    
    CHECK( *state.pMagic == 'ntft', "Magic marker overwritten" );

    CHECK( NT_SUCCESS( CngExportKeyFn( state.hKey, NULL, BCRYPT_OPAQUE_KEY_BLOB, blob, sizeof( blob ), &cbBlob, 0 ) ), "Opaque blob export error" );
    CHECK( NT_SUCCESS( CngDestroyKeyFn( state.hKey ) ), "Could not destroy key" );
    CHECK( *state.pMagic == 'ntft', "Magic marker overwritten" );
    CHECK( NT_SUCCESS( CngImportKeyFn( state.hAlg, NULL, BCRYPT_OPAQUE_KEY_BLOB, &state.hKey, pKeyObject, cbKeyObject, blob, cbBlob, 0 ) ), "Opaque blob import error" );
    
    CHECK( *state.pMagic == 'ntft', "Magic marker overwritten" );

Cleanup:
    return status;        
    
}