Changes by: antona
Update of /cvsroot/linux-ntfs/ntfsprogs/ntfsprogs
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16303/ntfsprogs
Modified Files:
decrypt.c ntfsdecrypt.c
Log Message:
Add EFS structure definitions to layout.h and adapt ntfsdecrypt for it.
More fixes/cleanups to decrypt.c.
This was all Yuval's work but I did some renaming afterwards and some
whitespace cleanups.
Index: decrypt.c
===================================================================
RCS file: /cvsroot/linux-ntfs/ntfsprogs/ntfsprogs/decrypt.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -p -r1.16 -r1.17
--- decrypt.c 27 Jul 2005 21:33:00 -0000 1.16
+++ decrypt.c 28 Jul 2005 10:36:32 -0000 1.17
@@ -161,8 +161,7 @@ ntfs_decrypt_user_key_session *ntfs_decr
return NULL;
}
if (!(hSystemStore = fnCertOpenStore(((LPCSTR)CERT_STORE_PROV_SYSTEM),
- 0, (HCRYPTPROV)NULL, CERT_SYSTEM_STORE_CURRENT_USER,
- L"MY"))) {
+ 0, 0, CERT_SYSTEM_STORE_CURRENT_USER, L"MY"))) {
fprintf(stderr, "Could not open system store.\n");
errno = EINVAL;
return NULL;
@@ -195,6 +194,13 @@ void ntfs_decrypt_user_key_session_close
free(session);
}
+/**
+ * reverse_buffer -
+ *
+ * This is a utility function for reversing the order of a buffer in place.
+ * Users of this function should be very careful not to sweep byte order
+ * problems under the rug.
+ */
static inline void reverse_buffer(unsigned char *buf, unsigned buf_size)
{
unsigned char t;
@@ -256,14 +262,14 @@ ntfs_decrypt_user_key *ntfs_decrypt_user
&key_size)) {
fprintf(stderr, "Could not export key: Error 0x%x\n",
(unsigned)GetLastError());
- errno = -1;
+ errno = EINVAL;
return NULL;
}
CryptDestroyKey(hCryptKey);
rsa_pub_key = (RSAPUBKEY*)(key_blob + sizeof(PUBLICKEYSTRUC));
if ((err = gcry_ac_open(&gcry_handle, GCRY_AC_RSA, 0))) {
fprintf(stderr, "Could not init gcrypt handle\n");
- errno = -1;
+ errno = EINVAL;
return NULL;
}
gcry_control(GCRYCTL_DISABLE_SECMEM, 0);
@@ -302,8 +308,8 @@ ntfs_decrypt_user_key *ntfs_decrypt_user
errno = EINVAL;
return NULL;
}
- if ((key = (ntfs_decrypt_user_key*)malloc(
- sizeof(NTFS_DECRYPT_USER_KEY))))
+ if ((key = (ntfs_decrypt_user_key*)
+ malloc(sizeof(NTFS_DECRYPT_USER_KEY))))
((NTFS_DECRYPT_USER_KEY*)key)->sexp_key = sexp_key;
// todo: release all
return key;
@@ -312,8 +318,10 @@ decrypt_key_open_err:
CryptDestroyKey(hCryptKey);
if (pCert)
fnCertFreeCertificateContext(pCert);
-#endif /* defined(__CYGWIN__) */
+ errno = EINVAL;
+#else /* !defined(__CYGWIN__) */
errno = ENOTSUP;
+#endif /* !defined(__CYGWIN__) */
return NULL;
}
@@ -427,6 +435,14 @@ static void ntfs_desx_key_expand(const u
*in_whitening = *(u64*)(md + 2);
}
+/**
+ * ntfs_desx_setkey - libgcrypt set_key implementation for DES-X-MS128
+ * @context: pointer to a variable of type ntfs_desx_ctx
+ * @key: the 128 bit DES-X-MS128 key, concated with the DES handle
+ * @keylen: must always be 16
+ *
+ * This is the libgcrypt set_key implementation for DES-X-MS128.
+ */
static gcry_err_code_t ntfs_desx_setkey(void *context, const u8 *key,
unsigned keylen)
{
@@ -606,8 +622,6 @@ ntfs_decrypt_data_key *ntfs_decrypt_data
case CALG_DESX:
/* FIXME: This really needs locking so it is safe from races. */
if (!ntfs_desx_module_count++) {
- gcry_error_t err;
-
if (!desx_key_expand_test() || !des_test()) {
errno = EINVAL;
return NULL;
Index: ntfsdecrypt.c
===================================================================
RCS file: /cvsroot/linux-ntfs/ntfsprogs/ntfsprogs/ntfsdecrypt.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -p -r1.6 -r1.7
--- ntfsdecrypt.c 27 Jul 2005 15:55:42 -0000 1.6
+++ ntfsdecrypt.c 28 Jul 2005 10:36:32 -0000 1.7
@@ -272,17 +272,60 @@ static int cat_decrypt(ntfs_inode *inode
return 0;
}
+static ntfs_decrypt_data_key *get_fek_from_df_array(
+ ntfs_decrypt_user_key_session *session,
+ EFS_DF_ARRAY_HEADER *efs_df_array)
+{
+ u32 ddf_count, hash_size, fek_size;
+ EFS_DF_CREDENTIAL_HEADER *efs_df_cred;
+ EFS_DF_CERTIFICATE_HEADER *efs_df_cert;
+ EFS_DF_HEADER *efs_df_header;
+ ntfs_decrypt_user_key *key;
+ u8 *hash_data, *fek_buf;
+ unsigned i;
+
+ efs_df_header = (EFS_DF_HEADER*)(efs_df_array + 1);
+ ddf_count = le32_to_cpu(efs_df_array->df_count);
+ for (i = 0; i < ddf_count; i++) {
+ //Eprintf("ddf #%u.\n", i);
+ efs_df_cred = (EFS_DF_CREDENTIAL_HEADER*)((u8*)efs_df_header +
+ le32_to_cpu(efs_df_header->cred_header_offset));
+ efs_df_cert = (EFS_DF_CERTIFICATE_HEADER*)((u8*)efs_df_cred +
+ le32_to_cpu(efs_df_cred->cert_header_offset));
+ hash_size = le32_to_cpu(efs_df_cert->thumbprint_size);
+ hash_data = (u8*)efs_df_cert +
+ le32_to_cpu(efs_df_cert->thumbprint_offset);
+ fek_size = le32_to_cpu(efs_df_header->fek_size);
+ fek_buf = (u8*)efs_df_header +
+ le32_to_cpu(efs_df_header->fek_offset);
+ if ((key = ntfs_decrypt_user_key_open(session, hash_data,
+ hash_size))) {
+ fek_size = ntfs_decrypt_user_key_decrypt(key, fek_buf,
+ fek_size);
+ ntfs_decrypt_user_key_close(key);
+ if (fek_size)
+ return ntfs_decrypt_data_key_open(fek_buf,
+ fek_size);
+ fprintf(stderr, "Failed to decrypt the FEK.\n");
+ } else
+ perror("Failed to open user key");
+ efs_df_header = (EFS_DF_HEADER*)((u8*)efs_df_header +
+ le32_to_cpu(efs_df_header->df_length));
+ }
+ return NULL;
+}
+
/**
* get_fek
*/
static ntfs_decrypt_data_key *get_fek(ntfs_inode *inode)
{
- ntfs_attr *na;
- unsigned char *efs_buffer, *ddf, *certificate, *hash_data, *fek_buf;
- u32 ddf_count, hash_size, fek_size;
- unsigned i;
ntfs_decrypt_user_key_session *session;
- ntfs_decrypt_user_key *key;
+ EFS_DF_ARRAY_HEADER *efs_df_array;
+ ntfs_decrypt_data_key *fek;
+ EFS_ATTR_HEADER *efs_attr;
+ u8 *efs_buffer;
+ ntfs_attr *na;
/* Obtain the $EFS contents. */
na = ntfs_attr_open(inode, AT_LOGGED_UTILITY_STREAM,
@@ -313,44 +356,19 @@ static ntfs_decrypt_data_key *get_fek(nt
return NULL;
}
/* Iterate through the DDFs & DRFs until we obtain a key. */
- ddf = efs_buffer + le32_to_cpu(*(u32*)(efs_buffer + 0x40));
- ddf_count = le32_to_cpu(*(u32*)ddf);
-
- ddf = ddf + 0x04;
- for (i = 0; i < ddf_count; i++) {
- //Eprintf("ddf #%u.\n", i);
- if (*(u32*)(ddf + 0x18))
- certificate = (ddf + 0x30 +
- le32_to_cpu(*(u32*)(ddf + 0x18)));
- else
- certificate = (ddf + 0x30);
- hash_size = (unsigned)le32_to_cpu(*(u32*)certificate);
- hash_data = certificate + (unsigned)
- le32_to_cpu(*(u32*)(certificate + 0x04));
- fek_size = (unsigned)le32_to_cpu(*(u32*)(ddf + 0x08));
- fek_buf = ddf + (unsigned)le32_to_cpu(*(u32*)(ddf + 0x0c));
- if ((key = ntfs_decrypt_user_key_open(session, hash_data,
- hash_size))) {
- fek_size = ntfs_decrypt_user_key_decrypt(key, fek_buf,
- fek_size);
- ntfs_decrypt_user_key_close(key);
- if (fek_size) {
- ntfs_decrypt_data_key *fek;
-
- ntfs_decrypt_user_key_session_close(session);
- fek = ntfs_decrypt_data_key_open(fek_buf,
- fek_size);
- free(efs_buffer);
- return fek;
- }
- fprintf(stderr, "Failed to decrypt the FEK.\n");
- } else
- perror("Failed to open user key");
- ddf = ddf + le32_to_cpu(*(u32*)(ddf + 0x08)) +
- le32_to_cpu(*(u32*)(ddf + 0x0c));
+ efs_attr = (EFS_ATTR_HEADER*)efs_buffer;
+ efs_df_array = (EFS_DF_ARRAY_HEADER*)(efs_buffer +
+ le32_to_cpu(efs_attr->offset_to_ddf_array));
+ fek = get_fek_from_df_array(session, efs_df_array);
+ if (!fek) {
+ efs_df_array = (EFS_DF_ARRAY_HEADER*)(efs_buffer +
+ le32_to_cpu(efs_attr->offset_to_drf_array));
+ fek = get_fek_from_df_array(session, efs_df_array);
}
+ /* Close all and return. */
ntfs_decrypt_user_key_session_close(session);
- return NULL;
+ free(efs_buffer);
+ return fek;
}
/**
|