Skip to content

Commit

Permalink
Merge pull request Aorimn#229 from kohend/recovery_search
Browse files Browse the repository at this point in the history
Recovery search of datums
  • Loading branch information
Aorimn authored Dec 12, 2020
2 parents 6662821 + ee01629 commit c3d4cbc
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 86 deletions.
2 changes: 1 addition & 1 deletion include/dislocker/metadata/vmk.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ int get_vmk_from_clearkey(dis_metadata_t dis_meta, void** vmk_datum);

int get_vmk_datum_from_guid(dis_metadata_t dis_meta, guid_t guid, void** vmk_datum);

int get_vmk_datum_from_range(dis_metadata_t dis_meta, uint16_t min_range, uint16_t max_range, void** vmk_datum);
int get_vmk_datum_from_range(dis_metadata_t dis_meta, uint16_t min_range, uint16_t max_range, void** vmk_datum, void* prev_vmk_datum);

int get_vmk(datum_aes_ccm_t* vmk_datum, uint8_t* recovery_key,
size_t key_size, datum_key_t** vmk);
Expand Down
166 changes: 85 additions & 81 deletions src/accesses/rp/recovery_password.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ int get_vmk_from_rp2(dis_metadata_t dis_meta, uint8_t* recovery_password,
uint8_t salt[16] = {0,};

int result = FALSE;
void* prev_vmk_datum = NULL;

/* If the recovery password wasn't provide, ask for it */
if(!recovery_password)
Expand All @@ -84,99 +85,102 @@ int get_vmk_from_rp2(dis_metadata_t dis_meta, uint8_t* recovery_password,
(char *)recovery_password);


/*
* We need a salt contained in the VMK datum associated to the recovery
* password, so go get this salt and the VMK datum first
* We use here the range which should be upper (or equal) than 0x800
*/
if(!get_vmk_datum_from_range(dis_meta, 0x800, 0xfff, (void**) vmk_datum))
{
dis_printf(
L_ERROR,
"Error, can't find a valid and matching VMK datum. Abort.\n"
);
*vmk_datum = NULL;
return FALSE;
}

while (!result) {
/*
* We need a salt contained in the VMK datum associated to the recovery
* password, so go get this salt and the VMK datum first
* We use here the range which should be upper (or equal) than 0x800
*/
if(!get_vmk_datum_from_range(dis_meta, 0x800, 0xfff, (void**) vmk_datum, prev_vmk_datum))
{
dis_printf(
L_ERROR,
"Error, can't find a valid and matching VMK datum. Abort.\n"
);
*vmk_datum = NULL;
return FALSE;
}
prev_vmk_datum = *vmk_datum;


/*
* We have the datum containing other data, so get in there and take the
* nested one with type 3 (stretch key)
*/
void* stretch_datum = NULL;
if(!get_nested_datumvaluetype(
*vmk_datum,
DATUMS_VALUE_STRETCH_KEY,
&stretch_datum
) ||
!stretch_datum)
{
char* type_str = datumvaluetypestr(DATUMS_VALUE_STRETCH_KEY);
dis_printf(
L_ERROR,
"Error looking for the nested datum of type %hd (%s) in the VMK one"
". Internal failure, abort.\n",
DATUMS_VALUE_STRETCH_KEY,
type_str
);
dis_free(type_str);
*vmk_datum = NULL;
return FALSE;
}

/*
* We have the datum containing other data, so get in there and take the
* nested one with type 3 (stretch key)
*/
void* stretch_datum = NULL;
if(!get_nested_datumvaluetype(
*vmk_datum,
DATUMS_VALUE_STRETCH_KEY,
&stretch_datum
) ||
!stretch_datum)
{
char* type_str = datumvaluetypestr(DATUMS_VALUE_STRETCH_KEY);
dis_printf(
L_ERROR,
"Error looking for the nested datum of type %hd (%s) in the VMK one"
". Internal failure, abort.\n",
DATUMS_VALUE_STRETCH_KEY,
type_str
);
dis_free(type_str);
*vmk_datum = NULL;
return FALSE;
}

/* The salt is in here, don't forget to keep it somewhere! */
memcpy(salt, ((datum_stretch_key_t*) stretch_datum)->salt, 16);

/* The salt is in here, don't forget to keep it somewhere! */
memcpy(salt, ((datum_stretch_key_t*) stretch_datum)->salt, 16);

/* Get data which can be decrypted with this password */
void* aesccm_datum = NULL;
if(!get_nested_datumvaluetype(
*vmk_datum,
DATUMS_VALUE_AES_CCM,
&aesccm_datum
) ||
!aesccm_datum)
{
dis_printf(
L_ERROR,
"Error finding the AES_CCM datum including the VMK. "
"Internal failure, abort.\n"
);
*vmk_datum = NULL;
return FALSE;
}

/* Get data which can be decrypted with this password */
void* aesccm_datum = NULL;
if(!get_nested_datumvaluetype(
*vmk_datum,
DATUMS_VALUE_AES_CCM,
&aesccm_datum
) ||
!aesccm_datum)
{
dis_printf(
L_ERROR,
"Error finding the AES_CCM datum including the VMK. "
"Internal failure, abort.\n"
);
*vmk_datum = NULL;
return FALSE;
}

/*
* We have all the things we need to compute the intermediate key from
* the recovery password, so do it!
*/
recovery_key = dis_malloc(32 * sizeof(uint8_t));

/*
* We have all the things we need to compute the intermediate key from
* the recovery password, so do it!
*/
recovery_key = dis_malloc(32 * sizeof(uint8_t));
if(!intermediate_key(recovery_password, salt, recovery_key))
{
dis_printf(
L_ERROR,
"Error computing the recovery password to the recovery key. "
"Abort.\n"
);
*vmk_datum = NULL;
dis_free(recovery_key);
return FALSE;
}

if(!intermediate_key(recovery_password, salt, recovery_key))
{
dis_printf(
L_ERROR,
"Error computing the recovery password to the recovery key. "
"Abort.\n"
/* As the computed key length is always the same, use a direct value */
result = get_vmk(
(datum_aes_ccm_t*) aesccm_datum,
recovery_key,
32,
(datum_key_t**) vmk_datum
);
*vmk_datum = NULL;

dis_free(recovery_key);
return FALSE;
}

/* As the computed key length is always the same, use a direct value */
result = get_vmk(
(datum_aes_ccm_t*) aesccm_datum,
recovery_key,
32,
(datum_key_t**) vmk_datum
);

dis_free(recovery_key);

return result;
}

Expand Down
2 changes: 1 addition & 1 deletion src/accesses/user_pass/user_pass.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ int get_vmk_from_user_pass2(dis_metadata_t dis_meta,
* There may be another mean to find the correct datum, but I don't see
* another one here
*/
if(!get_vmk_datum_from_range(dis_meta, 0x2000, 0x2000, (void**) vmk_datum))
if(!get_vmk_datum_from_range(dis_meta, 0x2000, 0x2000, (void**) vmk_datum, NULL))
{
dis_printf(
L_ERROR,
Expand Down
2 changes: 1 addition & 1 deletion src/metadata/datums.c
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ int dis_metadata_has_clear_key(dis_metadata_t dis_meta, void** vmk_datum)

dis_printf(L_DEBUG, "Entering has_clear_key. Returning result of get_vmk_datum_from_range with range between 0x00 and 0xff\n");

return get_vmk_datum_from_range(dis_meta, 0x00, 0xff, vmk_datum);
return get_vmk_datum_from_range(dis_meta, 0x00, 0xff, vmk_datum, NULL);
}


Expand Down
8 changes: 6 additions & 2 deletions src/metadata/vmk.c
Original file line number Diff line number Diff line change
Expand Up @@ -260,15 +260,19 @@ int get_vmk_datum_from_guid(dis_metadata_t dis_meta, guid_t guid,
* @return TRUE if result can be trusted, FALSE otherwise
*/
int get_vmk_datum_from_range(dis_metadata_t dis_meta, uint16_t min_range,
uint16_t max_range, void** vmk_datum)
uint16_t max_range, void** vmk_datum, void* prev_vmk_datum)
{
// Check parameters
if(!dis_meta)
return FALSE;

uint16_t datum_range = 0;

*vmk_datum = NULL;
if (prev_vmk_datum) {
*vmk_datum = prev_vmk_datum;
} else {
*vmk_datum = NULL;
}

while(1)
{
Expand Down

0 comments on commit c3d4cbc

Please sign in to comment.