03/26/2018 Authentication and Secure Data Transmission for Firmware Trustful Booting

This passage will introduce the details of implementing Remote Attestation in Pre-OS System and the necessary accessories or processes involved.

(1) Simple Introduction to Authentication Mechanism in the Design

As mentioned in the last part of the previous passage, the event log confidentiality is to be ensured. Simply using some symmetrical encryption algorithm cannot satisfy the requirement. The SSL/TLS(Secure Socket layer/Transmission Layer Security) Protocol to ensure the confidentiality of the transmission.

In SSL/TLS to verify the identification of the server and client before transmitting and receiving the data for remote attestation, the signature and verification process is necessary.

<Note> the different between certificate and digital signature

  • 什么是数字签名和证书?
    The digital signature is used to prove the identification the information provider; certificate includes public key and its digital signature, which is used to verify the trustfulness of the public key.
    However, the definition of Signature of Image is the SHA256 hash of PE/COFF image in UEFI Specification.
  • The idea is to dump the Event log && PCR Values into a recording file and signed the file and sign it with a private signature. Afterwards the recording file will be transmitted to the server and its trustfulness will be verified before and action is taken.

(2) Implementation of Remote Attestation

An important question here: we can make sure whether the IMA log is matching the PCR values from the quote report of TPM, but what if the PCR is extended with the events including malicious operation?

The standard attestation of the prover is a much more complicated way. Some materials worth referring to:

  1. Remote Attestation for Embedded System
  2. Things, Trouble, Trust: On Building Trust in IoT Systems
  3. Using the TPM: Machine Authentication and Attestation
  4. Security Analysis of Remote Attestation

And to simplify the situation (since in real cases, the embedded PLC devices are off Internet and only connected to the authentication server in the LAN), we just use SSL/TLS Protocol to encrypt the connection and verify the data on the server, to prevent malicious attacks including spying

Using the HpNetworkPkg for testing purpose.

sudo apt-get install git-svn
export PATH=$PATH:/usr/lib/git-core
git-svn http://svn.code.sf.net/p/libcurledk2/code/trunk/
# Some more details please see the slides attached
The Usage of BaseLib/PrintLib

The lib provides many fundamental functions supporting string manipulation.

Transmission Encryption using CryptoPkg
  • Add the CryptoRuntimeDriver into the list of DXE Drivers (Or simple use load CryptoRuntimeDriver.efi in UEFI Shell)
  • Locate and Open the EFI_RUNTIME_CRYPT_PROTOCOL
///
/// Runtime Cryptographic Protocol Structure.
///
typedef struct {
  EFI_RUNTIME_CRYPT_SHA256_GET_CONTEXT_SIZE  Sha256GetContextSize;
  EFI_RUNTIME_CRYPT_SHA256_INIT              Sha256Init;
  EFI_RUNTIME_CRYPT_SHA256_UPDATE            Sha256Update;
  EFI_RUNTIME_CRYPT_SHA256_FINAL             Sha256Final;
  EFI_RUNTIME_CRYPT_RSA_NEW                  RsaNew;
  EFI_RUNTIME_CRYPT_RSA_FREE                 RsaFree;
  EFI_RUNTIME_CRYPT_RSA_SET_KEY              RsaSetKey;
  EFI_RUNTIME_CRYPT_RSA_PKCS1_VERIFY         RsaPkcs1Verify;
} EFI_RUNTIME_CRYPT_PROTOCOL;
  • A simple sample of using Crypto Protocol to encrypting the character:
  Status = gBS->LocateProtocol(
                  &gEfiRuntimeCryptProtocolGuid, 
                  NULL, 
                  (VOID **) &mCryptProtocol);

  ZeroMem (Digest, MAX_DIGEST_SIZE);
  CtxSize = mCryptProtocol->Sha256GetContextSize ();
  HashCtx = AllocatePool (CtxSize);

  Status  = mCryptProtocol->Sha256Update (HashCtx, HashData, DataSize);

  Status  = mCryptProtocol->Sha256Final (HashCtx, Digest);

  for (Index=0;Index<SHA256_DIGEST_SIZE;Index++) {
          Print (L"%2X  ",Digest[Index]);
  }
  FreePool (HashCtx);

For some details please see Crypto 实现的 SHA256

Configuration of FTP Server Side

Setting up on the Ubuntu Server

sudo apt-get install vsftpd
sudo vi /etc/vsftpd.conf
sudo /etc/init.d/vsftpd restart

For testing purpose, username and password authentication are skipped and use anonymous signing-in:

# 请参考以下配置,不要看百度上的半吊子教程
# http://wiki.ubuntu.com.cn/Vsftpd

# Another passage worth referring
# vsftp:425 failed to establish connection解决办法
# http://blog.sina.com.cn/s/blog_4da051a60101c8ny.html

anonymous_enable=YES
anon_root=/home/server/ftp
no_anon_password=YES
write_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES

With the setting shown above, the client will be able to connect to the server with FTP protocol.

# use iptables or ufw to setup the firewall rules 
sudo ufw disable
ftp 10.192.13.88
...
ftp> get file

We can also use pyftpdlib in python to build up a FTP Server:

from pyftpdlib.authorizers import DummyAuthorizer
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer

#实例化虚拟用户,这是FTP验证首要条件
authorizer = DummyAuthorizer()

#添加用户权限和路径,括号内的参数是(用户名, 密码, 用户目录, 权限)
authorizer.add_user('user', '12345', '/home/', perm='elradfmw')

#添加匿名用户 只需要路径
authorizer.add_anonymous('/home/huangxm')

#初始化ftp句柄
handler = FTPHandler
handler.authorizer = authorizer

#监听ip 和 端口,因为linux里非root用户无法使用21端口,所以我使用了2121端口
server = FTPServer(('192.168.0.108', 2121), handler)

#开始服务
server.serve_forever()

For details please refer to python实现FTP服务器

Configuration of FTP Protocol in UEFI Client Side

Here is a brief description of my design. The authentication process is a improved version of HTTPS SSL/TLS Protocol

Design flow of the PLC Secure Booting

After the verification stage, the PCR value and Event log will be dumped into a reporting file and signed with the session key. And then it will be passed to the server and its integrity will be verified.

The description of EFI_FTP4_SERVICE_BINGDING_PROTOCOL in UEFI Specification 2.7 Page 1699

Summary of FTP4 Service Binding Protocol

The description of EFI_FTP4_CONNECTION_TOKEN in UEFI Specification 2.7 Page 1703. We are to initialise the Status and EFI Event after creating the FTP4 driver child protocol on specific supported device.

Definition of EFI FTP4 Config Data

So we will construct a simple FtpClient Struct to configure and set up the FTP connection. The definition is followed:

struct FtpClient{
        EFI_HANDLE                     m_FtpHandle;
        EFI_FTP4_PROTOCOL*             m_pFtp4Protocol;
        EFI_FTP4_CONFIG_DATA*          m_pFtp4ConfigData;
        EFI_FTP4_CONNECTION_TOKEN      ConnectToken;
        EFI_FTP4_COMMAND_TOKEN         CommandToken;
};

Also be aware of the definition in UEFI

  ///
  /// 1-byte unsigned value.
  ///
  typedef unsigned char       UINT8;
  ///
  /// 1-byte Character.
  ///
  typedef char                CHAR8;

The m_FtpHandle is the handle on which the child Ftp4 protocol driver will be bind on. But the fundamental driver seems not to have installed relevant protocols on any handle:

Error when Loading FTP Binding Protocol

Instead of modifying the DXE driver and install the FTP supported dependencies, the MTFTP(Multiple Trivial File Transmission Protocol) protocol is used as a substitution.

Configuration of TFTP Server and Client

References for implementing TFTP server with tftpd

A simpler way to use Python Lib tftpy
Example Python TFTP Server: http://tftpy.sourceforge.net/sphinx/

import tftpy
server = tftpy.TftpServer('/tftpboot')
server.listen('0.0.0.0', 69)

The TFTP server can be rebooted with sudo /etc/init.d/xinetd. Similarly, a simple struct is defined to call the EFI_MTFTP4_PROTOCOL

struct MtftpClient{
    EFI_HANDLE                       m_MtftpHandle;                   
    EFI_MTFTP4_PROTOCOL*             m_pMtftp4Protocol;
    EFI_MTFTP4_CONFIG_DATA*          m_pMtftp4ConfigData;
    EFI_MTFTP4_TOKEN                 WriteToken, ReadToken;
};

Configuration setting

    EFI_STATUS Status = EFI_NOT_FOUND;
    struct MtftpClient* this = MtftpClientfd[sk]; 
    if(this->m_pMtftp4ConfigData == NULL)   return Status;

    // StationIp & SubnetMask & GatewayIp need to be set if FALSE
    this->m_pMtftp4ConfigData->UseDefaultSetting = FALSE;
    *(UINT32*)(this->m_pMtftp4ConfigData->StationIp.Addr)  = (10  | 192 << 8 | 13 << 16  | 89 << 24);
    *(UINT32*)(this->m_pMtftp4ConfigData->SubnetMask.Addr) = (255 | 255 << 8 | 255 << 16 | 128 << 24);
    *(UINT32*)(this->m_pMtftp4ConfigData->GatewayIp.Addr)  = (10  | 192 << 8 | 13 << 16  | 1 << 24);

    this->m_pMtftp4ConfigData->LocalPort = (UINT16)0;

    *(UINT32*)(this->m_pMtftp4ConfigData->ServerIp.Addr) = Ip32;
    this->m_pMtftp4ConfigData->InitialServerPort = (UINT16)69;

    this->m_pMtftp4ConfigData->TryCount = (UINT16)5;
    this->m_pMtftp4ConfigData->TimeoutValue = (UINT16)10;

The protocol runs successfully in configuration, but failed in WriteFile() function. Status Error: 23 (EFI_TFTP_ERROR), which means that the client received a Error packet.

Note: The concept of Callback function.
深入浅出剖析C语言函数指针与回调函数(一)
Please make sure that the implementation of the callback function should be in form of "EFI_STATUS EFIAPI Function(....)"

The Example of Callback function to parse the return packet is like:

// The Process will be aborted with any other status but EFI_SUCCESS
// The 

EFI_STATUS
EFIAPI
CheckCallback(IN EFI_MTFTP4_PROTOCOL *This,
                         IN EFI_MTFTP4_TOKEN *Token,
                         IN UINT16 PacketLen,
                         IN EFI_MTFTP4_PACKET *Packet)
{
    EFI_STATUS Status = EFI_SUCCESS;
    Print(L"Parse the received Packet\n");
    Print(L"\nOperation Code: %d\n", Packet->OpCode);
    AsciiPrint("Msg: %s\n", Packet->Wrq.Filename[0]);
    Print(L"\nError Code: %d\n", Packet->Error.ErrorCode);
    AsciiPrint("Msg: %s\n", Packet->Error.ErrorMessage[0]);
    return Status;
}

Also assure that the address is passed to the token defined in WriteToken || ReadToken

struct MtftpClient* this = MtftpClientfd[sk];
this->WriteToken.CheckPacket = &CheckCallback;
this->WriteToken.TimeoutCallback = &myTimeoutCallback;

The parsing results of the RecvPacket is like (Error Packet d in this case)

MTFTP Initiliazation Success
To Cinfig the Data...6
Config Sucess Code: 0

Writing Data Now: 0
Parse the received Packet
Error Code: 512
Msg: 
Wait Status: 0

The Parsing function is defined like:

FTP The Request Data: POST / HTTP/1.1
Host:10.192.13.89
Accept:* / * 
Connection:Keep-Alive

InstallProtocolInterface: 41D94CD2-35B6-455A-8258-D4E51334AADD 7EC326A0
InstallProtocolInterface: 3AD9DF29-4501-478D-B1F8-7F7FE70E50F3 7EC31AB8
InstallProtocolInterface: 78247C57-63DB-4708-99C2-A8B4A9A61F6B 7EC32530

MTFTP Initiliazation Success
To Cinfig the Data...10
Config Sucess Code: 0
InstallProtocolInterface: F4B427BB-BA21-4F16-BC4E-43E416AB619C 7EC2FEB0

Writing Data Now: 0
Wait Status: 0
Writing Data Success: 0

InstallProtocolInterface: F4B427BB-BA21-4F16-BC4E-43E416AB619C 7EC29230

Reading Data Now: 0
Wait Status: 0
FTP Read Data Success: 0
Close Status Success

The TFTP Mode String is set as "octet" if left NULL. We set the default TFTP package size to be 512kb and launch the download process. The progress bar is implemented with CheckPacket, which is a function that will be triggered every time when a packet is received.

The downloading process of TFTP

(2) Principles of and SSL/TLS Protocol and Improvements

Generally, the remote attestation process is completed with the help of

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,236评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,867评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,715评论 0 340
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,899评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,895评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,733评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,085评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,722评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,025评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,696评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,816评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,447评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,057评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,009评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,254评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,204评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,561评论 2 343

推荐阅读更多精彩内容