⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbl.cpp

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 CPP
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//------------------------------------------------------------------------------
//
//  File:  SBL.cpp
//
//  Secure Boot Loader - verify the digital signature of a data packet
//

#include <windows.h>
#include <mincrypt.h>

#include <SBL.h>


#define CBR(x) if (!(x)) { hr = E_FAIL; goto Error; }


/////////////////////////////////////////////////
// Globals
//

static BOOL         bFoundCorrectKey = FALSE;
static BYTE         bHash[MINCRYPT_MAX_HASH_LEN];
static const BYTE * gpbPublicKey;
static DWORD        gdwPublicKeyLen;

/////////////////////////////////////////////////
// Verify
//

static HRESULT Verify(const BYTE * pbSig,   DWORD dwSigLen,
                      const BYTE * pbKey,   DWORD dwKeyLen,
                      BYTE * pbHash,        DWORD dwHashLen) 
{
    
    HRESULT hr = S_OK;
    LONG lResult;

    CRYPT_DER_BLOB blobSig;
    CRYPT_DER_BLOB blobKey;

    blobSig.cbData = dwSigLen;
    blobSig.pbData = const_cast <BYTE *> (pbSig);

    blobKey.cbData = dwKeyLen;
    blobKey.pbData = const_cast <BYTE *> (pbKey);

    lResult = MinCryptVerifySignedHash(
        CALG_SHA1,
        pbHash,
        dwHashLen,
        &blobSig,
        &blobKey);

#ifdef DEBUG
    NKDbgPrintfW(L"MinCryptVerifySignedHash() returned 0x%x\r\n", lResult);
#endif 

    CBR(ERROR_SUCCESS == lResult);

Error:
    return hr;
}

/////////////////////////////////////////////////
// SBL_VerifyPacket
//

HRESULT SBL_VerifyPacket(const PACKETDATA    * pPacketData, 
                         const PUBLICKEYDATA * pKeyData) 
{
    
    DWORD i, hHash, dwHashLen = 0;
    HRESULT hr = S_OK;
    LONG lReturn;
    BOOL bVerified = FALSE;
    CRYPT_DER_BLOB blob;
    
    lReturn = MinCryptCreateHashMemory(CALG_SHA1, &hHash);
    CBR(ERROR_SUCCESS == lReturn);
    
    // See if this packet contains any data
    // If so hash that data
    
    if (0 != pPacketData->dwDataLength) 
    {
        blob.cbData = pPacketData->dwDataLength;
        blob.pbData = const_cast <BYTE *> (pPacketData->pbData);

        lReturn = MinCryptUpdateHashMemory(CALG_SHA1, hHash, 1, &blob);
        CBR(ERROR_SUCCESS == lReturn);
    }

    // Store RecAddress, RecLength, RecCheck in the hash
    // Allows verification of these elements

    blob.cbData = sizeof(pPacketData->dwRecAddress);
    blob.pbData = (BYTE *) &pPacketData->dwRecAddress;
    lReturn = MinCryptUpdateHashMemory(CALG_SHA1, hHash, 1, &blob);
    CBR(ERROR_SUCCESS == lReturn);

    blob.cbData = sizeof(pPacketData->dwRecLength);
    blob.pbData = (BYTE *) &pPacketData->dwRecLength;
    lReturn = MinCryptUpdateHashMemory(CALG_SHA1, hHash, 1, &blob);
    CBR(ERROR_SUCCESS == lReturn);

    blob.cbData = sizeof(pPacketData->dwRecCheck);
    blob.pbData = (BYTE *) &pPacketData->dwRecCheck;
    lReturn = MinCryptUpdateHashMemory(CALG_SHA1, hHash, 1, &blob);
    CBR(ERROR_SUCCESS == lReturn);

    blob.cbData = sizeof(pPacketData->bFlags);
    blob.pbData = (BYTE *) &pPacketData->bFlags;
    lReturn = MinCryptUpdateHashMemory(CALG_SHA1, hHash, 1, &blob);
    CBR(ERROR_SUCCESS == lReturn);

    // Hash the global file random seed

    blob.cbData = RANDOM_SEED_LENGTH;
    blob.pbData = (BYTE *) pPacketData->bRandomSeed;
    lReturn = MinCryptUpdateHashMemory(CALG_SHA1, hHash, 1, &blob);
    CBR(ERROR_SUCCESS == lReturn);

    // Hash the sequence number

    blob.cbData = sizeof(pPacketData->dwSequenceNumber);
    blob.pbData = (BYTE *) &pPacketData->dwSequenceNumber;
    lReturn = MinCryptUpdateHashMemory(CALG_SHA1, hHash, 1, &blob);
    CBR(ERROR_SUCCESS == lReturn);

    lReturn = MinCryptGetHashParam(CALG_SHA1, hHash, bHash, &dwHashLen);
    CBR(ERROR_SUCCESS == lReturn);

#ifdef DEBUG
    NKDbgPrintfW(L"Hash = [");
    for (i = 0; i < dwHashLen; i++)
    {
        NKDbgPrintfW(L"%x ", bHash[i]);
    }
    NKDbgPrintfW(L"]\r\n\r\n");
#endif

    // This is an optimization. We could have many public keys and we don't know
    // which one this image was signed with. However once we find one that works
    // this will be the key that every packet is signed with so we don't have to
    // search again. After finding a key that works just verify each packet with
    // that key.

    if (!bFoundCorrectKey) 
    {
        for (i = pKeyData->wMinSearchIndex; i <= pKeyData->wMaxSearchIndex; i++) 
        {
            bVerified = (S_OK == Verify(pPacketData->pbSig, pPacketData->dwSigLength, pKeyData->rgpbPublicKeys[i], pKeyData->rgdwKeyLengths[i], bHash, dwHashLen));
            gpbPublicKey = pKeyData->rgpbPublicKeys[i];
            gdwPublicKeyLen = pKeyData->rgdwKeyLengths[i];
            
            if (bVerified) 
            {
                break;
            }
        }

        if (bVerified) 
        {
            bFoundCorrectKey = TRUE;
        }
    } 
    else 
    {
        bVerified = (S_OK == Verify(pPacketData->pbSig, pPacketData->dwSigLength, gpbPublicKey, gdwPublicKeyLen, bHash, dwHashLen));
    }

    CBR(bVerified);
    
Error:
    return hr;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -