Enhancing the Security of a Windows CE Device

Windows CE 3.0

Maricia Alforque
Microsoft Corporation

Updated October 2000

Applies to:
    Microsoft® Windows® CE version 3.0

Summary: This paper gives a high-level overview of the different options available in Windows CE 3.0 to enhance security for devices and applications. Familiarity with basic Microsoft security technologies and Win32 application programming interfaces (APIs) is assumed. (17 printed pages)

Contents

Introduction
Create a Trusted Environment
Use SSPI to Manage Security Providers
Use SSL to Enhance the Security of Network Communication
Encrypt Data Using CryptoAPI
Isolate Sensitive Data in a Smart Card
Identify Devices Uniquely
Use the Protected Kernel Mode
Use Digital Authentication in the Dial-up Boot Loader
For More Information

Introduction

Security services are an essential part of a modern operating system. Network infrastructures, system administration practices, and end users' experiences depend on the management, flexibility, and enforcement of security services. Microsoft® Windows® CE 3.0 extends the enterprise in an increasingly networked world without compromising security by providing an integrated set of security services employing features such as:

  • A trusted environment model.
  • The Security Support Provider Interface (SSPI).
  • Support for Windows NT® LAN Manager.
  • Support for the Secure Sockets Layer (SSL).
  • Cryptography.
  • A smart card infrastructure that supports the CryptoAPI.
  • A unique device identifier.
  • A kernel configuration with enhanced protection.
  • Digital authentication in the dial-up boot loader.

Create a Trusted Environment

Windows CE devices send, receive, and process information that requires protection from potentially unsafe applications. So, how do you protect your device? You can create a operating system (OS) with enhanced security that prevents the loading of unknown modules, restricts access to system APIs, and prevents write access to parts of the system registry.

To create a trusted environment, you must implement two functions:

  • OEMCertifyModuleInit
  • OEMCertifyModule

Before the kernel loads an application, the OEMCertifyModule function verifies the application signature to help protect your system from unfamiliar applications. This ensures that the Windows CE–based platform loads an application only if it contains a valid digital signature. The OEMCertifyModule function returns one of three options:

  1. Fully trusted to perform any operation.
  2. Trusted to run but restricted from calling certain functions.
  3. Not trusted and therefore not allowed to run.

The following table describes the two functions.

Function Description Return value
OEMCertifyModuleInit Enables the OS loader to notify the OEM that a new module is being loaded. It allows the OEM to decide whether to verify the module for safety. TRUE or FALSE
OEMCertifyModule Allows the OS loader to pass the module code (for example, DLL, EXE, and OCX) to the OEM for verification that it is safe to run on the system. OEM_CERTIFY_TRUST
OEM_CERTIFY_RUN
OEM_CERTIFY_FALSE

The following table describes the return values for OEMCertifyModule function.

Return value Description
OEM_CERTIFY_TRUST Trusted application to perform any operation.
OEM_CERTIFY_RUN Trusted application to run, but restricted from making any privileged function calls.
OEM_CERTIFY_FALSE Not trusted and therefore not allowed to run.

An OEMCertifyModule function can perform any type of check on the module that is loading, such as a cyclic redundancy check or certificate check. When a dynamic-link library (DLL) loads into the address space of an EXE, the trust level of the EXE determines the final access level. For example, when an EXE with the OEM_CERTIFY_RUN trust level tries to load a DLL that has a higher trust level (OEM_CERTIFY_TRUST), the final trust level of the DLL is OEM_CERTIFY_RUN. On the other hand, when the EXE tries to load a DLL that has a lower trust level, the DLL will fail to load.

The following table shows the different combinations of EXE and DLL trust levels.

EXE trust DLL trust Final DLL trust
OEM_CERTIFY_RUN OEM_CERTIFY_RUN OEM_CERTIFY_RUN
OEM_CERTIFY_RUN OEM_CERTIFY_TRUST OEM_CERTIFY_RUN
OEM_CERTIFY_TRUST OEM_CERTIFY_RUN DLL fails to load
OEM_CERTIFY_TRUST OEM_CERTIFY_TRUST OEM_CERTIFY_TRUST
Note   OEMs must digitally sign all third-party drivers or the drivers will fail to load. All drivers must be trusted when implementing this security model.

The simplest implementation of the trusted model uses the OEMCertifyModule function to return OEM_CERTIFY_RUN for all applications. This allows applications not part of the ROM MODULES section of the image to run, but restricted from making privileged function calls. This way you do not have to specify at run time which applications are trusted or not. If OEM_CERTIFY_FALSE is returned instead, then applications in RAM will not be able to run. In any case, the operating system files in the ROM MODULES section of the image will always run with full privileges.

To create a digital signature, you can use Signfile.exe, which is included in Platform Builder 3.0. Signfile.exe is a tool for signing an executable file with a private key that uses the Secure Hash Algorithm (SHA) to compute the cryptographic hash. For sample Signfile.exe code, see Public\Common\Oak\Tool\Signfile in Platform Builder 3.0 product CD.

To verify the signature at load time, you can use the Loadauth.lib functions provided in the processor-specific directory of Platform Builder in \Public\Common\Oak\Lib. For details about using Loadauth.lib functions, see the Platform Builder 3.0 documentation.

You can also write your own signature verification scheme instead of using the Platform Builder tools.

The following code shows an implementation example of the OEMCertifyModuleInit and OEMCertifyModule functions using Loadauth.lib functions:

/* The signature public key BLOB */
const unsigned char g_bSignPublicKeyBlob[] = {
0x06,0x02,0x00,0x00,0x00,0x24,0x00,0x00,0x52,0x53,0x41,0x31,0x00,0x02,
0x00,0x00,0x01,0x00,0x01,0x00,0xb1,0x00,0x93,0x7c,0x18,0x63,0xce,0xf3,
0x23,0xe3,0x57,0x74,0x13,0x54,0x17,0x2c,0xdb,0xf6,0x56,0x77,0xb3,0x8d,
0x34,0x6c,0x41,0x3d,0x4e,0xbb,0xc1,0xaf,0x3d,0x17,0xb6,0x0e,0x70,0x72,
0x43,0x12,0x1d,0xb1,0x2a,0x57,0x05,0x27,0x58,0x63,0xef,0xb7,0x3b,0x71,
0xee,0xe4,0xcd,0x14,0xbe,0xf7,0x32,0xec,0xa2,0xae,0xbf,0x9a,0x6b,0x75
};
// Declarations for load-time signature checking 
// of RAM executables
typedef BOOL (* OEMLoadInit_t)(LPWSTR lpszName);
typedef DWORD (* OEMLoadModule_t)(LPBYTE lpData, DWORD cbData);

extern OEMLoadInit_t pOEMLoadInit;
extern OEMLoadModule_t pOEMLoadModule;
extern BOOL InitPubKey(const BYTE *KeyBlob, DWORD cbKeyBlob);

// Loadauth library routines
extern BOOL CertifyModuleInit(void);
extern BOOL CertifyModule(PBYTE pbBlock, DWORD cbBlock);
extern BOOL CertifyModuleFinal(PBYTE *ppbSignData,
                               PDWORD pcbSignData);

// Called once for each RAM executable module
// to initialize signature checking
static BOOL OEMCertifyInit(LPWSTR lpszName)
{
    return CertifyModuleInit();
}

// called one or more times after OemLoadInit
static DWORD OEMCertifyModule(LPBYTE lpData, DWORD cbData)
{
    if (cbData)
    {
        // process module bytes
        return CertifyModule(lpData, cbData);
    }
    else
    {
        // final call
        DWORD dwTrustLevel = OEM_CERTIFY_FALSE;
        LPBYTE pSignedData;
        DWORD cbSignedData;
        BOOL fRet = CertifyModuleFinal(&pSignedData,
                                       &cbSignedData);
        if (fRet)
        {
            // the file has a valid signature
            // we expect the trust level to be returned as
            // signed data
            if (cbSignedData < sizeof(CHAR))
                dwTrustLevel = OEM_CERTIFY_RUN;
            else
            switch (*pSignedData)
            {
                case 'T' :
                    dwTrustLevel = OEM_CERTIFY_TRUST;
                    break;
                case 'R' :
                    dwTrustLevel = OEM_CERTIFY_RUN;
                    break;
                default:
                    dwTrustLevel = OEM_CERTIFY_FALSE;
                    break;
            }
        }
        #ifdef DEBUG
        if (!fRet)
        lpWriteDebugStringFunc(TEXT("OEMCertifyModule:signature
                                          check failed.\r\n"));
        #endif

        // return one of the OEM_CERTIFY levels
        return dwTrustLevel;
    }
}

void OEMInit()
{
    ...
    ...
    //
    // Set the module signature verification hooks.
    //
    pOEMLoadInit = OEMCertifyInit;
    pOEMLoadModule = OEMCertifyModule;
    //
    // Initialize the signature verification public key.
    //
    InitPubKey(g_bSignPublicKeyBlob,sizeof(g_bSignPublicKeyBlob));
    
    // 
    // Other OEM initialization steps
    //
    ...
}

Note   The names of the functions OEMCertifyModuleInit and OEMCertifyModule are arbitrary; you can use any name. However, it is important to initialize the two kernel pointers, pOEMLoadInit and pOEMLoadModule, in the OEMInit function to these named functions.

Restricted APIs

In addition to the OEM functions, the CeGetCurrentTrust and CeGetCallerTrust APIs enable a DLL to query the trust level of a calling application. You can use these functions to verify the trust levels of the applications.

Untrusted modules are restricted from calling the following APIs:

  • SetInterruptEvent
  • SetSystemMemoryDivision
  • CESetThreadPriority
  • CeSetThreadQuantum
  • ForcePageout
  • VirtualCopy
  • LockPages
  • UnlockPages
  • SetProcPermissions
  • SetKMode
  • ReadProcessMemory
  • WriteProcessMemory
  • SetCleanRebootFlag
  • PowerOffSystem
  • DebugActiveProcess

Debug flags, DEBUG_ONLY_THIS_PROCESS and DEBUG_PROCESS, in the CreateProcess API are restricted as well.

The registry architecture in Windows CE 3.0 allows only "trusted applications" (OEM_CERTIFY_TRUST) that you have identified to modify keys and values in the protected registries.

In Windows CE 3.0 the following registry root keys and their subkeys are protected from untrusted applications:

  • HKEY_LOCAL_MACHINE\Comm
  • HKEY_LOCAL_MACHINE\Drivers
  • HKEY_LOCAL_MACHINE\HARDWARE
  • HKEY_LOCAL_MACHINE\SYSTEM
  • HKEY_LOCAL_MACHINE\Init
  • HKEY_LOCAL_MACHINE\WDMDrivers

Additionally, untrusted applications receive the ERROR_ACCESS_DENIED return value if they attempt to use the following registry functions:

  • RegSetValueEx
  • RegCreateKeyEx
  • RegDeleteKey
  • RegDeleteValue

Because the rest of the registry is unprotected, OEMs must place all important registry information in one of the protected keys.

Note   All applications have read-only access to all registry keys and values.

Use SSPI to Manage Security Providers

The Security Support Provider Interface (SSPI), which is available through the Secur32.dll module, is a well-defined common API for obtaining integrated security services for authentication, enhanced message integrity and privacy. It provides an abstraction layer between application-level protocols and security protocols. Because different applications require different ways of identifying or authenticating users and different ways of encrypting data as it travels across a network, Windows CE SSPI provides a way to access DLLs containing different authentication and cryptographic data schemes. These DLLs are called Security Support Providers (SSPs).

The following illustration shows the relationship of the SSP DLLs to the SSPI Secur32.dll, Winsock, and WinInet.

Figure 1. Relationship of the SSP DLLs to the SSPI Secur32.dll, Winsock, and WinInet

The SSPI makes one or more SSPs, also called security packages, available to applications. A security package maps various SSPI functions to an implementation of the security protocol specific to that package. OEMs can also write their own security packages and then add them to the registry.

The following SSPs are available in Windows CE 3.0:

  • Schannel Cryptographic Provider
  • Windows NT LAN Manager SSP

SSPI Functions

SSPI allows application developers to use one of several SSPs without detailed knowledge of the security protocols.

The following tables show the SSPI functions supported by Windows CE 3.0.

Credential management functions provide access to credentials of a principal. A principal is an entity recognized by the operating system, which may be a user or a process. A principal uses credentials to establish the identity of a user or an application.

Function Description
AcquireCredentialsHandle Allows an application to acquire a handle to credentials.
FreeCredentialsHandle Releases a credential handle and any associated resources.
QueryCredentialsAttributes Retrieves the credential attributes.

Context management functions enable applications to create and use a security context. A security context is the security data relevant to a connection and contains data such as a session key and the session duration. Both the client and server must cooperate to create a security context.

Function Description
InitializeSecurityContext Initiates a security context by generating a token that can be passed to a server or a remote peer.
AcceptSecurityContext Establishes a security context using a redirector to validate credentials.
DeleteSecurityContext Releases a security context and deletes the local data structures associated with it.
QueryContextAttributes Retrieves the security context attributes.
ApplyControlToken Applies a supplemental security message to an existing security context.
FreeContextBuffer Releases the memory buffer allocated by the security provider.

Message support functions use a security context to ensure message integrity and privacy during message exchanges over the secured connection. Integrity is achieved through message signing and signature verification. Privacy is enhanced through message encryption and decryption.

Function Description
MakeSignature Generates a cryptographic checksum of the message and includes sequencing data to prevent message loss or insertion. This function also enables the application to choose from several cryptographic algorithms.
VerifySignature Verifies the message signature.

Package management functions provide services for the various security packages that are supported.

Function Description
EnumerateSecurityPackages Lists available security packages and their capabilities.
QuerySecurityPackageInfo Retrieves the specified package information.

User Authentication and DCOM Security

In client-server applications, Windows CE 3.0 uses the Windows NT LAN Manager Security Support Provider (NTLMSSP.dll) for user authentication. The client applications supply the user name, domain name, and password to the NTLMSSP and the server and client applications exchange tokens to complete the authentication.

Server applications running on Windows CE can also leverage the Windows NT LAN Manager security package. For example, the Distributed Component Object Model (DCOM) uses the Windows NT LAN Manager protocol to establish the user credentials if the RPC_C_AUTHN_WINNT flag is selected.

Although authentication in Windows CE is similar to Windows NT, there are marked differences. In Windows NT, authentication can take place each time the client connects with the server, each time the client calls, or each time the client and the server exchange data; authentication can also be disabled. Windows NT supports impersonation, which allows an object to acquire the security credentials of an authenticated user or client, whereas Windows CE does not. In Windows CE, authentication is done at the connect level only (RPC_C_AUTH_LEVEL_CONNECT). At the connect level, DCOM does an authentication check the first time a client calls the server and if the client passes the check, no authentication takes place on subsequent calls. A DCOM object on Windows CE can make calls at any authentication level, but incoming calls will never arrive with an authentication level that is higher than CONNECT. Additionally, Windows CE authentication can be disabled (RPC_C_AUTHN_LEVEL_NONE).

After a successful authentication, the access check is performed against an access list, which identifies the principals who can launch classes on the system. The list is created from the DefaultAccessPermissions registry settings or provided programmatically from the DCOMAccessControl object during server initialization.

Authentication proceeds normally when a Windows CE client is connected by a network to a Windows NT domain controller, which manages the security credentials. However, in a mobile environment when a Windows NT domain controller is not always available or when the network is not Windows NT based, you can create a local database of user name and passwords for the Windows NT LAN Manager security package to use for verifying credentials. Windows CE provides the following APIs to create and manage this local security database:

  • NTLMEnumUser returns the registered user name for any given index to the database.
  • NTLMSetUserInfo creates a user in the database (if none exists) and changes the information in that entry.
  • NTLMDeleterUser removes a user from the database.

Use SSL to Enhance the Security of Network Communication

In order to enhance secure network communication, Windows CE also supports SSL versions 2.0 and 3.0 security protocols, which are available through WinInet or directly from WinSock. These applications use secure sockets to send and receive encoded data over the communication lines.

Secure socket implementation relies on authentication to determine if a remote host can be trusted. Remote hosts establish their trustworthiness by obtaining a certificate from a certification authority (CA). The CA may, in turn, have certification from a higher authority and so on, creating a chain of trust. To determine whether a certificate is trustworthy, an application must determine the identity of the root CA and then determine if it is trustworthy.

Windows CE 3.0 SSL maintains a database of trusted CAs, which is independent of CryptoAPI 2.0 certificate store. When a secure connection is attempted by an application, Windows CE 3.0 extracts the root certificate from the certification chain and checks it against the CA database. It delivers the server certificate to the application through a certificate validation callback function, along with the results of the comparison against the CA database.

Applications bear the ultimate responsibility for verifying that a certificate is acceptable. Applications can accept or reject any certificate. If a certificate is rejected, the connection is not completed. At a minimum, a certificate should meet two requirements: the certificate is current and the identity contained in the certificate matches the identity of the entity to which you are connecting. A list of root certificate authorities is included in the channel CA database. Note that these root certificates expire and may need to be updated periodically. The database can also be updated to add more CAs by editing the registry.

The following root certificate authorities are included in the Windows CE 3.0 Schannel CA database:

  • VeriSign/RSA Secure Server
  • VeriSign Class 1 Public Primary CA
  • VeriSign Class 2 Public Primary CA
  • VeriSign Class 3 Public Primary CA
  • GTE Cybertrust ROOT
  • Thawte Personal Basic CA
  • Thawte Personal Freemail CA
  • Thawte Personal Premium CA
  • Microsoft Root Authority
  • Root SGC Authority
  • Entrust.net Secure Server CA
  • Entrust.net Premium Secure Server CA

Encrypt Data Using CryptoAPI

CryptoAPI provides services that enable application developers to add data encryption/decryption schemes, to authenticate using digital certificates, and to encode/decode to and from ASN.1 to their Win32-based applications. Application developers can use the functions in CryptoAPI without detailed knowledge of the underlying implementation. CryptoAPI works with a number of cryptographic service providers (CSPs) that perform the actual cryptographic functions, such as encryption, decryption, and key storage and security.

The three elements of the Microsoft cryptographic system are the operating system, the application, and the CSP. Applications communicate with the operating system through the CryptoAPI layer and the operating system communicates with the CSPs through the cryptographic service provider interface (CSPI). The following figure illustrates the concept.

Figure 2. Applications communicate with the operating system through the CryptoAPI layer and the operating system communicates with the CSPs through the cryptographic service provider interface (CSPI).

CSPs are independent modules, usually a DLL, that perform all cryptographic operations. Ideally, CSPs are written to be independent of a particular application, so that any application will run with a variety of CSPs. In reality, however, some applications have specific requirements that require a customized CSP. EOMs can write their own CSP package and add it to the registry.

The following table describes the two predefined CSPs included in Windows CE 3.0.

CSP Description
RSA Base Provider Supports digital signature and data encryption. It is considered a general-purpose cryptographic tool.
RSA Enhanced Provider Supports 128-bit key encryption. It provides stronger security through longer keys and additional algorithms.

Applications can use CryptoAPI functions to:

  • Generate and exchange keys.
  • Encrypt and decrypt data.
  • Encode and decode certificates.
  • Manage and enhance security of certificates.
  • Create and verify digital signatures and compute hash.

The capabilities provided by CryptoAPI 1.0 in Windows CE 3.0 are very similar to the Windows 2000 and Windows NT; however, only a subset of CryptoAPI 2.0 is supported. The following capabilities available in CryptoAPI 2.0 are supported in Windows CE 3.0: encoding and decoding digital certificates based on the X.509 standard and certificate management. The following capabilities are not supported: tools to manage certificate revocation lists (CRLs) and certificate trust lists (CTLs), low-level messaging functions, and simplified messaging functions.

Coredll.lib exports CryptoAPI 1.0 functions and Crypto32.lib exports the CryptoAPI 2.0 functions; all these functions are defined in the Wincrypt.h header file.

Isolate Sensitive Data in a Smart Card

You can add an additional layer of security to a Windows CE device by using smart cards to store authentication information or a digital signing mechanism. You can write a custom CryptoAPI provider that exploits a smart card's ability to store information with enhanced security.

The Windows CE smart card subsystem supports CrytoAPI through smart card service providers (SCSPs), which are DLLs that enable access to specific services. The subsystem provides a link between the smart card reader hardware and the applications. Windows CE does not provide SCSPs; typically, the smart card vendor provides the appropriate SCSPs. However, Windows CE provides the interfaces described in the following table.

Subsystem component File Description
Resource manager Scard.dll Uses the Win32 APIs to manage access to multiple readers and smart cards.
Resource manager helper library Winscard.dll Exposes PC/SC services for using smart cards and smart card readers.
Smart card reader helper library Smclib.lib Provides common smart card driver support routines and additional T=0 and T=1 protocol support to specific drivers as needed.
Sample smart card reader drivers Pscr.dll

bulltlp3.dll

stcusb.dll

SwapSmart PC reader driver.

Serial reader driver.

Universal serial bus (USB) reader driver.

A typical smart card system consists of applications, a subsystem that handles communication between smart card readers and the applications, readers, and the smart card. The following diagram illustrates the architecture of a Windows CE–based smart card system.

Figure 3. Windows CE–based smart card system architecture

Implementing a fraction of the smart card CryptoAPI service provider functionality in a separate hardware keeps the cryptographic keys and operations safer because it:

  • Provides tamper-resistant storage for protecting private keys and other forms for personal information.
  • Isolates security-critical computations involving authentication, digital signatures, and key exchange from other parts of the system.
  • Enables portability of credentials and other private information.

In an organization that uses smart cards, users don't have to remember any passwords at all (only a personal identification number or PIN), and they can use the same certificate for other security purposes, such as digitally signing e-mail.

Identify Devices Uniquely

OEMs can provide a unique identification tag to a Windows CE device, which can be accessed by an application. For example, you may need to identify each cell phone that runs your OS image for billing and security purposes.

Windows CE uses the DEVICE_ID structure to hold the unique device identification number. The input/output control IOCTL_HAL_GET_DEVICEID in the OEM adaptation layer returns the current DEVICE_ID assigned to the Windows CE device. For more information, see "Providing Platform Information for Applications" in the Operating System Development section of the Platform Builder documentation.

Use the Protected Kernel Mode

Using the full-kernel mode while running threads leaves the entire systems vulnerable because Windows CE bypasses the security features. In the full-kernel mode, applications can access any physical memory in the system. This leaves the system open to malicious applications that hunt for privileged information and encryption codes or those that delete files.

While running in the full-kernel mode increases performance, this may not be acceptable in an open unprotected environment. You can disable the full-kernel mode; set the second bit of the ROMFLAGS in the Config.bib file. Depending on what other flags are set, the value of ROMFLAGS may vary.

Use Digital Authentication in the Dial-up Boot Loader

The dial-up boot loader is a program stored in ROM used to upgrade the OS image file (Nk.bin) using flash memory or a remote server. To ensure the integrity of the OS image that is downloaded, you can use digital encryption to sign and verify OS image files. The dial-up boot loader uses the Microsoft CryptoAPI to authenticate data using the asymmetric hashing algorithm (CALG_SHA), which produces a 160-bit hash value.

Platform Builder 3.0 provides the following tools for digital authentication:

  • Makekey.exe, which creates a public/private key pair.
  • Mksigs.exe, which signs the OS image files.
  • Addsigs.exe, which appends the signatures to the manifest file.

During the OS image download process, the dial-up boot loader extracts the signatures from the manifest file and verifies the authenticity of each OS image file. If authentication fails, the download process halts and the user is notified.

For More Information

For implementation details on SSPI, secure sockets layer, CryptoAPI, and smart cards, see the Windows CE Programmers' Reference, version 3.0.

For implementation details on the kernel-level security (trusted model and kernel mode), the device label, and the dial-up boot loader, see the Windows CE Platform Builder 3.0.

Also see the MSDN Online Windows Embedded Developer Center at http://msdn.microsoft.com/embedded.

For more information on smart cards, see the PC/SC Workgroup Web site.

Show: