美文网首页
03/26/2018 Authentication and Se

03/26/2018 Authentication and Se

作者: Ramperouge | 来源:发表于2018-03-28 14:24 被阅读0次

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

相关文章

网友评论

      本文标题:03/26/2018 Authentication and Se

      本文链接:https://www.haomeiwen.com/subject/davlcftx.html