/* Sets the de- and encryption keys * Returns 1 if successful or -1 on error */ int libbde_encryption_set_keys( libbde_encryption_context_t *context, const uint8_t *full_volume_encryption_key, size_t full_volume_encryption_key_size, const uint8_t *tweak_key, size_t tweak_key_size, libcerror_error_t **error ) { static char *function = "libbde_encryption_set_keys"; size_t key_bit_size = 0; size_t key_byte_size = 0; if( context == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid context.", function ); return( -1 ); } if( full_volume_encryption_key == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid full volume encryption key.", function ); return( -1 ); } if( full_volume_encryption_key_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid full volume encryption key size value exceeds maximum.", function ); return( -1 ); } if( tweak_key == NULL ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE, "%s: invalid tweak key.", function ); return( -1 ); } if( tweak_key_size > (size_t) SSIZE_MAX ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM, "%s: invalid tweak key size value exceeds maximum.", function ); return( -1 ); } if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC ) || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER ) ) { key_byte_size = 16; } else if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC ) || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) ) { key_byte_size = 32; } else if( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS ) { key_byte_size = 32; } else if( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS ) { key_byte_size = 64; } if( full_volume_encryption_key_size < key_byte_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: invalid full volume encryption key value too small.", function ); return( -1 ); } if( tweak_key_size < key_byte_size ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_ARGUMENTS, LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL, "%s: invalid tweak key value too small.", function ); return( -1 ); } key_bit_size = key_byte_size * 8; if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC ) || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER ) || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC ) || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) ) { if( libcaes_crypt_set_key( context->fvek_decryption_context, LIBCAES_CRYPT_MODE_DECRYPT, full_volume_encryption_key, key_bit_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set full volume encryption key in decryption context.", function ); return( -1 ); } if( libcaes_crypt_set_key( context->fvek_encryption_context, LIBCAES_CRYPT_MODE_ENCRYPT, full_volume_encryption_key, key_bit_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set full volume encryption key in encryption context.", function ); return( -1 ); } /* The TWEAK key is only used with diffuser */ if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_CBC_DIFFUSER ) || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_CBC_DIFFUSER ) ) { if( libcaes_crypt_set_key( context->tweak_decryption_context, LIBCAES_CRYPT_MODE_DECRYPT, tweak_key, key_bit_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set tweak key in decryption context.", function ); return( -1 ); } if( libcaes_crypt_set_key( context->tweak_encryption_context, LIBCAES_CRYPT_MODE_ENCRYPT, tweak_key, key_bit_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set tweak key in encryption context.", function ); return( -1 ); } } } else if( ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_128_XTS ) || ( context->method == LIBBDE_ENCRYPTION_METHOD_AES_256_XTS ) ) { key_byte_size /= 2; key_bit_size /= 2; if( libcaes_tweaked_context_set_keys( context->fvek_decryption_tweaked_context, LIBCAES_CRYPT_MODE_DECRYPT, full_volume_encryption_key, key_bit_size, &( full_volume_encryption_key[ key_byte_size ] ), key_bit_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set full volume encryption key in decryption tweaked context.", function ); return( -1 ); } if( libcaes_tweaked_context_set_keys( context->fvek_encryption_tweaked_context, LIBCAES_CRYPT_MODE_ENCRYPT, full_volume_encryption_key, key_bit_size, &( full_volume_encryption_key[ key_byte_size ] ), key_bit_size, error ) != 1 ) { libcerror_error_set( error, LIBCERROR_ERROR_DOMAIN_RUNTIME, LIBCERROR_RUNTIME_ERROR_SET_FAILED, "%s: unable to set full volume encryption key in encryption tweaked context.", function ); return( -1 ); } } return( 1 ); }
/* Sets the keys * Returns a Python object if successful or NULL on error */ PyObject *pycaes_tweaked_context_set_keys( pycaes_tweaked_context_t *pycaes_context, PyObject *arguments, PyObject *keywords ) { libcerror_error_t *error = NULL; PyObject *key_string_object = NULL; PyObject *tweak_key_string_object = NULL; static char *function = "pycaes_tweaked_context_set_key"; static char *keyword_list[] = { "mode", "key", "tweak_key", NULL }; char *key_data = NULL; char *tweak_key_data = NULL; Py_ssize_t key_data_size = 0; Py_ssize_t tweak_key_data_size = 0; int mode = 0; int result = 0; if( PyArg_ParseTupleAndKeywords( arguments, keywords, "iOO", keyword_list, &mode, &key_string_object, &tweak_key_string_object ) == 0 ) { return( NULL ); } #if PY_MAJOR_VERSION >= 3 key_data = PyBytes_AsString( key_string_object ); key_data_size = PyBytes_Size( key_string_object ); #else key_data = PyString_AsString( key_string_object ); key_data_size = PyString_Size( key_string_object ); #endif if( ( key_data_size < 0 ) || ( key_data_size > (Py_ssize_t) ( SSIZE_MAX / 8 ) ) ) { PyErr_Format( PyExc_ValueError, "%s: invalid argument key data size value out of bounds.", function ); return( NULL ); } #if PY_MAJOR_VERSION >= 3 tweak_key_data = PyBytes_AsString( tweak_key_string_object ); tweak_key_data_size = PyBytes_Size( tweak_key_string_object ); #else tweak_key_data = PyString_AsString( tweak_key_string_object ); tweak_key_data_size = PyString_Size( tweak_key_string_object ); #endif if( ( tweak_key_data_size < 0 ) || ( tweak_key_data_size > (Py_ssize_t) ( SSIZE_MAX / 8 ) ) ) { PyErr_Format( PyExc_ValueError, "%s: invalid argument tweak key data size value out of bounds.", function ); return( NULL ); } Py_BEGIN_ALLOW_THREADS result = libcaes_tweaked_context_set_keys( pycaes_context->context, mode, (uint8_t *) key_data, (size_t) ( key_data_size * 8 ), (uint8_t *) tweak_key_data, (size_t) ( tweak_key_data_size * 8 ), &error ); Py_END_ALLOW_THREADS if( result != 1 ) { pycaes_error_raise( error, PyExc_IOError, "%s: unable to set keys.", function ); libcerror_error_free( &error ); return( NULL ); } Py_IncRef( Py_None ); return( Py_None ); }