windows-nt/Source/XPSP1/NT/public/internal/drivers/inc/efsstruc.h

672 lines
17 KiB
C
Raw Permalink Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
efsstruc.h
Abstract:
EFS (Encrypting File System) defines, data and function prototypes.
Author:
Robert Reichel (RobertRe)
Robert Gu (RobertG)
Environment:
Revision History:
--*/
#ifndef _EFSSTRUC_
#define _EFSSTRUC_
#ifdef __cplusplus
extern "C" {
#endif
#ifndef ALGIDDEF
#define ALGIDDEF
typedef unsigned int ALG_ID;
#endif
//
// Our OID. Remove from here once it's in the real headers.
//
#ifndef szOID_EFS_CRYPTO
#define szOID_EFS_CRYPTO "1.3.6.1.4.1.311.10.3.4"
#endif
#ifndef szOID_EFS_RECOVERY
#define szOID_EFS_RECOVERY "1.3.6.1.4.1.311.10.3.4.1"
#endif
//
// Context flag
//
#define CONTEXT_FOR_EXPORT 0x00000000
#define CONTEXT_FOR_IMPORT 0x00000001
#define CONTEXT_INVALID 0x00000002
#define CONTEXT_OPEN_FOR_DIR 0x00008000
//
// Context ID
//
#define EFS_CONTEXT_ID 0x00000001
//
// Signature type
//
#define SIG_LENGTH 0x00000008
#define SIG_NO_MATCH 0x00000000
#define SIG_EFS_FILE 0x00000001
#define SIG_EFS_STREAM 0x00000002
#define SIG_EFS_DATA 0x00000003
//
// Export file format stream flag information
//
#define STREAM_NOT_ENCRYPTED 0x0001
#define EFS_EXP_FORMAT_CURRENT_VERSION 0x0100
#define EFS_SIGNATURE_LENGTH 4
#define EFS_STREAM_ID 0x1910
#define FSCTL_IMPORT_INPUT_LENGTH 4 * 1024
#define FSCTL_EXPORT_INPUT_LENGTH 128
#define FSCTL_OUTPUT_INITIAL_LENGTH 68 * 1024
#define FSCTL_OUTPUT_LESS_LENGTH 8 * 1024
#define FSCTL_OUTPUT_MIN_LENGTH 20 * 1024
#define FSCTL_OUTPUT_MISC_LENGTH 4 * 1024
//
// FSCTL data shared between server and driver
//
#define EFS_SET_ENCRYPT 0
#define EFS_SET_ATTRIBUTE 1
#define EFS_DEL_ATTRIBUTE 2
#define EFS_GET_ATTRIBUTE 3
#define EFS_OVERWRITE_ATTRIBUTE 4
#define EFS_ENCRYPT_DONE 5
#define EFS_DECRYPT_BEGIN 6
//
// Mask for Set EFS Attribute
//
#define WRITE_EFS_ATTRIBUTE 0x00000001
#define SET_EFS_KEYBLOB 0x00000002
//
// Sub code of SET_ENCRYPT FSCTL
//
#define EFS_FSCTL_ON_DIR 0x80000000
#define EFS_ENCRYPT_FILE 0x00000001
#define EFS_DECRYPT_FILE 0x00000002
#define EFS_ENCRYPT_STREAM 0x00000003
#define EFS_DECRYPT_STREAM 0x00000004
#define EFS_DECRYPT_DIRFILE 0x80000002
#define EFS_ENCRYPT_DIRSTR 0x80000003
#define EFS_DECRYPT_DIRSTR 0x80000004
//
// EFS Version Information
//
// EFS_CURRENT_VERSION must always be the highest known revision
// level. This value is placed in the EfsVersion field of the
// $EFS header.
//
#define EFS_VERSION_1 (0x00000001)
#define EFS_VERSION_2 (0x00000002)
#define EFS_CURRENT_VERSION EFS_VERSION_2
///////////////////////////////////////////////////////////////////////////////
// /
// EFS Data structures /
// /
///////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// /
// EFS_KEY Structure /
// /
/////////////////////////////////////////////////////////////////////
typedef struct _EFS_KEY {
//
// The length in bytes of the appended key.
//
ULONG KeyLength;
//
// The number of bits of entropy in the key.
// For example, an 8 byte key has 56 bits of
// entropy.
//
ULONG Entropy;
//
// The algorithm used in conjunction with this key.
//
// Note: this is not the algorithm used to encrypt the
// actual key data itself.
//
ALG_ID Algorithm;
//
// This structure must be a multiple of 8 in size,
// including the KeyData at the end.
//
ULONG Pad;
//
// KeyData is appended to the end of the structure.
//
// UCHAR KeyData[1];
} EFS_KEY, *PEFS_KEY;
//
// Private macros to manipulate data structures
//
#define EFS_KEY_SIZE( pKey ) (sizeof( EFS_KEY ) + (pKey)->KeyLength)
#define EFS_KEY_DATA( Key ) (PUCHAR)(((PUCHAR)(Key)) + sizeof( EFS_KEY ))
#define OFFSET_TO_POINTER( FieldName, Base ) ((PCHAR)(Base) + (Base)->FieldName)
#define POINTER_TO_OFFSET( Pointer, Base ) (((PUCHAR)(Pointer)) - ((PUCHAR)(Base)))
//
// We're going to use MD5 to hash the EFS stream. MD5 yields a 16 byte long hash.
//
#define MD5_HASH_SIZE 16
typedef struct _EFS_DATA_STREAM_HEADER {
ULONG Length;
ULONG State;
ULONG EfsVersion;
ULONG CryptoApiVersion;
GUID EfsId;
UCHAR EfsHash[MD5_HASH_SIZE];
UCHAR DrfIntegrity[MD5_HASH_SIZE];
ULONG DataDecryptionField; //Offset to DDF
ULONG DataRecoveryField; //Offset to DRF
ULONG Reserved;
ULONG Reserved2;
ULONG Reserved3;
} EFS_DATA_STREAM_HEADER, *PEFS_DATA_STREAM_HEADER;
///////////////////////////////////////////////////////////////////////////////
// /
// EFS_PUBLIC_KEY_INFO /
// /
// This structure is used to contain all the information necessary to decrypt /
// the FEK. /
// /
///////////////////////////////////////////////////////////////////////////////
typedef struct _EFS_CERT_HASH_DATA {
ULONG pbHash; // offset from start of structure
ULONG cbHash; // count of bytes in hash
ULONG ContainerName; // hint data, offset to LPWSTR
ULONG ProviderName; // hint data, offset to LPWSTR
ULONG lpDisplayInformation; // offset to an LPWSTR
} EFS_CERT_HASH_DATA, *PEFS_CERT_HASH_DATA;
typedef struct _EFS_PUBLIC_KEY_INFO {
//
// The length of this entire structure, including string data
// appended to the end.
//
ULONG Length;
//
// Sid of owner of the public key (regardless of format).
// This field is to be treated as a hint only.
//
ULONG PossibleKeyOwner;
//
// Contains information describing how to interpret
// the public key information
//
ULONG KeySourceTag;
union {
struct {
//
// The following fields contain offsets based at the
// beginning of the structure. Each offset is to
// a NULL terminated WCHAR string.
//
ULONG ContainerName;
ULONG ProviderName;
//
// The exported public key used to encrypt the FEK.
// This field contains an offset from the beginning of the
// structure.
//
ULONG PublicKeyBlob;
//
// Length of the PublicKeyBlob in bytes
//
ULONG PublicKeyBlobLength;
} ContainerInfo;
struct {
ULONG CertificateLength; // in bytes
ULONG Certificate; // offset from start of structure
} CertificateInfo;
struct {
ULONG ThumbprintLength; // in bytes
ULONG CertHashData; // offset from start of structure
} CertificateThumbprint;
};
} EFS_PUBLIC_KEY_INFO, *PEFS_PUBLIC_KEY_INFO;
//
// Possible KeyTag values
//
typedef enum _PUBLIC_KEY_SOURCE_TAG {
EfsCryptoAPIContainer = 1,
EfsCertificate,
EfsCertificateThumbprint
} PUBLIC_KEY_SOURCE_TAG, *PPUBLIC_KEY_SOURCE_TAG;
///////////////////////////////////////////////////////////////////////////////
// /
// RECOVERY_KEY Data Structure /
// /
///////////////////////////////////////////////////////////////////////////////
//
// Current format of recovery data.
//
typedef struct _RECOVERY_KEY_1_1 {
ULONG TotalLength;
EFS_PUBLIC_KEY_INFO PublicKeyInfo;
} RECOVERY_KEY_1_1, *PRECOVERY_KEY_1_1;
///////////////////////////////////////////////////////////////////////////////
// /
// KEY_INTEGRITY_INFO /
// /
// The KEY_INTEGRITY_INFO structure is used to verify that /
// the user's key has correctly decrypted the file's FEK. /
// /
///////////////////////////////////////////////////////////////////////////////
typedef struct _KEY_INTEGRITY_INFO {
//
// The length of the entire structure, including the
// variable length integrity information appended to
// the end
//
ULONG Length;
//
// The algorithm used to hash the combined FEK and
// public key
//
ALG_ID HashAlgorithm;
//
// The length of just the hash data.
//
ULONG HashDataLength;
//
// Integrity information goes here
//
// UCHAR Integrity Info[]
} KEY_INTEGRITY_INFO, *PKEY_INTEGRITY_INFO;
typedef struct _EFS_KEY_SALT {
ULONG Length; // total length of header plus data
ULONG SaltType; // figure out what you want for this
//
// Put data here, so total length of the structure is
// sizeof( EFS_KEY_SALT ) + length of your data
//
} EFS_KEY_SALT, *PEFS_KEY_SALT;
//
// EFS Private DataStructures
//
typedef struct _ENCRYPTED_KEY {
//
// Total length of this structure and its data
//
ULONG Length;
//
// contains an offset from beginning of structure,
// used to decrypt the EncryptedKey
//
ULONG PublicKeyInfo;
//
// Length in bytes of EncryptedFEK field
//
ULONG EncryptedFEKLength;
//
// offset from beginning of structure to encrypted
// EFS_KEY containing the FEK
//
// Type is PUCHAR because data is encrypted.
//
ULONG EncryptedFEK;
//
// offset from beginning of structure to KEY_INTEGRITY_INFO
//
ULONG EfsKeySalt;
//
// FEK Data
//
// KEY_INTEGRITY_INFO Data
//
// PEFS_PUBLIC_KEY_INFO Data
//
} ENCRYPTED_KEY, *PENCRYPTED_KEY;
//
// The Key Ring Structure.
//
typedef struct _ENCRYPTED_KEYS {
ULONG KeyCount;
ENCRYPTED_KEY EncryptedKey[1];
} ENCRYPTED_KEYS, *PENCRYPTED_KEYS;
typedef ENCRYPTED_KEYS DDF, *PDDF;
typedef ENCRYPTED_KEYS DRF, *PDRF;
typedef struct _EFS_STREAM_SIZE {
ULONG StreamFlag;
LARGE_INTEGER EOFSize;
LARGE_INTEGER AllocSize;
} EFS_STREAM_SIZE, *PEFS_STREAM_SIZE;
#define NEXT_ENCRYPTED_KEY( pEncryptedKey ) (PENCRYPTED_KEY)(((PBYTE)(pEncryptedKey)) + *((ULONG UNALIGNED *)&((PENCRYPTED_KEY)(pEncryptedKey))->Length))
//
// Import context
//
typedef struct IMPORT_CONTEXT{
ULONG ContextID; //To distinguish from other LSA context. Offset is fixed across LSA.
ULONG Flag; // Indicate the type of context
HANDLE Handle; // File handle, used to create rest streams
ULONG Attribute;
ULONG CreateDisposition;
ULONG CreateOptions;
ULONG DesiredAccess;
} IMPORT_CONTEXT, *PIMPORT_CONTEXT;
//
// Export context
//
typedef struct EXPORT_CONTEXT{
ULONG ContextID; //To distinguish from other LSA context. Offset is fixed across LSA.
ULONG Flag; // Indicate the type of context
HANDLE Handle; // File handle, used to open rest streams
ULONG NumberOfStreams;
PHANDLE StreamHandles;
PUNICODE_STRING StreamNames;
PFILE_STREAM_INFORMATION StreamInfoBase;
} EXPORT_CONTEXT, *PEXPORT_CONTEXT;
//
// EFS Export/Import RPC pipe status
//
typedef struct EFS_EXIM_STATE{
PVOID ExImCallback;
PVOID CallbackContext;
char *WorkBuf;
ULONG BufLength;
ULONG Status;
} EFS_EXIM_STATE, *PEFS_EXIM_STATE;
//
// Export file format
//
typedef struct EFSEXP_FILE_HEADER{
ULONG VersionID; // Export file version
WCHAR FileSignature[EFS_SIGNATURE_LENGTH]; // Signature of the file
ULONG Reserved[2];
//STREAM_DADA Streams[0]; // An array of STREAM_BLOCK
} EFSEXP_FILE_HEADER, *PEFSEXP_FILE_HEADER;
typedef struct EFSEXP_STREAM_HEADER{
ULONG Length; // Redundant information. The length of this block not including DataBlocks but
// including itself; This field is to simplify the import routine.
WCHAR StreamSignature[EFS_SIGNATURE_LENGTH]; // Signature of the stream
ULONG Flag; // Indicating if the stream is encrypted or not and etc.
ULONG Reserved[2]; // For future use
ULONG NameLength; // Length of the stream name
//WCHAR StreamName[0]; // ID of the stream, Binary value can be used.
//DATA_BLOCK DataBlocks[0]; // Variable number of data block
} EFSEXP_STREAM_HEADER, *PEFSEXP_STREAM_HEADER;
typedef struct EFSEXP_DATA_HEADER{
ULONG Length; // Length of the block including this ULONG
WCHAR DataSignature[EFS_SIGNATURE_LENGTH]; // Signature of the data
ULONG Flag; // For future use.
// BYTE DataBlock[N]; // N = Length - 2 * sizeof (ULONG) - 4 * sizeof (WCHAR)
} EFSEXP_DATA_HEADER, *PEFSEXP_DATA_HEADER;
//
// TotalLength - total length of the RECOVERY_KEY Datastructure.
//
// KeyName - the storage stream will actually have the characters terminated by
// a NULL character.
// AlgorithmId - CryptAPI Algorithm ID - in V1 it is always RSA.
//
// CSPName - the storage stream will actually have the characters terminated by
// a NULL character.
// CSPType - CryptAPI type of CSP.
//
// PublicBlobLength - Length of the public blob that is importable in CryptoAPI in bytes.
//
//
// Recovery Policy Data Structures
//
typedef struct _RECOVERY_POLICY_HEADER {
USHORT MajorRevision;
USHORT MinorRevision;
ULONG RecoveryKeyCount;
} RECOVERY_POLICY_HEADER, *PRECOVERY_POLICY_HEADER;
typedef struct _RECOVERY_POLICY_1_1 {
RECOVERY_POLICY_HEADER RecoveryPolicyHeader;
RECOVERY_KEY_1_1 RecoveryKeyList[1];
} RECOVERY_POLICY_1_1, *PRECOVERY_POLICY_1_1;
#define EFS_RECOVERY_POLICY_MAJOR_REVISION_1 (1)
#define EFS_RECOVERY_POLICY_MINOR_REVISION_0 (0)
#define EFS_RECOVERY_POLICY_MINOR_REVISION_1 (1)
//
// Major/Minor Revision - revision number of policy information.
//
// RecoveryKeyCount - number of recovery keys configured in this policy.
//
// RecoveryKeyList - array of recovery keys.
//
//
// Session Key Structure
//
#define SESSION_KEY_SIZE 8
#define COMMON_FSCTL_HEADER_SIZE (7 * sizeof( ULONG ) + 2 * SESSION_KEY_SIZE)
typedef struct _EFS_INIT_DATAEXG {
UCHAR Key[SESSION_KEY_SIZE];
HANDLE LsaProcessID; // The reason we use HANDLE is for the sake of 64 bits
} EFS_INIT_DATAEXG, *PEFS_INIT_DATAEXG;
//
// Server API, callable from kernel mode
//
NTSTATUS
EfsGenerateKey(
PEFS_KEY * Fek,
PEFS_DATA_STREAM_HEADER * EfsStream,
PEFS_DATA_STREAM_HEADER DirectoryEfsStream,
ULONG DirectoryEfsStreamLength,
PVOID * BufferBase,
PULONG BufferLength
);
NTSTATUS
GenerateDirEfs(
PEFS_DATA_STREAM_HEADER DirectoryEfsStream,
ULONG DirectoryEfsStreamLength,
PEFS_DATA_STREAM_HEADER * NewEfs,
PVOID * BufferBase,
PULONG BufferLength
);
#define EFS_OPEN_NORMAL 1
#define EFS_OPEN_RESTORE 2
#define EFS_OPEN_BACKUP 3
NTSTATUS
EfsDecryptFek(
IN OUT PEFS_KEY * Fek,
IN PEFS_DATA_STREAM_HEADER CurrentEfs,
IN ULONG EfsStreamLength,
IN ULONG OpenType, //Normal, Recovery or Backup
OUT PEFS_DATA_STREAM_HEADER *NewEfs, //In case the DDF, DRF are changed
PVOID * BufferBase,
PULONG BufferLength
);
NTSTATUS
GenerateSessionKey(
OUT EFS_INIT_DATAEXG * SessionKey
);
//
// Private usermode server API
//
ULONG
EfsEncryptFileRPCClient(
IN PUNICODE_STRING FileName
);
ULONG
EfsDecryptFileRPCClient(
PUNICODE_STRING FileName,
ULONG OpenFlag
);
ULONG
EfsOpenFileRawRPCClient(
IN LPCWSTR FileName,
IN ULONG Flags,
OUT PVOID * Context
);
VOID
EfsCloseFileRawRPCClient(
IN PVOID Context
);
#ifdef __cplusplus
}
#endif
#endif // _EFSSTRUC_