зеркало из https://github.com/microsoft/RIoT.git
Add reference implementation
This commit is contained in:
Родитель
857d386b73
Коммит
ee09fe471b
|
@ -28,169 +28,11 @@ extern "C" {
|
|||
#define RIOT_LABEL_MK "Migration"
|
||||
#define RIOT_LABEL_AK "Attestation"
|
||||
|
||||
//
|
||||
// Macro for label sizes (skip strlen()).
|
||||
//
|
||||
//
|
||||
// Macro for label sizes (skip strlen()).
|
||||
//
|
||||
#define lblSize(a) (sizeof(a) - 1)
|
||||
|
||||
//
|
||||
// Descriptors for RIoT images and entry points. In reality, the way these are
|
||||
// specified is purely implementation-specific. But, since every implementation
|
||||
// will need some way to identify components in the RIoT framework, these are
|
||||
// defined here and not in RiotPlatform. For this user-mode reference device,
|
||||
// these are strings/filenames.
|
||||
//
|
||||
#define RIOT_CORE_IMAGE L"RiotCore.dll"
|
||||
#define RIOT_CORE_ENTRY "RiotStart"
|
||||
#define RIOT_CORE_INDEX 0x00UL
|
||||
|
||||
#define RIOT_LOADER_IMAGE L"Loader.dll"
|
||||
#define RIOT_LOADER_ENTRY "RiotModuleMain"
|
||||
#define RIOT_LOADER_INDEX 0x01UL
|
||||
|
||||
#define RIOT_TEE_IMAGE L"Tee.dll"
|
||||
#define RIOT_TEE_ENTRY "RiotModuleMain"
|
||||
#define RIOT_TEE_INDEX 0x02UL
|
||||
|
||||
typedef enum RIOT_ACTIVE_KEY_CHAIN {
|
||||
RIOT_CHAIN_SK = 1,
|
||||
RIOT_CHAIN_AK = 2,
|
||||
RIOT_CHAIN_MK = 4
|
||||
} RIOT_ACTIVE_KEY_CHAIN;
|
||||
|
||||
//*** RIOT_DYNAMIC_DATA
|
||||
// Data structure containing data that are generated and modified during each Boot
|
||||
// Sequence. These data represent secrets of the RIoT controlled modules, and shall
|
||||
// be kept in protected facilities at all times (e.g. hardware registers or RAM with
|
||||
// no DMA access).
|
||||
typedef struct {
|
||||
// Current module index. This index is used by the RIoT framework to locate
|
||||
// metadata (such as SMD, SKEB) associated with the given mutable Software
|
||||
// Module. Note that indices of mutable Software Modules are 1-based
|
||||
// (following the notation used by the RIoT spec). Index 0 is reserved for the
|
||||
// Invariant Code.
|
||||
//
|
||||
// REVISIT: Make it zero-based?
|
||||
uint16_t moduleIndex;
|
||||
|
||||
// A combination of RIOT_ACTIVE_KEY_CHAIN flags that specifies, which key
|
||||
// derivation chains are are active during this Boot Sequence.
|
||||
uint16_t activeKeyChains;
|
||||
|
||||
// Current module's Sealing Key
|
||||
uint8_t SK[RIOT_KEY_LENGTH];
|
||||
|
||||
// Current module's Migration Key
|
||||
uint8_t MK[RIOT_KEY_LENGTH];
|
||||
|
||||
// Current module's Attestation Key
|
||||
uint8_t AK[RIOT_KEY_LENGTH];
|
||||
} RIOT_DYNAMIC_DATA;
|
||||
|
||||
typedef enum RIOT_BOOT_MODE {
|
||||
RIOT_BOOT_UNKNOWN = 0x0UL, // Boot mode is unknown.
|
||||
RIOT_BOOT_INITIAL, // Initial Boot Sequence
|
||||
RIOT_BOOT_SECURE, // Regular Boot Sequence
|
||||
RIOT_BOOT_UPDATE, // Update Boot Sequence
|
||||
RIOT_BOOT_REMEDIATION, // Remediation Boot Sequence
|
||||
RIOT_BOOT_LAST_MODE = RIOT_BOOT_REMEDIATION
|
||||
} RIOT_BOOT_MODE;
|
||||
|
||||
//*** RIOT_FAILURE_INFO
|
||||
// Implementation specific data strucure containing information necessary for
|
||||
// Remediation Boot Sequence.
|
||||
typedef struct {
|
||||
// Index of the module that has failed its policy check during the previous
|
||||
// Boot Sequence.
|
||||
uint8_t failedModule;
|
||||
} RIOT_FAILURE_INFO;
|
||||
|
||||
//*** RIOT_BSD
|
||||
// Boot Sequence Descriptor (BSD) data structure. It is used by the RIoT framework
|
||||
// to determine the type of Boot Sequence to execute upon Power-on, and to store
|
||||
// data necessary for the current and/or next Boot Sequence completion.
|
||||
typedef struct {
|
||||
RIOT_BOOT_MODE bootMode;
|
||||
RIOT_FAILURE_INFO failureInfo;
|
||||
} RIOT_BSD;
|
||||
|
||||
//*** RIOT_UPDATE_APPROVAL
|
||||
// A ticket issued by the current version of a Software Module that gives permission
|
||||
// to update it to another version, and instructs which checks should be done by the
|
||||
// RIoT framework during update.
|
||||
typedef struct {
|
||||
// Approval type
|
||||
uint8_t approval[RIOT_DIGEST_LENGTH];
|
||||
|
||||
// HMAC over the approval field
|
||||
uint8_t signature[RIOT_HMAC_LENGTH];
|
||||
} RIOT_UPDATE_APPROVAL;
|
||||
|
||||
// Number of Software Modules controlled by the RIoT framework. This is a count
|
||||
// of the Software Modules in this implementation of the RIoT framewrok that
|
||||
// include a Software Module Descriptor, i.e., the number of Software Modules
|
||||
// that can be updated in RIoT. So, even though RIoT Core qualifies as RIoT-
|
||||
// controlled image, it is single-layer and does not contain an SMD. Therefore,
|
||||
// is not included in this count.
|
||||
#define RIOT_NUM_MODULES 2
|
||||
|
||||
// TODO: FIX THIS COMMENT
|
||||
typedef struct {
|
||||
// Public part of the AIK.
|
||||
RIOT_ECC_PUBLIC aikPublic;
|
||||
|
||||
// Public part of the Ateestation Authority that issued the AIK
|
||||
RIOT_ECC_PUBLIC aaPublic;
|
||||
|
||||
// Signature made with aaPublic over aikPublic
|
||||
RIOT_ECC_SIGNATURE signature;
|
||||
} RIOT_MIN_CERT;
|
||||
|
||||
//*** RIOT_AIK
|
||||
// Data structure containing an AIK (Attestation Identity Key) used by RIoT
|
||||
// Software Modules.
|
||||
typedef struct {
|
||||
// Public part of the AIK.
|
||||
RIOT_ECC_PUBLIC aikPublic;
|
||||
|
||||
// Private part of the AIK. During AIK import this field is encrypted to
|
||||
// the Attestation Secret. After successful import it is re-encrypted to
|
||||
// the Sealing Key of the interactive Software Module.
|
||||
RIOT_ECC_PRIVATE aikPrivate;
|
||||
|
||||
// Size of the cert data in aikCert in bytes
|
||||
uint16_t aikCertLength;
|
||||
|
||||
// AIK certificate
|
||||
uint8_t aikCert[RIOT_MAX_CERT_LENGTH];
|
||||
} RIOT_AIK;
|
||||
|
||||
//*** RIOT_PERSISTENT_DATA
|
||||
// Data structure containing data that are preserved across reboots.
|
||||
typedef struct {
|
||||
// Boot Sequence Descriptor
|
||||
RIOT_BSD BSD;
|
||||
|
||||
// Public part of an ECC key uniquely identifying the given Device.
|
||||
RIOT_ECC_PUBLIC DeviceIDPublic;
|
||||
|
||||
// Encrypted private part of an ECC key uniquely identifying the given Device.
|
||||
RIOT_ECC_PRIVATE DeviceIDPrivate;
|
||||
|
||||
// HMAC over DeviceID key pair
|
||||
uint8_t signature[RIOT_HMAC_LENGTH];
|
||||
|
||||
// Device signatures for the Software Modules
|
||||
uint8_t DeviceSignature[RIOT_NUM_MODULES][RIOT_HMAC_LENGTH];
|
||||
|
||||
// Update approval tickets
|
||||
RIOT_UPDATE_APPROVAL updateTicket[RIOT_NUM_MODULES];
|
||||
|
||||
// Current AIK with its private part encrypted to the Sealing Key of the
|
||||
// Interactive Module.
|
||||
RIOT_AIK AIK;
|
||||
} RIOT_PERSISTENT_DATA;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2015, 2016
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
/*
|
||||
* FILE: sha2.c
|
||||
* AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/
|
||||
*
|
||||
* Copyright (c) 2000-2001, Aaron D. Gifford
|
||||
* All rights reserved.
|
||||
*
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DRW).
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT)
|
||||
//
|
||||
#include "RiotTarget.h"
|
||||
#include "RiotStatus.h"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2015, 2016
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DRW).
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT).
|
||||
//
|
||||
#include "RiotTarget.h"
|
||||
#include "RiotStatus.h"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DRW).
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT).
|
||||
//
|
||||
#include "RiotTarget.h"
|
||||
#include "RiotStatus.h"
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
*/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DRW).
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT).
|
||||
//
|
||||
#ifndef __RIOT_CRYPTO_SHA256_H__
|
||||
#define __RIOT_CRYPTO_SHA256_H__
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DRW).
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT).
|
||||
//
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DICE", "DICE\DICE.vcxproj", "{0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RIoT", "RIoT\Core\RIoT.vcxproj", "{B7AF6C41-115E-4926-A8B3-7842FFE9D605}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07} = {0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FW", "FW\Loader.vcxproj", "{FD767D67-E637-4AD0-A99A-6C35CE32E4A4}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{B7AF6C41-115E-4926-A8B3-7842FFE9D605} = {B7AF6C41-115E-4926-A8B3-7842FFE9D605}
|
||||
{0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07} = {0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07}.Debug|x64.Build.0 = Debug|Win32
|
||||
{0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07}.Debug|x86.Build.0 = Debug|Win32
|
||||
{0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07}.Release|x64.ActiveCfg = Release|Win32
|
||||
{0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07}.Release|x64.Build.0 = Release|Win32
|
||||
{0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07}.Release|x86.ActiveCfg = Release|Win32
|
||||
{0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07}.Release|x86.Build.0 = Release|Win32
|
||||
{B7AF6C41-115E-4926-A8B3-7842FFE9D605}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{B7AF6C41-115E-4926-A8B3-7842FFE9D605}.Debug|x64.Build.0 = Debug|Win32
|
||||
{B7AF6C41-115E-4926-A8B3-7842FFE9D605}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B7AF6C41-115E-4926-A8B3-7842FFE9D605}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B7AF6C41-115E-4926-A8B3-7842FFE9D605}.Release|x64.ActiveCfg = Release|Win32
|
||||
{B7AF6C41-115E-4926-A8B3-7842FFE9D605}.Release|x64.Build.0 = Release|Win32
|
||||
{B7AF6C41-115E-4926-A8B3-7842FFE9D605}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B7AF6C41-115E-4926-A8B3-7842FFE9D605}.Release|x86.Build.0 = Release|Win32
|
||||
{FD767D67-E637-4AD0-A99A-6C35CE32E4A4}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{FD767D67-E637-4AD0-A99A-6C35CE32E4A4}.Debug|x64.Build.0 = Debug|Win32
|
||||
{FD767D67-E637-4AD0-A99A-6C35CE32E4A4}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{FD767D67-E637-4AD0-A99A-6C35CE32E4A4}.Debug|x86.Build.0 = Debug|Win32
|
||||
{FD767D67-E637-4AD0-A99A-6C35CE32E4A4}.Release|x64.ActiveCfg = Release|Win32
|
||||
{FD767D67-E637-4AD0-A99A-6C35CE32E4A4}.Release|x64.Build.0 = Release|Win32
|
||||
{FD767D67-E637-4AD0-A99A-6C35CE32E4A4}.Release|x86.ActiveCfg = Release|Win32
|
||||
{FD767D67-E637-4AD0-A99A-6C35CE32E4A4}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,157 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{0E4A2BB0-FBC0-4F2D-80A7-A10359BF6B07}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>DICE</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="DiceSha256.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="DiceCore.cpp" />
|
||||
<ClCompile Include="DiceSha256.c" />
|
||||
<ClCompile Include="stdafx.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,42 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Ignore">
|
||||
<UniqueIdentifier>{92acde2d-b9a9-4383-b930-b710808212dd}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Ignore\Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DiceSha256.h">
|
||||
<Filter>Ignore</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="DiceCore.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DiceSha256.c">
|
||||
<Filter>Ignore</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Ignore</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,210 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
|
||||
// DICE definitions
|
||||
#define DICE_UDS_LENGTH 0x20
|
||||
#define DICE_DIGEST_LENGTH 0x20
|
||||
|
||||
// On real hardware, the UDS MUST be kept in some form of protected storage.
|
||||
const BYTE UDS[DICE_UDS_LENGTH] = {
|
||||
0xb5, 0x85, 0x94, 0x93, 0x66, 0x1e, 0x2e, 0xae,
|
||||
0x96, 0x77, 0xc5, 0x5d, 0x59, 0x0b, 0x92, 0x94,
|
||||
0xe0, 0x94, 0xab, 0xaf, 0xd7, 0x40, 0x78, 0x7e,
|
||||
0x05, 0x0d, 0xfe, 0x6d, 0x85, 0x90, 0x53, 0xa0 };
|
||||
|
||||
// Storage for Compound Device Identifier
|
||||
BYTE CDI[DICE_DIGEST_LENGTH] = { 0x00 };
|
||||
|
||||
// Simulation-only definitions
|
||||
#define DEFAULT_RIOT_PATH L"riot.dll" // Contains RIoT Invariant Code
|
||||
#define DEFAULT_LOADER_PATH L"FW.dll" // Our simulated FW
|
||||
#define RIOT_ENTRY "RiotStart" // RIoT Core entry point
|
||||
typedef void(__cdecl* fpRiotStart)(const BYTE *, const uint32_t, const TCHAR *);
|
||||
|
||||
// Simulation only: This function finds the in-memory base-offset and size
|
||||
// of RIoT .text section. On real hardware DICE would have knowledge of
|
||||
// the physical location and size of RIoT Invariant Code.
|
||||
BOOLEAN DiceGetRiotInfo(HINSTANCE riotDLL, DWORD *riotCore, DWORD *riotSize);
|
||||
|
||||
int _tmain(int argc, TCHAR* argv[])
|
||||
//
|
||||
// This is the main entrypoint for this reference simulation. It does some
|
||||
// initial setup and falls through to Boot. The code after the Boot label
|
||||
// simulates device power-on-reset. Everything between start of _tmain and
|
||||
// the Boot label can be safely ignored, as it is uninteresting.
|
||||
//
|
||||
{
|
||||
uint8_t uDigest[DICE_DIGEST_LENGTH] = { 0 };
|
||||
uint8_t rDigest[DICE_DIGEST_LENGTH] = { 0 };
|
||||
TCHAR *riotImagePath, *loaderImagePath;
|
||||
uint8_t *riotCore;
|
||||
DWORD riotSize, offset;
|
||||
HINSTANCE hRiotDLL;
|
||||
|
||||
// Assume default paths
|
||||
riotImagePath = DEFAULT_RIOT_PATH;
|
||||
loaderImagePath = DEFAULT_LOADER_PATH;
|
||||
|
||||
// Check for path to riot image
|
||||
if (argc > 1)
|
||||
{
|
||||
if (wcslen(argv[1]) > MAX_PATH)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Bad RIoT path.\n");
|
||||
goto Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
riotImagePath = argv[1];
|
||||
}
|
||||
// Check for path to loader image
|
||||
if (argc > 2)
|
||||
{
|
||||
if (wcslen(argv[2]) > MAX_PATH)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Bad Loader path.\n");
|
||||
goto Error;
|
||||
}
|
||||
else
|
||||
{
|
||||
loaderImagePath = argv[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Boot:
|
||||
// ++
|
||||
// DICE is responsible for the following actions:
|
||||
// 1. Measure RIoT Core
|
||||
// 2. Generate CDI based on UDS and RIoT Core measurement
|
||||
// 3. Close access to UDS and pass CDI in transition to RIoT
|
||||
//
|
||||
// To accomplish this, we first need to take some steps to setup our
|
||||
// simulated device. This doesn't happen on real hardware.
|
||||
// --
|
||||
|
||||
// Power-on "device"
|
||||
printf("DICE: Begin\n");
|
||||
|
||||
//DiceInit:
|
||||
|
||||
// Load DLL containing RIoT Core.
|
||||
hRiotDLL = LoadLibrary(riotImagePath);
|
||||
if (hRiotDLL == NULL) {
|
||||
fprintf(stderr, "ERROR: Failed to load RIoT Framework\n");
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// Locate RiotStart
|
||||
fpRiotStart RiotStart = (fpRiotStart)GetProcAddress(hRiotDLL, RIOT_ENTRY);
|
||||
if (!RiotStart) {
|
||||
fprintf(stderr, "ERROR: Failed to locate RiotStart\n");
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// Get base offset and size of RIoT Invariant Code
|
||||
if (!DiceGetRiotInfo(hRiotDLL, &offset, &riotSize)) {
|
||||
fprintf(stderr, "ERROR: Failed to locate RIoT Invariant code\n");
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// Calculate base VA of RIoT Invariant Code
|
||||
riotCore = (uint8_t *)((uint64_t)hRiotDLL + offset);
|
||||
|
||||
// UDS
|
||||
printf("DICE: UDS Bytes:\n\t");
|
||||
for (int i = 0; i < DICE_UDS_LENGTH; i++) {
|
||||
printf("%02X", UDS[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// RIoTStart address
|
||||
printf("DICE: RiotStart: %p\n", RiotStart);
|
||||
|
||||
// DiceCore:
|
||||
|
||||
// The hashing functions below are only used for this simulated devivce
|
||||
// and in those instances where an MCU doesn't include one in HW.
|
||||
|
||||
// Measure RIoT Invariant Code
|
||||
printf("DICE: Measure RIoT Invariant Code:\n\t");
|
||||
DiceSHA256(riotCore, riotSize, rDigest);
|
||||
for (int i = 0; i < DICE_UDS_LENGTH; i++) {
|
||||
printf("%02X", rDigest[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Don't use UDS directly
|
||||
DiceSHA256(UDS, DICE_UDS_LENGTH, uDigest);
|
||||
|
||||
// Derive CDI value
|
||||
printf("DICE: Derive CDI\n\t");
|
||||
DiceSHA256_2(uDigest, DICE_DIGEST_LENGTH, rDigest, DICE_DIGEST_LENGTH, CDI);
|
||||
for (int i = 0; i < DICE_UDS_LENGTH; i++) {
|
||||
printf("%02X", CDI[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Clean up potentially sensative data
|
||||
memset(uDigest, 0x00, DICE_DIGEST_LENGTH);
|
||||
memset(rDigest, 0x00, DICE_DIGEST_LENGTH);
|
||||
|
||||
// Handoff to RIoT. Note that we pass loaderImagePath here only so
|
||||
// when our "device" is powered on, we can take as an argument
|
||||
// different "FW" images. On a real device DICE would not tell
|
||||
// RIoT Core what code to invoke next. This would be a fixed
|
||||
// address in flash and (probably) unknown to DICE.
|
||||
printf("DICE: Transition to RIoTStart\n");
|
||||
RiotStart(CDI, DICE_DIGEST_LENGTH, loaderImagePath);
|
||||
|
||||
// We treat a return as a power-cycle for our simulated device.
|
||||
// Tear down our RIoT image and "reboot".
|
||||
if (!FreeLibrary(hRiotDLL))
|
||||
{
|
||||
fprintf(stderr, "ERROR: Failed to unload RIoT Framework\n");
|
||||
goto Error;
|
||||
}
|
||||
|
||||
// Pause briefly
|
||||
Sleep(500);
|
||||
goto Boot;
|
||||
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
DiceGetRiotInfo(
|
||||
HINSTANCE riotDLL,
|
||||
DWORD *riotCore,
|
||||
DWORD *riotSize
|
||||
)
|
||||
// This is a quick and dirty function to find the .text (CODE) section of
|
||||
// the RIoT image. We don't do anything like this on real hardware because,
|
||||
// on real hardware, DICE has the base address and size of RIoT Invariant
|
||||
// Code as constant values resolved at link time (at the latest).
|
||||
{
|
||||
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)riotDLL;
|
||||
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((PCHAR)dosHeader + (ULONG)(dosHeader->e_lfanew));
|
||||
PIMAGE_OPTIONAL_HEADER optionalHeader = &(ntHeader->OptionalHeader);
|
||||
PIMAGE_SECTION_HEADER sectionHeader = (PIMAGE_SECTION_HEADER)(optionalHeader + 1);
|
||||
PIMAGE_FILE_HEADER fileHeader = &(ntHeader->FileHeader);
|
||||
ULONG nSections = fileHeader->NumberOfSections, i;
|
||||
|
||||
for (i = 0; i < nSections; i++)
|
||||
{
|
||||
if (!strcmp((char *)sectionHeader->Name, ".text"))
|
||||
{
|
||||
*riotCore = sectionHeader->VirtualAddress;
|
||||
*riotSize = sectionHeader->Misc.VirtualSize;
|
||||
return TRUE;
|
||||
}
|
||||
sectionHeader++;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
|
@ -0,0 +1,470 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2001, Aaron D. Gifford
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2014, AllSeen Alliance. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; DICE adaptation (DennisMa;MSFT).
|
||||
//
|
||||
#include "stdint.h"
|
||||
#include "string.h" // memcpy/memset
|
||||
#include "DiceSha256.h"
|
||||
|
||||
/*** SHA-256 Machine Architecture Definitions *****************/
|
||||
/*
|
||||
* BYTE_ORDER NOTE:
|
||||
*
|
||||
* Please make sure that your system defines BYTE_ORDER. If your
|
||||
* architecture is little-endian, make sure it also defines
|
||||
* LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
|
||||
* equivilent.
|
||||
*
|
||||
* If your system does not define the above, then you can do so by
|
||||
* hand like this:
|
||||
*
|
||||
* #define LITTLE_ENDIAN 1234
|
||||
* #define BIG_ENDIAN 4321
|
||||
*
|
||||
* And for little-endian machines, add:
|
||||
*
|
||||
* #define BYTE_ORDER LITTLE_ENDIAN
|
||||
*
|
||||
* Or for big-endian machines:
|
||||
*
|
||||
* #define BYTE_ORDER BIG_ENDIAN
|
||||
*
|
||||
* The FreeBSD machine this was written on defines BYTE_ORDER
|
||||
* appropriately by including <sys/types.h> (which in turn includes
|
||||
* <machine/endian.h> where the appropriate definitions are actually
|
||||
* made).
|
||||
*/
|
||||
#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#define BIG_ENDIAN 4321
|
||||
#if HOST_IS_LITTLE_ENDIAN
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#else
|
||||
#define BYTE_ORDER BIG_ENDIAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define the followingsha2_* types to types of the correct length on
|
||||
* the native architecture. Most BSD systems and Linux define u_intXX_t
|
||||
* types. Machines with very recent ANSI C headers, can use the
|
||||
* uintXX_t definitions from inttypes.h by defining SHA2_USE_INTTYPES_H
|
||||
* during compile or in the sha.h header file.
|
||||
*
|
||||
* Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
|
||||
* will need to define these three typedefs below (and the appropriate
|
||||
* ones in sha.h too) by hand according to their system architecture.
|
||||
*
|
||||
* Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
|
||||
* types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
|
||||
*/
|
||||
|
||||
/*** SHA-256 Length Definitions ***********************/
|
||||
/* NOTE: Most of these are in sha2.h */
|
||||
#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
|
||||
|
||||
/*** ENDIAN REVERSAL MACROS *******************************************/
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if !defined(ALIGNED_ACCESS_REQUIRED)
|
||||
#define REVERSE32(w,x) { \
|
||||
sha2_word32 tmp = (w); \
|
||||
tmp = (tmp >> 16) | (tmp << 16); \
|
||||
(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
|
||||
}
|
||||
#else
|
||||
#define REVERSE32(w,x) { \
|
||||
sha2_uint8_t *b = (sha2_uint8_t*) &w; \
|
||||
sha2_word32 tmp = 0; \
|
||||
tmp = ((sha2_word32)*b++); \
|
||||
tmp = (tmp << 8) | ((sha2_word32)*b++); \
|
||||
tmp = (tmp << 8) | ((sha2_word32)*b++); \
|
||||
tmp = (tmp << 8) | ((sha2_word32)*b++); \
|
||||
(x) = tmp; \
|
||||
}
|
||||
#endif /* ALIGNED_ACCESS_REQUIRED */
|
||||
#define REVERSE64(w,x) { \
|
||||
sha2_word64 tmp = (w); \
|
||||
tmp = (tmp >> 32) | (tmp << 32); \
|
||||
tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
|
||||
((tmp & 0x00ff00ff00ff00ffULL) << 8); \
|
||||
(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
|
||||
((tmp & 0x0000ffff0000ffffULL) << 16); \
|
||||
}
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
|
||||
/*
|
||||
* Macro for incrementally adding the unsigned 64-bit integer n to the
|
||||
* unsigned 128-bit integer (represented using a two-element array of
|
||||
* 64-bit words):
|
||||
*/
|
||||
#define ADDINC128(w,n) { \
|
||||
(w)[0] += (sha2_word64)(n); \
|
||||
if ((w)[0] < (n)) { \
|
||||
(w)[1]++; \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Macros for copying blocks of memory and for zeroing out ranges
|
||||
* of memory. Using these macros makes it easy to switch from
|
||||
* using memset()/memcpy() and using bzero()/bcopy().
|
||||
*
|
||||
* Please define either SHA2_USE_MEMSET_MEMCPY or define
|
||||
* SHA2_USE_BZERO_BCOPY depending on which function set you
|
||||
* choose to use:
|
||||
*/
|
||||
#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
|
||||
/* Default to memset()/memcpy() if no option is specified */
|
||||
#define SHA2_USE_MEMSET_MEMCPY 1
|
||||
#endif
|
||||
#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
|
||||
/* Abort with an error if BOTH options are defined */
|
||||
#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
|
||||
#endif
|
||||
|
||||
#ifdef SHA2_USE_MEMSET_MEMCPY
|
||||
#define MEMSET_BZERO(p,l) memset((p), 0, (l))
|
||||
#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l))
|
||||
#endif
|
||||
#ifdef SHA2_USE_BZERO_BCOPY
|
||||
#define MEMSET_BZERO(p,l) bzero((p), (l))
|
||||
#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l))
|
||||
#endif
|
||||
|
||||
|
||||
/*** THE SIX LOGICAL FUNCTIONS ****************************************/
|
||||
/*
|
||||
* Bit shifting and rotation (used by the six SHA-XYZ logical functions:
|
||||
*
|
||||
* NOTE: The naming of R and S appears backwards here (R is a SHIFT and
|
||||
* S is a ROTATION) because the SHA-256/384/512 description document
|
||||
* (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
|
||||
* same "backwards" definition.
|
||||
*/
|
||||
/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
|
||||
#define R(b,x) ((x) >> (b))
|
||||
/* 32-bit Rotate-right (used in SHA-256): */
|
||||
#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
|
||||
|
||||
/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
|
||||
#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
|
||||
#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
|
||||
/* Four of six logical functions used in SHA-256: */
|
||||
#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))
|
||||
#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))
|
||||
#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x)))
|
||||
#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x)))
|
||||
|
||||
/*** INTERNAL FUNCTION PROTOTYPES *************************************/
|
||||
/* NOTE: These should not be accessed directly from outside this
|
||||
* library -- they are intended for private internal visibility/use
|
||||
* only.
|
||||
*/
|
||||
static void SHA256_Transform(DICE_SHA256_CONTEXT *, const sha2_word32 *);
|
||||
|
||||
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
|
||||
/* Hash constant words K for SHA-256: */
|
||||
static const sha2_word32 K256[64] = {
|
||||
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
|
||||
0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
|
||||
0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
|
||||
0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
|
||||
0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
|
||||
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
|
||||
0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
|
||||
0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
|
||||
0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
|
||||
0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
|
||||
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
|
||||
0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
|
||||
0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
|
||||
0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
|
||||
0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
|
||||
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
|
||||
};
|
||||
|
||||
/* Initial hash value H for SHA-256: */
|
||||
static const sha2_word32 sha256_initial_hash_value[8] = {
|
||||
0x6a09e667UL,
|
||||
0xbb67ae85UL,
|
||||
0x3c6ef372UL,
|
||||
0xa54ff53aUL,
|
||||
0x510e527fUL,
|
||||
0x9b05688cUL,
|
||||
0x1f83d9abUL,
|
||||
0x5be0cd19UL
|
||||
};
|
||||
|
||||
/*
|
||||
* Constant used by SHA256() functions for converting the
|
||||
* digest to a readable hexadecimal character string:
|
||||
*/
|
||||
//static const char *sha2_hex_digits = "0123456789abcdef";
|
||||
|
||||
/*** SHA-256: *********************************************************/
|
||||
void DICE_SHA256_Init(DICE_SHA256_CONTEXT *context)
|
||||
{
|
||||
if (context == (DICE_SHA256_CONTEXT *)0) {
|
||||
return;
|
||||
}
|
||||
context->magic = HASH_MAGIC_VALUE;
|
||||
MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
|
||||
MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
|
||||
context->bitcount = 0;
|
||||
}
|
||||
|
||||
static void SHA256_Transform(DICE_SHA256_CONTEXT *context, const sha2_word32 *data)
|
||||
{
|
||||
sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
|
||||
sha2_word32 T1, T2, *W256;
|
||||
int j;
|
||||
|
||||
W256 = (sha2_word32 *)context->buffer;
|
||||
|
||||
/* Initialize registers with the prev. intermediate value */
|
||||
a = context->state[0];
|
||||
b = context->state[1];
|
||||
c = context->state[2];
|
||||
d = context->state[3];
|
||||
e = context->state[4];
|
||||
f = context->state[5];
|
||||
g = context->state[6];
|
||||
h = context->state[7];
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
/* Copy data while converting to host uint8_t order */
|
||||
REVERSE32(*data++,W256[j]);
|
||||
/* Apply the SHA-256 compression function to update a..h */
|
||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
|
||||
#else /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
/* Apply the SHA-256 compression function to update a..h with copy */
|
||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
T2 = Sigma0_256(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 16);
|
||||
|
||||
do {
|
||||
/* Part of the message block expansion: */
|
||||
s0 = W256[(j+1)&0x0f];
|
||||
s0 = sigma0_256(s0);
|
||||
s1 = W256[(j+14)&0x0f];
|
||||
s1 = sigma1_256(s1);
|
||||
|
||||
/* Apply the SHA-256 compression function to update a..h */
|
||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
|
||||
(W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
|
||||
T2 = Sigma0_256(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 64);
|
||||
|
||||
/* Compute the current intermediate hash value */
|
||||
context->state[0] += a;
|
||||
context->state[1] += b;
|
||||
context->state[2] += c;
|
||||
context->state[3] += d;
|
||||
context->state[4] += e;
|
||||
context->state[5] += f;
|
||||
context->state[6] += g;
|
||||
context->state[7] += h;
|
||||
|
||||
/* Clean up */
|
||||
a = b = c = d = e = f = g = h = T1 = T2 = 0;
|
||||
}
|
||||
|
||||
void DICE_SHA256_Update(DICE_SHA256_CONTEXT *context, const sha2_uint8_t *data, size_t len)
|
||||
{
|
||||
unsigned int freespace, usedspace;
|
||||
|
||||
if (len == 0) {
|
||||
/* Calling with no data is valid - we do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
|
||||
if (usedspace > 0) {
|
||||
/* Calculate how much free space is available in the buffer */
|
||||
freespace = SHA256_BLOCK_LENGTH - usedspace;
|
||||
|
||||
if (len >= freespace) {
|
||||
/* Fill the buffer completely and process it */
|
||||
MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
|
||||
context->bitcount += freespace << 3;
|
||||
len -= freespace;
|
||||
data += freespace;
|
||||
SHA256_Transform(context, (sha2_word32 *)context->buffer);
|
||||
} else {
|
||||
/* The buffer is not yet full */
|
||||
MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
|
||||
context->bitcount += len << 3;
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (len >= SHA256_BLOCK_LENGTH) {
|
||||
/* Process as many complete blocks as we can */
|
||||
SHA256_Transform(context, (sha2_word32 *)data);
|
||||
context->bitcount += SHA256_BLOCK_LENGTH << 3;
|
||||
len -= SHA256_BLOCK_LENGTH;
|
||||
data += SHA256_BLOCK_LENGTH;
|
||||
}
|
||||
if (len > 0) {
|
||||
/* There's left-overs, so save 'em */
|
||||
MEMCPY_BCOPY(context->buffer, data, len);
|
||||
context->bitcount += len << 3;
|
||||
}
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
}
|
||||
|
||||
void DICE_SHA256_Final(DICE_SHA256_CONTEXT *context, sha2_uint8_t *digest)
|
||||
{
|
||||
sha2_word32 *d = (sha2_word32 *)digest;
|
||||
unsigned int usedspace;
|
||||
|
||||
/* If no digest buffer is passed, we don't bother doing this: */
|
||||
if (digest != (sha2_uint8_t *)0) {
|
||||
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
/* Convert FROM host uint8_t order */
|
||||
REVERSE64(context->bitcount,context->bitcount);
|
||||
#endif
|
||||
if (usedspace > 0) {
|
||||
/* Begin padding with a 1 bit: */
|
||||
context->buffer[usedspace++] = 0x80;
|
||||
|
||||
if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
|
||||
/* Set-up for the last transform: */
|
||||
MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
|
||||
} else {
|
||||
if (usedspace < SHA256_BLOCK_LENGTH) {
|
||||
MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
|
||||
}
|
||||
/* Do second-to-last transform: */
|
||||
SHA256_Transform(context, (sha2_word32 *)context->buffer);
|
||||
|
||||
/* And set-up for the last transform: */
|
||||
MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
|
||||
}
|
||||
} else {
|
||||
/* Set-up for the last transform: */
|
||||
MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
|
||||
|
||||
/* Begin padding with a 1 bit: */
|
||||
*context->buffer = 0x80;
|
||||
}
|
||||
/* Set the bit count: */
|
||||
*(sha2_word64 *)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
|
||||
|
||||
/* Final transform: */
|
||||
SHA256_Transform(context, (sha2_word32 *)context->buffer);
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
{
|
||||
/* Convert TO host uint8_t order */
|
||||
int j;
|
||||
for (j = 0; j < 8; j++) {
|
||||
REVERSE32(context->state[j],context->state[j]);
|
||||
*d++ = context->state[j];
|
||||
}
|
||||
}
|
||||
#else
|
||||
MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Clean up state data: */
|
||||
MEMSET_BZERO(context, sizeof(DICE_SHA256_CONTEXT));
|
||||
usedspace = 0;
|
||||
}
|
||||
|
||||
void DiceSHA256Ctx(DICE_SHA256_CONTEXT *context, const uint8_t *buf, size_t bufSize, uint8_t *digest)
|
||||
{
|
||||
DICE_SHA256_Init(context);
|
||||
DICE_SHA256_Update(context, buf, bufSize);
|
||||
DICE_SHA256_Final(context, digest);
|
||||
}
|
||||
|
||||
void DiceSHA256(const uint8_t *buf, size_t bufSize, uint8_t *digest)
|
||||
{
|
||||
DICE_SHA256_CONTEXT context;
|
||||
DICE_SHA256_Init(&context);
|
||||
DICE_SHA256_Update(&context, buf, bufSize);
|
||||
DICE_SHA256_Final(&context, digest);
|
||||
}
|
||||
|
||||
void DiceSHA256_2(const uint8_t *buf1, size_t bufSize1, const uint8_t *buf2, size_t bufSize2, uint8_t *digest)
|
||||
{
|
||||
DICE_SHA256_CONTEXT context;
|
||||
DICE_SHA256_Init(&context);
|
||||
DICE_SHA256_Update(&context, buf1, bufSize1);
|
||||
DICE_SHA256_Update(&context, buf2, bufSize2);
|
||||
DICE_SHA256_Final(&context, digest);
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2001, Aaron D. Gifford
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $
|
||||
*/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; DICE adaptation (DennisMa;MSFT).
|
||||
//
|
||||
#ifndef __DICE_CRYPTO_SHA256_H__
|
||||
#define __DICE_CRYPTO_SHA256_H__
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int asb;
|
||||
|
||||
typedef uint8_t sha2_uint8_t; // Exactly 1 byte
|
||||
typedef uint32_t sha2_word32; // Exactly 4 bytes
|
||||
typedef uint64_t sha2_word64; // Exactly 8 bytes
|
||||
|
||||
#define SHA256_BLOCK_LENGTH 64
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
|
||||
typedef uint64_t hashMagic_t;
|
||||
|
||||
#if HOST_IS_LITTLE_ENDIAN
|
||||
#define HASH_MAGIC_VALUE (0x4078746368736168LL)
|
||||
#else
|
||||
#define HASH_MAGIC_VALUE (0x6861736863747840LL)
|
||||
#endif
|
||||
|
||||
typedef struct _DICE_SHA256_CONTEXT {
|
||||
uint32_t state[8];
|
||||
hashMagic_t magic;
|
||||
uint64_t bitcount;
|
||||
uint8_t buffer[SHA256_BLOCK_LENGTH];
|
||||
} DICE_SHA256_CONTEXT;
|
||||
|
||||
//
|
||||
// Initialize the hash context
|
||||
// @param context the hash context
|
||||
//
|
||||
void DICE_SHA256_Init(DICE_SHA256_CONTEXT *context);
|
||||
|
||||
//
|
||||
// Update the digest using the specific bytes
|
||||
// @param context the hash context
|
||||
// @param buf the bytes to digest
|
||||
// @param bufSize the number of bytes to digest
|
||||
//
|
||||
void DICE_SHA256_Update(DICE_SHA256_CONTEXT *context,
|
||||
const sha2_uint8_t *data, size_t len);
|
||||
|
||||
//
|
||||
// Retrieve the final digest
|
||||
// @param context the hash context
|
||||
// @param digest the buffer to hold the digest. Must be of size SHA256_DIGEST_LENGTH
|
||||
//
|
||||
void DICE_SHA256_Final(DICE_SHA256_CONTEXT *context, sha2_uint8_t *digest);
|
||||
|
||||
//
|
||||
// Hash a block of data
|
||||
// @param context the hash context
|
||||
// @param buf the buffer containing the data to hash
|
||||
// @param bufSize the number of bytes in the buffer
|
||||
// @param digest the buffer to hold the digest. Must be of size SHA256_DIGEST_LENGTH
|
||||
//
|
||||
void DiceSHA256Ctx(DICE_SHA256_CONTEXT *context,
|
||||
const uint8_t *buf, size_t bufSize,
|
||||
uint8_t *digest);
|
||||
|
||||
//
|
||||
// Hash a block of data
|
||||
// @param buf the buffer containing the data to hash
|
||||
// @param bufSize the number of bytes in the buffer
|
||||
// @param digest the buffer to hold the digest. Must be of size SHA256_DIGEST_LENGTH
|
||||
//
|
||||
void DiceSHA256(const uint8_t *buf, size_t bufSize,
|
||||
uint8_t *digest);
|
||||
|
||||
void DiceSHA256_2(const uint8_t *buf1, size_t bufSize1,
|
||||
const uint8_t *buf2, size_t bufSize2,
|
||||
uint8_t *digest);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -0,0 +1 @@
|
|||
#include "stdafx.h"
|
|
@ -0,0 +1,8 @@
|
|||
#pragma once
|
||||
#include "targetver.h"
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <stdint.h>
|
||||
#include "DiceSha256.h"
|
|
@ -0,0 +1,2 @@
|
|||
#pragma once
|
||||
#include <SDKDDKVer.h>
|
|
@ -0,0 +1,53 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
|
||||
// There are lots of ways to force a new FWID value. However, to
|
||||
// maintain a consistent FWID value accross "boots", the default
|
||||
// linker option that randomizes base addresses must be disabled.
|
||||
|
||||
FW_API void FirmwareEntry(
|
||||
ecc_publickey *DeviceIDPub,
|
||||
ecc_publickey *AliasKeyPub,
|
||||
ecc_privatekey *AliasKeyPriv,
|
||||
char *AliasKeyCert
|
||||
)
|
||||
{
|
||||
UINT32 i;
|
||||
|
||||
printf("FW: Begin.\n");
|
||||
printf("FW: AliasKeyPub:\n\tx: ");
|
||||
for (i = 0; i < ((BIGLEN)-1); i++) {
|
||||
printf("%08X", AliasKeyPub->x.data[i]);
|
||||
}
|
||||
printf("\n\ty: ");
|
||||
for (i = 0; i < ((BIGLEN)-1); i++) {
|
||||
printf("%08X", AliasKeyPub->y.data[i]);
|
||||
}
|
||||
printf("\nFW: AliasKeyPriv:\n\t ");
|
||||
for (i = 0; i < ((BIGLEN)-1); i++) {
|
||||
printf("%08X", AliasKeyPriv->data[i]);
|
||||
}
|
||||
|
||||
printf("\nFW: AliasKeyCertificate:\n %s", AliasKeyCert);
|
||||
|
||||
i = 5;
|
||||
do {
|
||||
printf("\rFW: \"Running\" \\");
|
||||
Sleep(100);
|
||||
printf("\rFW: \"Running\" |");
|
||||
Sleep(100);
|
||||
printf("\rFW: \"Running\" /");
|
||||
Sleep(100);
|
||||
printf("\rFW: \"Running\" -");
|
||||
Sleep(100);
|
||||
} while (i--);
|
||||
|
||||
printf("\nFW: Reboot!\n");
|
||||
Sleep(300);
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "RIoT.h"
|
||||
#include "RIoTSim.h"
|
||||
|
||||
#ifdef LOADER_EXPORTS
|
||||
#define FW_API __declspec(dllexport)
|
||||
#else
|
||||
#define FW_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
FW_API void FirmwareEntry(
|
||||
ecc_publickey *DeviceIDPub,
|
||||
ecc_publickey *AliasKeyPub,
|
||||
ecc_privatekey *AliasKeyPriv,
|
||||
char *AliasKeyCert
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,113 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{FD767D67-E637-4AD0-A99A-6C35CE32E4A4}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>Loader</RootNamespace>
|
||||
<ProjectName>FW</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;LOADER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\RIoT\Core;$(SolutionDir)\RIoT\Platform;$(SolutionDir)\RIoT\Core\RIoTCrypt\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;LOADER_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\RIoT\Core;$(SolutionDir)\RIoT\Platform;$(SolutionDir)\RIoT\Core\RIoTCrypt\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>No</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Loader.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Loader.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Loader.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Ignore</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Ignore</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Ignore</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Ignore</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Loader.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{246e2e3b-b4ca-4a5e-8c5c-4fc07fe1f88d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Ignore">
|
||||
<UniqueIdentifier>{68d94a60-4cbc-42b1-b668-6f18d91c12d5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{086194d6-5a29-4de0-b4e2-890204396e6c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,24 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
|
||||
BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#include "stdafx.h"
|
|
@ -0,0 +1,15 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
#include <stdio.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
// Includes
|
||||
#include "Loader.h"
|
|
@ -0,0 +1,8 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#pragma once
|
||||
#include <SDKDDKVer.h>
|
|
@ -1 +0,0 @@
|
|||
DICE/RIoT Reference Implementation
|
|
@ -0,0 +1,234 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// There are lots of ways to force a new CDI value. However, to
|
||||
// maintain a consistent CDI value accross "boots", the default
|
||||
// linker option that randomizes base addresses must be disabled.
|
||||
|
||||
// For our simulated device, it's fine that these are in the global
|
||||
// data for the RIoT DLL. On real hardware, these are passed via some
|
||||
// shared data area or in a hardware security module.
|
||||
RIOT_ECC_PUBLIC DeviceIDPub;
|
||||
RIOT_ECC_PUBLIC AliasKeyPub;
|
||||
RIOT_ECC_PRIVATE AliasKeyPriv;
|
||||
BYTE FWID[RIOT_DIGEST_LENGTH];
|
||||
char Cert[DER_MAX_PEM];
|
||||
char *CSRBuffer = NULL; // Optional, !used when NULL
|
||||
|
||||
// Device Firmware may prefer PEM encoded DeviceID/Alias Keys. This is not
|
||||
// the default. Define RIOT_ENCODED_KEYS here and adjust the buffer copies
|
||||
// below to support PEM-encoded keys for device firmware.
|
||||
// #define RIOT_ENCODED_KEYS
|
||||
|
||||
// The static data fields that make up the x509 "to be signed" region
|
||||
RIOT_X509_TBS_DATA x509TBSData = { { 0x0A, 0x0B, 0x0C, 0x0D, 0x0E },
|
||||
"RIoT Core", "MSR_TEST", "US",
|
||||
"170101000000Z", "370101000000Z",
|
||||
"RIoT Device", "MSR_TEST", "US" };
|
||||
|
||||
// Name and function pointer corresponding to the current FW image
|
||||
#define FIRMWARE_ENTRY "FirmwareEntry"
|
||||
typedef void(__cdecl* fpFirmwareEntry)(
|
||||
ecc_publickey *DeviceIDPub,
|
||||
ecc_publickey *AliasKeyPub,
|
||||
ecc_privatekey *AliasKeyPriv,
|
||||
char *AliasKeyCert
|
||||
);
|
||||
|
||||
// Simulation only: This function finds the in-memory base-offset and size
|
||||
// of RIoT .text section. On real hardware RIoT would have knowledge of
|
||||
// the physical location and size of device firmware.
|
||||
BOOLEAN RiotGetFWInfo(HINSTANCE fwDLL, DWORD *baseOffset, DWORD *length);
|
||||
|
||||
RIOT_API void
|
||||
RiotStart(
|
||||
const BYTE *CDI,
|
||||
const uint32_t CDILen,
|
||||
const TCHAR *FWImagePath
|
||||
)
|
||||
{
|
||||
BYTE cerBuffer[DER_MAX_TBS];
|
||||
BYTE derBuffer[DER_MAX_TBS];
|
||||
BYTE cDigest[RIOT_DIGEST_LENGTH];
|
||||
RIOT_ECC_PRIVATE deviceIDPriv;
|
||||
RIOT_ECC_SIGNATURE tbsSig;
|
||||
DERBuilderContext derCtx;
|
||||
DERBuilderContext cerCtx;
|
||||
fpFirmwareEntry FirmwareEntry;
|
||||
BYTE *fwImage;
|
||||
uint32_t length;
|
||||
DWORD fwSize, offset, i;
|
||||
HINSTANCE fwDLL;
|
||||
|
||||
// Parameter validation
|
||||
if (!(CDI) || (CDILen != SHA256_DIGEST_LENGTH)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// RIoT Begin
|
||||
printf("RIOT: Begin\n");
|
||||
|
||||
// Don't use CDI directly
|
||||
RiotCrypt_Hash(cDigest, RIOT_DIGEST_LENGTH, CDI, CDILen);
|
||||
|
||||
// Derive DeviceID key pair from CDI
|
||||
RiotCrypt_DeriveEccKey(&DeviceIDPub,
|
||||
&deviceIDPriv,
|
||||
cDigest, RIOT_DIGEST_LENGTH,
|
||||
(const uint8_t *)RIOT_LABEL_IDENTITY,
|
||||
lblSize(RIOT_LABEL_IDENTITY));
|
||||
|
||||
// Device Identity Key pair
|
||||
printf("RIOT: deviceIDPublic:\n\tx: ");
|
||||
for (i = 0; i < ((BIGLEN) - 1); i++) {
|
||||
printf("%08X", DeviceIDPub.x.data[i]);
|
||||
}
|
||||
printf("\n\ty: ");
|
||||
for (i = 0; i < ((BIGLEN) - 1); i++) {
|
||||
printf("%08X", DeviceIDPub.y.data[i]);
|
||||
}
|
||||
printf("\nRIOT: deviceIDPrivate:\n\t ");
|
||||
for (i = 0; i < ((BIGLEN)-1); i++) {
|
||||
printf("%08X", deviceIDPriv.data[i]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
// Locate firmware image
|
||||
fwDLL = LoadLibrary(FWImagePath);
|
||||
if (fwDLL == NULL) {
|
||||
printf("RIOT: ERROR: Failed to load firmware image.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Locate entry point for FW
|
||||
FirmwareEntry = (fpFirmwareEntry)GetProcAddress(fwDLL, FIRMWARE_ENTRY);
|
||||
if (!FirmwareEntry) {
|
||||
printf("RIOT: ERROR: Failed to locate fw start\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get base offset and size of FW image
|
||||
if (!RiotGetFWInfo(fwDLL, &offset, &fwSize)) {
|
||||
fprintf(stderr, "FW: Failed to locate FW code\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate base VA of FW code
|
||||
fwImage = (BYTE *)((uint64_t)fwDLL + offset);
|
||||
|
||||
// Measure FW, i.e., calculate FWID
|
||||
RiotCrypt_Hash(FWID, RIOT_DIGEST_LENGTH, fwImage, fwSize);
|
||||
|
||||
// Combine CDI and FWID, result in cDigest
|
||||
RiotCrypt_Hash2(cDigest, RIOT_DIGEST_LENGTH,
|
||||
cDigest, RIOT_DIGEST_LENGTH,
|
||||
FWID, RIOT_DIGEST_LENGTH);
|
||||
|
||||
// Derive Alias key pair from CDI and FWID
|
||||
RiotCrypt_DeriveEccKey(&AliasKeyPub,
|
||||
&AliasKeyPriv,
|
||||
cDigest, RIOT_DIGEST_LENGTH,
|
||||
(const uint8_t *)RIOT_LABEL_ALIAS,
|
||||
lblSize(RIOT_LABEL_ALIAS));
|
||||
|
||||
// Clean up potentially sensative data
|
||||
memset(cDigest, 0x00, RIOT_DIGEST_LENGTH);
|
||||
|
||||
// Build the TBS (to be signed) region of Alias Key Certificate
|
||||
DERInitContext(&cerCtx, cerBuffer, DER_MAX_TBS);
|
||||
X509GetDEREncodedTBS(&cerCtx, &x509TBSData,
|
||||
&AliasKeyPub, &DeviceIDPub,
|
||||
FWID, RIOT_DIGEST_LENGTH);
|
||||
|
||||
// Sign the Alias Key Certificate's TBS region
|
||||
RiotCrypt_Sign(&tbsSig, cerCtx.Buffer, cerCtx.Position, &deviceIDPriv);
|
||||
|
||||
// Generate Alias Key Certificate by signing the TBS region
|
||||
X509MakeAliasCert(&cerCtx, &tbsSig);
|
||||
|
||||
// Optionally, make a CSR for the DeviceID
|
||||
if (CSRBuffer != NULL) {
|
||||
|
||||
// Initialize, create CSR TBS region
|
||||
DERInitContext(&derCtx, derBuffer, DER_MAX_TBS);
|
||||
X509GetDERCsrTbs(&derCtx, &x509TBSData, &DeviceIDPub);
|
||||
|
||||
// Sign the Alias Key Certificate's TBS region
|
||||
RiotCrypt_Sign(&tbsSig, derCtx.Buffer, derCtx.Position, &deviceIDPriv);
|
||||
|
||||
// Create CSR for DeviceID
|
||||
X509GetDERCsr(&derCtx, &tbsSig);
|
||||
|
||||
// Copy CSR
|
||||
length = sizeof(CSRBuffer);
|
||||
DERtoPEM(&derCtx, CERT_REQ_TYPE, CSRBuffer, &length);
|
||||
CSRBuffer[length] = '\0';
|
||||
}
|
||||
|
||||
// Copy Alias Key Certificate
|
||||
length = sizeof(Cert);
|
||||
DERtoPEM(&cerCtx, CERT_TYPE, Cert, &length);
|
||||
Cert[length] = '\0';
|
||||
|
||||
#ifdef RIOT_ENCODE_KEYS
|
||||
|
||||
// Copy DeviceID Public
|
||||
length = sizeof(PEM);
|
||||
DERInitContext(&derCtx, derBuffer, DER_MAX_TBS);
|
||||
X509GetDEREccPub(&derCtx, DeviceIDPub);
|
||||
DERtoPEM(&derCtx, PUBLICKEY_TYPE, PEM, &length);
|
||||
*DeviceIDPublicEncodedSize = length;
|
||||
memcpy(DeviceIDPublicEncoded, PEM, length);
|
||||
|
||||
// Copy Alias Key Pair
|
||||
length = sizeof(PEM);
|
||||
DERInitContext(&derCtx, derBuffer, DER_MAX_TBS);
|
||||
X509GetDEREcc(&derCtx, AliasKeyPub, AliasKeyPriv);
|
||||
DERtoPEM(&derCtx, ECC_PRIVATEKEY_TYPE, PEM, &length);
|
||||
*AliasKeyEncodedSize = length;
|
||||
memcpy(AliasKeyEncoded, PEM, length);
|
||||
|
||||
#endif
|
||||
|
||||
// Transfer control to firmware
|
||||
FirmwareEntry(&DeviceIDPub, &AliasKeyPub, &AliasKeyPriv, Cert);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
RiotGetFWInfo(
|
||||
HINSTANCE fwDLL,
|
||||
DWORD *baseOffset,
|
||||
DWORD *length
|
||||
)
|
||||
// This is a quick and dirty function to find the .text (CODE) section of
|
||||
// the FW image. We don't do anything like this on real hardware because,
|
||||
// on real hardware, RIoT has the base address and size of the FW are
|
||||
// as constant values resolved at build/link time.
|
||||
{
|
||||
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)fwDLL;
|
||||
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((PCHAR)dosHeader + (ULONG)(dosHeader->e_lfanew));
|
||||
PIMAGE_OPTIONAL_HEADER optionalHeader = &(ntHeader->OptionalHeader);
|
||||
PIMAGE_SECTION_HEADER sectionHeader = (PIMAGE_SECTION_HEADER)(optionalHeader + 1);
|
||||
PIMAGE_FILE_HEADER fileHeader = &(ntHeader->FileHeader);
|
||||
ULONG nSections = fileHeader->NumberOfSections, i;
|
||||
|
||||
for (i = 0; i < nSections; i++)
|
||||
{
|
||||
if (!strcmp((char *)sectionHeader->Name, ".text"))
|
||||
{
|
||||
*baseOffset = sectionHeader->VirtualAddress;
|
||||
*length = sectionHeader->Misc.VirtualSize;
|
||||
return TRUE;
|
||||
}
|
||||
sectionHeader++;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#ifndef _RIOT_H
|
||||
#define _RIOT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "RiotStatus.h"
|
||||
#include "RiotCrypt.h"
|
||||
|
||||
#define RIOT_SUCCESS(a) (a == (RIOT_OK))
|
||||
|
||||
//
|
||||
// Key derivation labels used by both RIoT Devices and External Infrastructure
|
||||
//
|
||||
#define RIOT_LABEL_IDENTITY "Identity"
|
||||
#define RIOT_LABEL_ALIAS "Alias"
|
||||
#define RIOT_LABEL_PROTECTOR "Encrypt"
|
||||
#define RIOT_LABEL_INTEGRITY "HMAC"
|
||||
#define RIOT_LABEL_AIK "AikProtector"
|
||||
#define RIOT_LABEL_SK "Sealing"
|
||||
#define RIOT_LABEL_MK "Migration"
|
||||
#define RIOT_LABEL_AK "Attestation"
|
||||
|
||||
//
|
||||
// Macro for label sizes (skip strlen()).
|
||||
//
|
||||
#define lblSize(a) (sizeof(a) - 1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,143 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{B7AF6C41-115E-4926-A8B3-7842FFE9D605}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>RIoT</RootNamespace>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IntDir>$(Configuration)\$(ProjectName)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;RIOT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\RIoT\Core;$(SolutionDir)\RIoT\Core\RIoTCrypt\include;$(SolutionDir)\RIoT\Platform;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
|
||||
<MapFileName>
|
||||
</MapFileName>
|
||||
<MapExports>true</MapExports>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>false</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;RIOT_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\RIoT\Core;$(SolutionDir)\RIoT\Core\RIoTCrypt\include;$(SolutionDir)\RIoT\Platform;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>No</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<PreventDllBinding>false</PreventDllBinding>
|
||||
<GenerateMapFile>true</GenerateMapFile>
|
||||
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
|
||||
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<MapFileName>
|
||||
</MapFileName>
|
||||
<MapExports>true</MapExports>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="RIoT.h" />
|
||||
<ClInclude Include="RIoTCrypt\include\RiotAes128.h" />
|
||||
<ClInclude Include="RIoTCrypt\include\RiotBase64.h" />
|
||||
<ClInclude Include="RIoTCrypt\include\RiotCrypt.h" />
|
||||
<ClInclude Include="RIoTCrypt\include\RiotDerEnc.h" />
|
||||
<ClInclude Include="RIoTCrypt\include\RiotEcc.h" />
|
||||
<ClInclude Include="RIoTCrypt\include\RiotHmac.h" />
|
||||
<ClInclude Include="RIoTCrypt\include\RiotKdf.h" />
|
||||
<ClInclude Include="RIoTCrypt\include\RiotSha256.h" />
|
||||
<ClInclude Include="RIoTCrypt\include\RiotTarget.h" />
|
||||
<ClInclude Include="RIoTCrypt\include\RiotX509Bldr.h" />
|
||||
<ClInclude Include="RIoTSim.h" />
|
||||
<ClInclude Include="RiotStatus.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RIoT.cpp" />
|
||||
<ClCompile Include="RIoTCrypt\RiotAes128.c" />
|
||||
<ClCompile Include="RIoTCrypt\RiotAesTables.c" />
|
||||
<ClCompile Include="RIoTCrypt\RiotBase64.c" />
|
||||
<ClCompile Include="RIoTCrypt\RiotCrypt.c" />
|
||||
<ClCompile Include="RIoTCrypt\RiotDerEnc.c" />
|
||||
<ClCompile Include="RIoTCrypt\RiotEcc.c" />
|
||||
<ClCompile Include="RIoTCrypt\RiotHmac.c" />
|
||||
<ClCompile Include="RIoTCrypt\RiotKdf.c" />
|
||||
<ClCompile Include="RIoTCrypt\RiotSha256.c" />
|
||||
<ClCompile Include="RIoTCrypt\RiotX509Bldr.c" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,105 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Ignore</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Ignore</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RIoTCrypt\RiotAes128.c">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RIoTCrypt\RiotAesTables.c">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RIoTCrypt\RiotCrypt.c">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RIoTCrypt\RiotEcc.c">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RIoTCrypt\RiotHmac.c">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RIoTCrypt\RiotKdf.c">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RIoTCrypt\RiotSha256.c">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RIoT.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RIoTCrypt\RiotBase64.c">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RIoTCrypt\RiotDerEnc.c">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RIoTCrypt\RiotX509Bldr.c">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Ignore</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Ignore</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RIoTCrypt\include\RiotAes128.h">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RIoTCrypt\include\RiotCrypt.h">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RIoTCrypt\include\RiotEcc.h">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RIoTCrypt\include\RiotHmac.h">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RIoTCrypt\include\RiotKdf.h">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RIoTCrypt\include\RiotSha256.h">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RIoTCrypt\include\RiotTarget.h">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RIoTSim.h">
|
||||
<Filter>Ignore</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RIoT.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RiotStatus.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RIoTCrypt\include\RiotBase64.h">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RIoTCrypt\include\RiotDerEnc.h">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RIoTCrypt\include\RiotX509Bldr.h">
|
||||
<Filter>Source Files\RIoTCrypt</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Ignore">
|
||||
<UniqueIdentifier>{771665da-df93-4f4a-9295-8a1dff1fcda6}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{8ec5003f-cc85-4a86-86b1-fb45f3b0a096}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{d98b2f81-2200-4dd2-8325-d85667c038ca}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\RIoTCrypt">
|
||||
<UniqueIdentifier>{8154c665-1e08-4aa5-84b9-76d6c7a4dcb8}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,271 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2013, AllSeen Alliance. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT)
|
||||
//
|
||||
#include "RiotTarget.h"
|
||||
#include "RiotAes128.h"
|
||||
|
||||
#define _AES_COMPILE_
|
||||
#include "RiotAesTables.c"
|
||||
|
||||
#define ROTL8(x) ((((uint32_t)(x)) << 8) | (((uint32_t)(x)) >> 24))
|
||||
#define ROTL16(x) ((((uint32_t)(x)) << 16) | (((uint32_t)(x)) >> 16))
|
||||
#define ROTL24(x) ((((uint32_t)(x)) << 24) | (((uint32_t)(x)) >> 8))
|
||||
|
||||
#define SHFL8(x) (((uint32_t)(x)) << 8)
|
||||
#define SHFL16(x) (((uint32_t)(x)) << 16)
|
||||
#define SHFL24(x) (((uint32_t)(x)) << 24)
|
||||
|
||||
#define ROW_0(x) (uint8_t)(x)
|
||||
#define ROW_1(x) (uint8_t)((x) >> 8)
|
||||
#define ROW_2(x) (uint8_t)((x) >> 16)
|
||||
#define ROW_3(x) (uint8_t)((x) >> 24)
|
||||
|
||||
#define round_column(x0, x1, x2, x3) \
|
||||
ftable[ROW_0(x0)] \
|
||||
^ ROTL8 (ftable[ROW_1(x1)]) \
|
||||
^ ROTL16(ftable[ROW_2(x2)]) \
|
||||
^ ROTL24(ftable[ROW_3(x3)])
|
||||
|
||||
//
|
||||
// yN are inputs xN are outputs
|
||||
//
|
||||
#define round(y0, y1, y2, y3, x0, x1, x2, x3, key) \
|
||||
y0 = round_column(x0, x1, x2, x3) ^ *key++; \
|
||||
y1 = round_column(x1, x2, x3, x0) ^ *key++; \
|
||||
y2 = round_column(x2, x3, x0, x1) ^ *key++; \
|
||||
y3 = round_column(x3, x0, x1, x2) ^ *key++;
|
||||
|
||||
#define lastround_column(x0, x1, x2, x3) \
|
||||
(uint32_t)sbox[ROW_0(x0)] \
|
||||
^ SHFL8(sbox[ROW_1(x1)]) \
|
||||
^ SHFL16(sbox[ROW_2(x2)]) \
|
||||
^ SHFL24(sbox[ROW_3(x3)])
|
||||
|
||||
//
|
||||
// yN are inputs xN are outputs
|
||||
//
|
||||
#define lastround(y0, y1, y2, y3, x0, x1, x2, x3, key) \
|
||||
y0 = lastround_column(x0, x1, x2, x3) ^ *key++; \
|
||||
y1 = lastround_column(x1, x2, x3, x0) ^ *key++; \
|
||||
y2 = lastround_column(x2, x3, x0, x1) ^ *key++; \
|
||||
y3 = lastround_column(x3, x0, x1, x2) ^ *key++;
|
||||
|
||||
static void Pack32(uint32_t *u32, const uint8_t *u8)
|
||||
{
|
||||
#if HOST_IS_LITTLE_ENDIAN
|
||||
memcpy(u32, u8, 16);
|
||||
#else
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i, ++u32, u8 += 4) {
|
||||
*u32 = (uint32_t)u8[0] | (u8[1] << 8) | (u8[2] << 16) | (u8[3] << 24);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void Unpack32(uint8_t *u8, const uint32_t *u32)
|
||||
{
|
||||
#if HOST_IS_LITTLE_ENDIAN
|
||||
memcpy(u8, u32, 16);
|
||||
#else
|
||||
int i;
|
||||
for (i = 0; i < 4; ++i, ++u32) {
|
||||
*u8++ = (uint8_t)(*u32);
|
||||
*u8++ = (uint8_t)(*u32 >> 8);
|
||||
*u8++ = (uint8_t)(*u32 >> 16);
|
||||
*u8++ = (uint8_t)(*u32 >> 24);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint32_t SubBytes(uint32_t a)
|
||||
{
|
||||
return (uint32_t)sbox[(uint8_t)(a)] |
|
||||
(sbox[(uint8_t)(a >> 8)] << 8) |
|
||||
(sbox[(uint8_t)(a >> 16)] << 16) |
|
||||
(sbox[(uint8_t)(a >> 24)] << 24);
|
||||
}
|
||||
|
||||
#define ROUNDS 10
|
||||
|
||||
static void EncryptRounds(uint32_t *out, uint32_t *in, uint32_t *key)
|
||||
{
|
||||
int i;
|
||||
uint32_t x0 = in[0] ^ key[0];
|
||||
uint32_t x1 = in[1] ^ key[1];
|
||||
uint32_t x2 = in[2] ^ key[2];
|
||||
uint32_t x3 = in[3] ^ key[3];
|
||||
uint32_t y0;
|
||||
uint32_t y1;
|
||||
uint32_t y2;
|
||||
uint32_t y3;
|
||||
key += 4;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
round(y0, y1, y2, y3, x0, x1, x2, x3, key);
|
||||
round(x0, x1, x2, x3, y0, y1, y2, y3, key);
|
||||
}
|
||||
|
||||
round(y0, y1, y2, y3, x0, x1, x2, x3, key);
|
||||
lastround(x0, x1, x2, x3, y0, y1, y2, y3, key);
|
||||
|
||||
out[0] = x0;
|
||||
out[1] = x1;
|
||||
out[2] = x2;
|
||||
out[3] = x3;
|
||||
}
|
||||
|
||||
void RIOT_AES128_Enable(const uint8_t *key, aes128EncryptKey_t *aesEncryptKey)
|
||||
{
|
||||
int i;
|
||||
uint32_t *fkey = (uint32_t *)aesEncryptKey;
|
||||
|
||||
Pack32(fkey, key);
|
||||
for (i = 0; i <= ROUNDS; ++i, fkey += 4) {
|
||||
fkey[4] = fkey[0] ^ SubBytes(ROTL24(fkey[3])) ^ Rconst[i];
|
||||
fkey[5] = fkey[1] ^ fkey[4];
|
||||
fkey[6] = fkey[2] ^ fkey[5];
|
||||
fkey[7] = fkey[3] ^ fkey[6];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RIOT_AES128_Disable(aes128EncryptKey_t *aesEncryptionKey)
|
||||
{
|
||||
memset(aesEncryptionKey, 0, sizeof(aes128EncryptKey_t));
|
||||
}
|
||||
|
||||
#if AES_CTR_MODE
|
||||
void RIOT_AES_CTR_128(const aes128EncryptKey_t *aes128EncryptKey, const uint8_t *in,
|
||||
uint8_t *out, uint32_t len, uint8_t *ctr)
|
||||
{
|
||||
uint32_t counter[4];
|
||||
#if HOST_IS_LITTLE_ENDIAN
|
||||
// Point to the big endian counter at the end of the IV
|
||||
uint8_t *pCtr = (uint8_t *)(&counter[3]);
|
||||
#endif
|
||||
uint32_t tmp[4];
|
||||
|
||||
// Counter is really the IV for the encryption. The counter will take the
|
||||
// low-order 4 octets of the IV and use that as a counter.
|
||||
Pack32(counter, ctr);
|
||||
|
||||
while (len) {
|
||||
|
||||
// DJM: DICE (min->MIN)
|
||||
uint32_t n = MIN(len, 16);
|
||||
uint8_t *p = (uint8_t *)tmp;
|
||||
EncryptRounds(tmp, counter, (uint32_t *)aes128EncryptKey);
|
||||
len -= n;
|
||||
while (n--) {
|
||||
*out++ = *p++ ^ *in++;
|
||||
}
|
||||
//
|
||||
// The counter field is big-endian because that is what is in the standard.
|
||||
//
|
||||
#if HOST_IS_LITTLE_ENDIAN
|
||||
//
|
||||
// A big-endian increment of a 32 bit value on a little-endian CPU.
|
||||
//
|
||||
if ((pCtr[3] += 1) == 0)
|
||||
if ((pCtr[2] += 1) == 0)
|
||||
if ((pCtr[1] += 1) == 0)
|
||||
{ pCtr[0] += 1; }
|
||||
#else
|
||||
counter[3] += 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
Unpack32(ctr, counter);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if AES_CBC_MODE
|
||||
void RIOT_AES_CBC_128_ENCRYPT(const aes128EncryptKey_t *aes128EncryptKey,
|
||||
const uint8_t *in, uint8_t *out, uint32_t len,
|
||||
uint8_t *iv)
|
||||
{
|
||||
uint32_t xorbuf[4];
|
||||
uint32_t ivt[4];
|
||||
|
||||
assert((len % 16) == 0);
|
||||
|
||||
Pack32(ivt, iv);
|
||||
while (len) {
|
||||
int i;
|
||||
Pack32(xorbuf, in);
|
||||
for (i = 0; i < 4; ++i) {
|
||||
xorbuf[i] ^= ivt[i];
|
||||
}
|
||||
EncryptRounds(ivt, xorbuf, (uint32_t *)aes128EncryptKey);
|
||||
Unpack32(out, ivt);
|
||||
out += 16;
|
||||
in += 16;
|
||||
len -= 16;
|
||||
}
|
||||
Unpack32(iv, ivt);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if AES_ECB_MODE
|
||||
void RIOT_AES_ECB_128_ENCRYPT(const aes128EncryptKey_t *aes128EncryptKey,
|
||||
const uint8_t *in, uint8_t *out, size_t size)
|
||||
{
|
||||
uint32_t in32[4];
|
||||
uint32_t out32[4];
|
||||
|
||||
assert((size % AES_BLOCK_SIZE) == 0);
|
||||
|
||||
for (; size != 0; size -= AES_BLOCK_SIZE) {
|
||||
Pack32(in32, in);
|
||||
EncryptRounds(out32, in32, (uint32_t *)aes128EncryptKey);
|
||||
Unpack32(out, out32);
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define CRYPTO_TESTS
|
||||
|
||||
//
|
||||
// Symmetric Test Functions
|
||||
//
|
||||
//#define CRYPTO_TESTS
|
||||
#ifdef CRYPTO_TESTS
|
||||
|
||||
const char *modes[] = {
|
||||
#if AES_CTR_MODE
|
||||
"CTR",
|
||||
#endif
|
||||
#if AES_CBC_MODE
|
||||
"CBC",
|
||||
#endif
|
||||
#if AES_ECB_MODE
|
||||
"ECB",
|
||||
#endif
|
||||
""
|
||||
};
|
||||
|
||||
const char **riot_aes_modes(void)
|
||||
{
|
||||
return &modes[0];
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,135 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2013, AllSeen Alliance. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT).
|
||||
//
|
||||
|
||||
#ifdef _AES_COMPILE_
|
||||
|
||||
/* The Rijndael S-box matrix */
|
||||
static const uint8_t sbox[256] = {
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
|
||||
0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
|
||||
0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
|
||||
0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
|
||||
0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
|
||||
0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
|
||||
0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
|
||||
0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
|
||||
0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
|
||||
0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
|
||||
0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
|
||||
0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
|
||||
0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
|
||||
0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
|
||||
0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
|
||||
0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
|
||||
0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
|
||||
0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
|
||||
0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
|
||||
0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
|
||||
0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
|
||||
0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
|
||||
0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
|
||||
0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
|
||||
0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
|
||||
0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
|
||||
0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
|
||||
0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
|
||||
0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
||||
};
|
||||
|
||||
static const uint32_t ftable[256] = {
|
||||
0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6,
|
||||
0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591,
|
||||
0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56,
|
||||
0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec,
|
||||
0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa,
|
||||
0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb,
|
||||
0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45,
|
||||
0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b,
|
||||
0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c,
|
||||
0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83,
|
||||
0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9,
|
||||
0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a,
|
||||
0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d,
|
||||
0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f,
|
||||
0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df,
|
||||
0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea,
|
||||
0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34,
|
||||
0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b,
|
||||
0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d,
|
||||
0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413,
|
||||
0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1,
|
||||
0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6,
|
||||
0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972,
|
||||
0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85,
|
||||
0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed,
|
||||
0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511,
|
||||
0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe,
|
||||
0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b,
|
||||
0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05,
|
||||
0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1,
|
||||
0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142,
|
||||
0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf,
|
||||
0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3,
|
||||
0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e,
|
||||
0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a,
|
||||
0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6,
|
||||
0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3,
|
||||
0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b,
|
||||
0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428,
|
||||
0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad,
|
||||
0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14,
|
||||
0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8,
|
||||
0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4,
|
||||
0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2,
|
||||
0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda,
|
||||
0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949,
|
||||
0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf,
|
||||
0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810,
|
||||
0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c,
|
||||
0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697,
|
||||
0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e,
|
||||
0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f,
|
||||
0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc,
|
||||
0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c,
|
||||
0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969,
|
||||
0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27,
|
||||
0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122,
|
||||
0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433,
|
||||
0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9,
|
||||
0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5,
|
||||
0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a,
|
||||
0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0,
|
||||
0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e,
|
||||
0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c
|
||||
};
|
||||
|
||||
static const uint32_t Rconst[12] = {
|
||||
0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#include "stdint.h"
|
||||
extern const uint32_t ftable[];
|
||||
|
||||
#endif
|
|
@ -0,0 +1,311 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "RiotBase64.h"
|
||||
|
||||
#define splitInt(intVal, bytePos) (char)((intVal >> (bytePos << 3)) & 0xFF)
|
||||
#define joinChars(a, b, c, d) (uint32_t)((uint32_t)a + \
|
||||
((uint32_t)b << 8) + \
|
||||
((uint32_t)c << 16) + \
|
||||
((uint32_t)d << 24))
|
||||
static char
|
||||
base64char(
|
||||
unsigned char Val
|
||||
)
|
||||
{
|
||||
if (Val < 26)
|
||||
{
|
||||
return 'A' + (char)Val;
|
||||
}
|
||||
else if (Val < 52)
|
||||
{
|
||||
return 'a' + ((char)Val - 26);
|
||||
}
|
||||
else if (Val < 62)
|
||||
{
|
||||
return '0' + ((char)Val - 52);
|
||||
}
|
||||
else if (Val == 62)
|
||||
{
|
||||
return '+';
|
||||
}
|
||||
else
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
}
|
||||
|
||||
static char
|
||||
base64b16(
|
||||
unsigned char Val
|
||||
)
|
||||
{
|
||||
const uint32_t base64b16values[4] = {
|
||||
joinChars('A', 'E', 'I', 'M'),
|
||||
joinChars('Q', 'U', 'Y', 'c'),
|
||||
joinChars('g', 'k', 'o', 's'),
|
||||
joinChars('w', '0', '4', '8')
|
||||
};
|
||||
return splitInt(base64b16values[Val >> 2], (Val & 0x03));
|
||||
}
|
||||
|
||||
static char
|
||||
base64b8(
|
||||
unsigned char Val
|
||||
)
|
||||
{
|
||||
const uint32_t base64b8values = joinChars('A', 'Q', 'g', 'w');
|
||||
return splitInt(base64b8values, Val);
|
||||
}
|
||||
|
||||
static int
|
||||
base64toValue(
|
||||
char Base64Character,
|
||||
unsigned char *Val
|
||||
)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (('A' <= Base64Character) && (Base64Character <= 'Z'))
|
||||
{
|
||||
*Val = Base64Character - 'A';
|
||||
}
|
||||
else if (('a' <= Base64Character) && (Base64Character <= 'z'))
|
||||
{
|
||||
*Val = ('Z' - 'A') + 1 + (Base64Character - 'a');
|
||||
}
|
||||
else if (('0' <= Base64Character) && (Base64Character <= '9'))
|
||||
{
|
||||
*Val = ('Z' - 'A') + 1 + ('z' - 'a') + 1 + (Base64Character - '0');
|
||||
}
|
||||
else if ('+' == Base64Character)
|
||||
{
|
||||
*Val = 62;
|
||||
}
|
||||
else if ('/' == Base64Character)
|
||||
{
|
||||
*Val = 63;
|
||||
}
|
||||
else
|
||||
{
|
||||
*Val = 0;
|
||||
result = -1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
base64CharacterCount(
|
||||
const char *EncodedString
|
||||
)
|
||||
{
|
||||
uint32_t length = 0;
|
||||
unsigned char junkChar;
|
||||
|
||||
while (base64toValue(EncodedString[length], &junkChar) != -1)
|
||||
{
|
||||
length++;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
Base64DecodedLength(
|
||||
const char *EncodedString
|
||||
)
|
||||
// Returns the count of original bytes before being base64 encoded. Notice
|
||||
// NO validation of the content of encodedString. Its length is validated
|
||||
// to be a multiple of 4.
|
||||
{
|
||||
uint32_t length = (uint32_t)strlen(EncodedString);
|
||||
uint32_t result;
|
||||
|
||||
if (length == 0)
|
||||
{
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = length / 4 * 3;
|
||||
if (EncodedString[length - 1] == '=')
|
||||
{
|
||||
if (EncodedString[length - 2] == '=')
|
||||
{
|
||||
result --;
|
||||
}
|
||||
result--;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
Base64Decode(
|
||||
const char *Input,
|
||||
unsigned char *Output,
|
||||
uint32_t *OutLen
|
||||
)
|
||||
{
|
||||
uint32_t charsRemaining, reqLen;
|
||||
uint32_t encodedIndex = 0;
|
||||
uint32_t decodedIndex = 0;
|
||||
|
||||
// Parameter validation
|
||||
if (!(Input) || !(Output) || !(OutLen)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Validate length of source string
|
||||
if ((strlen(Input) % 4) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Validate output buffer length
|
||||
reqLen = Base64DecodedLength(Input);
|
||||
if (*OutLen < reqLen) {
|
||||
*OutLen = reqLen;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Encoded character count
|
||||
charsRemaining = base64CharacterCount(Input);
|
||||
|
||||
// We can only operate on individual bytes. If we attempt to work on
|
||||
// anything larger we could get an alignment fault on some architectures.
|
||||
while (charsRemaining >= 4)
|
||||
{
|
||||
unsigned char c1;
|
||||
unsigned char c2;
|
||||
unsigned char c3;
|
||||
unsigned char c4;
|
||||
|
||||
(void)base64toValue(Input[encodedIndex], &c1);
|
||||
(void)base64toValue(Input[encodedIndex + 1], &c2);
|
||||
(void)base64toValue(Input[encodedIndex + 2], &c3);
|
||||
(void)base64toValue(Input[encodedIndex + 3], &c4);
|
||||
|
||||
Output[decodedIndex++] = (c1 << 2) | (c2 >> 4);
|
||||
Output[decodedIndex++] = ((c2 & 0x0f) << 4) | (c3 >> 2);
|
||||
Output[decodedIndex++] = ((c3 & 0x03) << 6) | c4;
|
||||
|
||||
charsRemaining -= 4;
|
||||
encodedIndex += 4;
|
||||
}
|
||||
|
||||
if (charsRemaining == 3)
|
||||
{
|
||||
unsigned char c1;
|
||||
unsigned char c2;
|
||||
unsigned char c3;
|
||||
|
||||
(void)base64toValue(Input[encodedIndex], &c1);
|
||||
(void)base64toValue(Input[encodedIndex + 1], &c2);
|
||||
(void)base64toValue(Input[encodedIndex + 2], &c3);
|
||||
|
||||
Output[decodedIndex++] = (c1 << 2) | (c2 >> 4);
|
||||
Output[decodedIndex] = ((c2 & 0x0f) << 4) | (c3 >> 2);
|
||||
}
|
||||
else if (charsRemaining == 2)
|
||||
{
|
||||
unsigned char c1;
|
||||
unsigned char c2;
|
||||
|
||||
(void)base64toValue(Input[encodedIndex], &c1);
|
||||
(void)base64toValue(Input[encodedIndex + 1], &c2);
|
||||
|
||||
Output[decodedIndex] = (c1 << 2) | (c2 >> 4);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Base64Encode(
|
||||
const unsigned char *Input,
|
||||
uint32_t Length,
|
||||
char *Output,
|
||||
uint32_t *OutLen
|
||||
)
|
||||
// The data in Input is processed 3 characters at a time to produce 4 base64
|
||||
// encoded characters for as long as there are more than 3 characters still to
|
||||
// process. The remaining characters (1 or 2) shall be then encoded. This
|
||||
// assumes that 'a' corresponds to 0b000000 and that '_' corresponds to
|
||||
// 0b111111. It will use the optional [=] or [==] at the end of the encoded
|
||||
// string, so that other less standard aware libraries can do their work.
|
||||
{
|
||||
uint32_t reqSize;
|
||||
uint32_t curPos = 0;
|
||||
uint32_t dstPos = 0;
|
||||
|
||||
// Parameter validation
|
||||
if (!(Input) || !(Output)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Calculate required output buffer length in bytes
|
||||
reqSize = (Length == 0) ? (0) : ((((Length - 1) / 3) + 1) * 4);
|
||||
|
||||
// Plus trailing NULL
|
||||
reqSize += 1;
|
||||
|
||||
// Validate length of output buffer
|
||||
if (OutLen && (*OutLen < reqSize)) {
|
||||
*OutLen = reqSize;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Perform encoding
|
||||
// b0 b1(+1) b2(+2)
|
||||
// 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
|
||||
// |----c1---| |----c2---| |----c3---| |----c4---|
|
||||
while (Length - curPos >= 3)
|
||||
{
|
||||
char c1 = base64char(Input[curPos] >> 2);
|
||||
char c2 = base64char(((Input[curPos] & 3) << 4) |
|
||||
(Input[curPos + 1] >> 4));
|
||||
char c3 = base64char(((Input[curPos + 1] & 0x0F) << 2) |
|
||||
((Input[curPos + 2] >> 6) & 3));
|
||||
char c4 = base64char(Input[curPos + 2] & 0x3F);
|
||||
|
||||
curPos += 3;
|
||||
Output[dstPos++] = c1;
|
||||
Output[dstPos++] = c2;
|
||||
Output[dstPos++] = c3;
|
||||
Output[dstPos++] = c4;
|
||||
|
||||
}
|
||||
|
||||
if (Length - curPos == 2)
|
||||
{
|
||||
char c1 = base64char(Input[curPos] >> 2);
|
||||
char c2 = base64char(((Input[curPos] & 0x03) << 4) |
|
||||
(Input[curPos + 1] >> 4));
|
||||
char c3 = base64b16(Input[curPos + 1] & 0x0F);
|
||||
|
||||
Output[dstPos++] = c1;
|
||||
Output[dstPos++] = c2;
|
||||
Output[dstPos++] = c3;
|
||||
Output[dstPos++] = '=';
|
||||
}
|
||||
else if (Length - curPos == 1)
|
||||
{
|
||||
char c1 = base64char(Input[curPos] >> 2);
|
||||
char c2 = base64b8(Input[curPos] & 0x03);
|
||||
|
||||
Output[dstPos++] = c1;
|
||||
Output[dstPos++] = c2;
|
||||
Output[dstPos++] = '=';
|
||||
Output[dstPos++] = '=';
|
||||
}
|
||||
|
||||
// Add NL termination
|
||||
Output[dstPos] = '\n';
|
||||
|
||||
// Output buffer length
|
||||
if (OutLen) {
|
||||
*OutLen = reqSize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,361 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#include "RiotCrypt.h"
|
||||
|
||||
#define RIOT_MAX_KDF_FIXED_SIZE RIOT_MAX_KDF_CONTEXT_LENGTH + \
|
||||
RIOT_MAX_KDF_LABEL_LENGTH + 5
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Kdf(
|
||||
uint8_t *result, // OUT: Buffer to receive the derived bytes
|
||||
size_t resultSize, // IN: Capacity of the result buffer
|
||||
const uint8_t *source, // IN: Initial data for derivation
|
||||
size_t sourceSize, // IN: Size of the source data in bytes
|
||||
const uint8_t *context, // IN: Derivation context (may be NULL)
|
||||
size_t contextSize, // IN: Size of the context in bytes
|
||||
const uint8_t *label, // IN: Label for derivation (may be NULL)
|
||||
size_t labelSize, // IN: Size of the label in bytes
|
||||
uint32_t bytesToDerive // IN: Number of bytesto be produced
|
||||
)
|
||||
{
|
||||
uint8_t fixed[RIOT_MAX_KDF_FIXED_SIZE];
|
||||
size_t fixedSize = sizeof(fixed);
|
||||
uint32_t counter = 0;
|
||||
|
||||
if (contextSize > RIOT_MAX_KDF_CONTEXT_LENGTH ||
|
||||
labelSize > RIOT_MAX_KDF_LABEL_LENGTH ||
|
||||
bytesToDerive > resultSize ||
|
||||
bytesToDerive % RIOT_KEY_LENGTH != 0) {
|
||||
return RIOT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
RIOT_KDF_FIXED(fixed, fixedSize, context, contextSize,
|
||||
label, labelSize, bytesToDerive * 8);
|
||||
|
||||
while (counter < (bytesToDerive / (RIOT_KEY_LENGTH))) {
|
||||
|
||||
RIOT_KDF_SHA256(result + (counter * (RIOT_KEY_LENGTH)),
|
||||
source, sourceSize, &counter,
|
||||
fixed, fixedSize);
|
||||
}
|
||||
|
||||
return RIOT_SUCCESS;
|
||||
}
|
||||
|
||||
typedef RIOT_SHA256_CONTEXT RIOT_HASH_CONTEXT;
|
||||
|
||||
#define RiotCrypt_HashInit RIOT_SHA256_Init
|
||||
#define RiotCrypt_HashUpdate RIOT_SHA256_Update
|
||||
#define RiotCrypt_HashFinal RIOT_SHA256_Final
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Hash(
|
||||
uint8_t *result, // OUT: Buffer to receive the digest
|
||||
size_t resultSize, // IN: Capacity of the result buffer
|
||||
const void *data, // IN: Data to hash
|
||||
size_t dataSize // IN: Data size in bytes
|
||||
)
|
||||
{
|
||||
RIOT_HASH_CONTEXT ctx;
|
||||
|
||||
if (resultSize < RIOT_DIGEST_LENGTH) {
|
||||
return RIOT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
RiotCrypt_HashInit(&ctx);
|
||||
RiotCrypt_HashUpdate(&ctx, data, dataSize);
|
||||
RiotCrypt_HashFinal(&ctx, result);
|
||||
|
||||
return RIOT_SUCCESS;
|
||||
}
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Hash2(
|
||||
uint8_t *result, // OUT: Buffer to receive the digest
|
||||
size_t resultSize, // IN: Capacity of the result buffer
|
||||
const void *data1, // IN: 1st operand to hash
|
||||
size_t data1Size, // IN: 1st operand size in bytes
|
||||
const void *data2, // IN: 2nd operand to hash
|
||||
size_t data2Size // IN: 2nd operand size in bytes
|
||||
)
|
||||
{
|
||||
RIOT_HASH_CONTEXT ctx;
|
||||
|
||||
if (resultSize < RIOT_DIGEST_LENGTH) {
|
||||
return RIOT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
RiotCrypt_HashInit(&ctx);
|
||||
RiotCrypt_HashUpdate(&ctx, data1, data1Size);
|
||||
RiotCrypt_HashUpdate(&ctx, data2, data2Size);
|
||||
RiotCrypt_HashFinal(&ctx, result);
|
||||
|
||||
return RIOT_SUCCESS;
|
||||
}
|
||||
|
||||
typedef RIOT_HMAC_SHA256_CTX RIOT_HMAC_CONTEXT;
|
||||
|
||||
#define RiotCrypt_HmacInit RIOT_HMAC_SHA256_Init
|
||||
#define RiotCrypt_HmacUpdate RIOT_HMAC_SHA256_Update
|
||||
#define RiotCrypt_HmacFinal RIOT_HMAC_SHA256_Final
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Hmac(
|
||||
uint8_t *result, // OUT: Buffer to receive the HMAC
|
||||
size_t resultCapacity, // IN: Capacity of the result buffer
|
||||
const void *data, // IN: Data to HMAC
|
||||
size_t dataSize, // IN: Data size in bytes
|
||||
const uint8_t *key, // IN: HMAK key
|
||||
size_t keySize // IN: HMAC key size in bytes
|
||||
)
|
||||
{
|
||||
RIOT_HMAC_CONTEXT ctx;
|
||||
|
||||
if (resultCapacity < RIOT_HMAC_LENGTH ||
|
||||
keySize != RIOT_HMAC_LENGTH) {
|
||||
return RIOT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
RiotCrypt_HmacInit(&ctx, key, keySize);
|
||||
RiotCrypt_HmacUpdate(&ctx, data, dataSize);
|
||||
RiotCrypt_HmacFinal(&ctx, result);
|
||||
|
||||
return RIOT_SUCCESS;
|
||||
}
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Hmac2(
|
||||
uint8_t *result, // OUT: Buffer to receive the HMAK
|
||||
size_t resultCapacity, // IN: Capacity of the result buffer
|
||||
const void *data1, // IN: 1st operand to HMAC
|
||||
size_t data1Size, // IN: 1st operand size in bytes
|
||||
const void *data2, // IN: 2nd operand to HMAC
|
||||
size_t data2Size, // IN: 2nd operand size in bytes
|
||||
const uint8_t *key, // IN: HMAK key
|
||||
size_t keySize // IN: HMAC key size in bytes
|
||||
)
|
||||
{
|
||||
RIOT_HMAC_CONTEXT ctx;
|
||||
|
||||
if (resultCapacity < RIOT_HMAC_LENGTH ||
|
||||
keySize != RIOT_HMAC_LENGTH) {
|
||||
return RIOT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
RiotCrypt_HmacInit(&ctx, key, keySize);
|
||||
RiotCrypt_HmacUpdate(&ctx, data1, data1Size);
|
||||
RiotCrypt_HmacUpdate(&ctx, data2, data2Size);
|
||||
RiotCrypt_HmacFinal(&ctx, result);
|
||||
|
||||
return RIOT_SUCCESS;
|
||||
}
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_DeriveEccKey(
|
||||
RIOT_ECC_PUBLIC *publicPart, // OUT: TODO
|
||||
RIOT_ECC_PRIVATE *privatePart, // OUT: TODO
|
||||
const void *srcData, // IN: TODO
|
||||
size_t srcDataSize, // IN: TODO
|
||||
const uint8_t *label, // IN: TODO
|
||||
size_t labelSize // IN: TODO
|
||||
)
|
||||
{
|
||||
bigval_t srcVal, *pSrcVal;
|
||||
|
||||
if (srcDataSize > sizeof(bigval_t)) {
|
||||
return RIOT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (srcDataSize == sizeof(bigval_t)) {
|
||||
pSrcVal = (bigval_t *)srcData;
|
||||
} else {
|
||||
memcpy(&srcVal, srcData, srcDataSize);
|
||||
pSrcVal = &srcVal;
|
||||
}
|
||||
|
||||
return RIOT_DeriveDsaKeyPair(publicPart, privatePart,
|
||||
pSrcVal, label, labelSize);
|
||||
}
|
||||
|
||||
void
|
||||
RiotCrypt_ExportEccPub(
|
||||
RIOT_ECC_PUBLIC *a, // IN: TODO
|
||||
uint8_t *b, // OUT: TODO
|
||||
uint32_t *s // OUT: TODO
|
||||
)
|
||||
{
|
||||
*b++ = 0x04;
|
||||
BigValToBigInt(b, &a->x);
|
||||
b += RIOT_ECC_COORD_BYTES;
|
||||
BigValToBigInt(b, &a->y);
|
||||
if (s) {
|
||||
*s = 1 + 2 * RIOT_ECC_COORD_BYTES;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Sign(
|
||||
RIOT_ECC_SIGNATURE *sig, // OUT: TODO
|
||||
const void *data, // IN: TODO
|
||||
size_t dataSize, // IN: TODO
|
||||
const RIOT_ECC_PRIVATE *key // IN: TODO
|
||||
)
|
||||
{
|
||||
uint8_t digest[RIOT_DIGEST_LENGTH];
|
||||
|
||||
RiotCrypt_Hash(digest, sizeof(digest), data, dataSize);
|
||||
|
||||
return RIOT_DSASignDigest(digest, key, sig);
|
||||
}
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_SignDigest(
|
||||
RIOT_ECC_SIGNATURE *sig, // OUT: TODO
|
||||
const uint8_t *digest, // IN: TODO
|
||||
size_t digestSize, // IN: TODO
|
||||
const RIOT_ECC_PRIVATE *key // IN: TODO
|
||||
)
|
||||
{
|
||||
if (digestSize != RIOT_DIGEST_LENGTH) {
|
||||
return RIOT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return RIOT_DSASignDigest(digest, key, sig);
|
||||
}
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Verify(
|
||||
const void *data, // IN: TODO
|
||||
size_t dataSize, // IN: TODO
|
||||
const RIOT_ECC_SIGNATURE *sig, // IN: TODO
|
||||
const RIOT_ECC_PUBLIC *key // IN: TODO
|
||||
)
|
||||
{
|
||||
uint8_t digest[RIOT_DIGEST_LENGTH];
|
||||
|
||||
RiotCrypt_Hash(digest, sizeof(digest), data, dataSize);
|
||||
|
||||
return RIOT_DSAVerifyDigest(digest, sig, key);
|
||||
}
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_VerifyDigest(
|
||||
const uint8_t *digest, // IN: TODO
|
||||
size_t digestSize, // IN: TODO
|
||||
const RIOT_ECC_SIGNATURE *sig, // IN: TODO
|
||||
const RIOT_ECC_PUBLIC *key // IN: TODO
|
||||
)
|
||||
{
|
||||
if (digestSize != RIOT_DIGEST_LENGTH) {
|
||||
return RIOT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return RIOT_DSAVerifyDigest(digest, sig, key);
|
||||
}
|
||||
|
||||
#define RIOT_LABEL_EXCHANGE_KEY "RiotExchange"
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_EccEncrypt(
|
||||
uint8_t *result, // OUT: Buffer to receive encrypted data
|
||||
size_t resultCapacity, // IN: Capacity of the result buffer
|
||||
RIOT_ECC_PUBLIC *ephKey, // OUT: Ephemeral key to produce
|
||||
const void *data, // IN: Data to encrypt
|
||||
size_t dataSize, // IN: Data size in bytes
|
||||
const RIOT_ECC_PUBLIC *key // IN: Encryption key
|
||||
)
|
||||
{
|
||||
ecc_privatekey ephPriv;
|
||||
ecc_secret secret;
|
||||
uint8_t exchKey[RIOT_KEY_LENGTH];
|
||||
RIOT_STATUS status;
|
||||
|
||||
status = RIOT_GenerateDHKeyPair(ephKey, &ephPriv);
|
||||
|
||||
if (status != RIOT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = RIOT_GenerateShareSecret((RIOT_ECC_PUBLIC *)key, &ephPriv, &secret);
|
||||
|
||||
if (status != RIOT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = RiotCrypt_Kdf(exchKey, sizeof(exchKey),
|
||||
(uint8_t *)&secret, sizeof(secret),
|
||||
NULL, 0, (const uint8_t*)RIOT_LABEL_EXCHANGE_KEY,
|
||||
(sizeof(RIOT_LABEL_EXCHANGE_KEY) - 1),
|
||||
sizeof(exchKey));
|
||||
|
||||
if (status != RIOT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = RiotCrypt_SymEncryptDecrypt(result, resultCapacity,
|
||||
data, dataSize, exchKey);
|
||||
return status;
|
||||
}
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_EccDecrypt(
|
||||
uint8_t *result, // OUT: Buffer to receive decrypted data
|
||||
size_t resultCapacity, // IN: Capacity of the result buffer
|
||||
const void *data, // IN: Data to decrypt
|
||||
size_t dataSize, // IN: Data size in bytes
|
||||
RIOT_ECC_PUBLIC *ephKey, // IN: Ephemeral key to produce
|
||||
const RIOT_ECC_PRIVATE *key // IN: Decryption key
|
||||
)
|
||||
{
|
||||
ecc_secret secret;
|
||||
uint8_t exchKey[RIOT_KEY_LENGTH];
|
||||
RIOT_STATUS status;
|
||||
|
||||
status = RIOT_GenerateShareSecret(ephKey, (RIOT_ECC_PRIVATE *)key, &secret);
|
||||
|
||||
if (status != RIOT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = RiotCrypt_Kdf(exchKey, sizeof(exchKey),
|
||||
(uint8_t *)&secret, sizeof(secret),
|
||||
NULL, 0, (const uint8_t*)RIOT_LABEL_EXCHANGE_KEY,
|
||||
(sizeof(RIOT_LABEL_EXCHANGE_KEY) - 1),
|
||||
sizeof(exchKey));
|
||||
|
||||
if (status != RIOT_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = RiotCrypt_SymEncryptDecrypt(result, resultCapacity,
|
||||
data, dataSize, exchKey);
|
||||
return status;
|
||||
}
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_SymEncryptDecrypt(
|
||||
void *outData, // OUT: Output data
|
||||
size_t outSize, // IN: Size of output data
|
||||
const void *inData, // IN: Input data
|
||||
size_t inSize, // IN: Size of input data
|
||||
uint8_t key[RIOT_SYM_KEY_LENGTH] // IN/OUT: Symmetric key & IV
|
||||
)
|
||||
{
|
||||
uint8_t *iv = key + 16;
|
||||
aes128EncryptKey_t aesKey;
|
||||
|
||||
if (outSize < inSize) {
|
||||
return RIOT_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
RIOT_AES128_Enable(key, &aesKey);
|
||||
RIOT_AES_CTR_128((const aes128EncryptKey_t*) &aesKey, inData, outData, (uint32_t)inSize, iv);
|
||||
RIOT_AES128_Disable(&aesKey);
|
||||
|
||||
return RIOT_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,603 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <winsock2.h> // TODO: REMOVE THIS
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#include "RiotDerEnc.h"
|
||||
#include "RiotBase64.h"
|
||||
|
||||
//
|
||||
// This file contains basic DER-encoding routines that are sufficient to create
|
||||
// RIoT X.509 certificates. A few corners are cut (and noted) in the interests
|
||||
// of small code footprint and simplicity.
|
||||
//
|
||||
// Routines in this file encode the following types:
|
||||
// SEQUENCE
|
||||
// SET
|
||||
// INTEGER
|
||||
// OID
|
||||
// BOOL
|
||||
// PrintableString
|
||||
// UTF8String
|
||||
// UTCTime
|
||||
//
|
||||
|
||||
// Assert-less assert
|
||||
#define ASRT(_X) if(!(_X)) {goto Error;}
|
||||
|
||||
// The encoding routines need to check that the encoded data will fit in the
|
||||
// buffer. The following macros do (conservative) checks because it's hard to
|
||||
// properly test low-buffer situations. CHECK_SPACE is appropriate for short
|
||||
// additions. CHECK_SPACE2 when larger objects are being added (and the length
|
||||
// is known.)
|
||||
#define CHECK_SPACE(_X) if((_X->Length-_X->Position)<32) {goto Error;}
|
||||
#define CHECK_SPACE2(_X, _N) if(((_X->Length-_X->Position)+(_N))<32) {goto Error;}
|
||||
|
||||
static int
|
||||
GetIntEncodedNumBytes(
|
||||
int Val
|
||||
)
|
||||
// Returns the number of bytes needed to DER encode a number. If the number
|
||||
// is less then 127, a single byte is used. Otherwise the DER rule is first
|
||||
// byte is 0x80|NumBytes, followed by the number in network byte-order. Note
|
||||
// that the routines in this library only handle lengths up to 16K Bytes.
|
||||
{
|
||||
ASRT(Val < 166536);
|
||||
if (Val < 128) {
|
||||
return 1;
|
||||
}
|
||||
if (Val < 256) {
|
||||
return 2;
|
||||
}
|
||||
return 3;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
EncodeInt(
|
||||
uint8_t *Buffer,
|
||||
int Val
|
||||
)
|
||||
// DER-encode Val into buffer. Function assumes the caller knows how many
|
||||
// bytes it will need (e.g., from GetIntEncodedNumBytes).
|
||||
{
|
||||
ASRT(Val < 166536);
|
||||
if (Val <128) {
|
||||
Buffer[0] = (uint8_t)Val;
|
||||
return 0;
|
||||
}
|
||||
if (Val < 256) {
|
||||
Buffer[0] = 0x81;
|
||||
Buffer[1] = (uint8_t)Val;
|
||||
return 0;
|
||||
}
|
||||
Buffer[0] = 0x82;
|
||||
Buffer[1] = (uint8_t)(Val / 256);
|
||||
Buffer[2] = Val % 256;
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
DERInitContext(
|
||||
DERBuilderContext *Context,
|
||||
uint8_t *Buffer,
|
||||
uint32_t Length
|
||||
)
|
||||
// Intialize the builder context. The caller manages the encoding buffer.
|
||||
// Note that the encoding routines do conservative checks that the encoding
|
||||
// will fit, so approximately 30 extra bytes are needed. Note that if an
|
||||
// encoding routine fails because the buffer is too small, the buffer will
|
||||
// be in an indeterminate state, and the encoding must be restarted.
|
||||
{
|
||||
int j;
|
||||
Context->Buffer = Buffer;
|
||||
Context->Length = Length;
|
||||
Context->Position = 0;
|
||||
memset(Buffer, 0, Length);
|
||||
for (j = 0; j < DER_MAX_NESTED; j++) {
|
||||
Context->CollectionStart[j] = -1;
|
||||
}
|
||||
Context->CollectionPos = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
DERGetEncodedLength(
|
||||
DERBuilderContext *Context
|
||||
)
|
||||
// Get the length of encoded data.
|
||||
{
|
||||
return Context->Position;
|
||||
}
|
||||
|
||||
int
|
||||
DERAddOID(
|
||||
DERBuilderContext *Context,
|
||||
int *Values
|
||||
)
|
||||
// Add an OID. The OID is an int-array (max 16) terminated with -1
|
||||
{
|
||||
int j, k;
|
||||
int lenPos, digitPos = 0;
|
||||
int val, digit;
|
||||
int numValues = 0;
|
||||
uint8_t digits[5];
|
||||
|
||||
for (j = 0; j < 16; j++) {
|
||||
if (Values[j] < 0) {
|
||||
break;
|
||||
}
|
||||
numValues++;
|
||||
}
|
||||
|
||||
// Sanity check
|
||||
ASRT(numValues < 16);
|
||||
|
||||
// Note that we don't know how many bytes the actual encoding will be
|
||||
// so we also check as we fill the buffer.
|
||||
CHECK_SPACE(Context);
|
||||
Context->Buffer[Context->Position++] = 6;
|
||||
|
||||
// Save space for length (only <128 supported)
|
||||
lenPos = Context->Position;
|
||||
Context->Position++;
|
||||
|
||||
// DER-encode the OID, first octet is special
|
||||
val = numValues == 1 ? 0 : Values[1];
|
||||
Context->Buffer[Context->Position++] = (uint8_t)(Values[0] * 40 + val);
|
||||
|
||||
// Others are base-128 encoded with the most significant bit of each byte,
|
||||
// apart from the least significant byte, set to 1.
|
||||
if (numValues >= 2) {
|
||||
for (j = 2; j < numValues; j++) {
|
||||
digitPos = 0;
|
||||
val = Values[j];
|
||||
|
||||
// Convert to B128
|
||||
while (true) {
|
||||
digit = val % 128;
|
||||
digits[digitPos++] = (uint8_t)digit;
|
||||
val = val / 128;
|
||||
if (val == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Reverse into the buffer, setting the MSB as needed.
|
||||
for (k = digitPos - 1; k >= 0; k--) {
|
||||
val = digits[k];
|
||||
if (k != 0) {
|
||||
val += 128;
|
||||
}
|
||||
Context->Buffer[Context->Position++] = (uint8_t)val;
|
||||
}
|
||||
CHECK_SPACE(Context);
|
||||
}
|
||||
}
|
||||
|
||||
Context->Buffer[lenPos] = (uint8_t)(Context->Position - 1 - lenPos);
|
||||
return 0;
|
||||
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DERAddUTF8String(
|
||||
DERBuilderContext *Context,
|
||||
const char *Str
|
||||
)
|
||||
{
|
||||
uint32_t j, numChar = (uint32_t)strlen(Str);
|
||||
|
||||
ASRT(numChar < 127);
|
||||
CHECK_SPACE2(Context, numChar);
|
||||
|
||||
Context->Buffer[Context->Position++] = 0x0c;
|
||||
Context->Buffer[Context->Position++] = (uint8_t)numChar;
|
||||
|
||||
for (j = 0; j < numChar; j++) {
|
||||
Context->Buffer[Context->Position++] = Str[j];
|
||||
}
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DERAddPrintableString(
|
||||
DERBuilderContext *Context,
|
||||
const char *Str
|
||||
)
|
||||
{
|
||||
uint32_t j, numChar = (uint32_t)strlen(Str);
|
||||
|
||||
ASRT(numChar < 127);
|
||||
CHECK_SPACE2(Context, numChar);
|
||||
|
||||
Context->Buffer[Context->Position++] = 0x13;
|
||||
Context->Buffer[Context->Position++] = (uint8_t)numChar;
|
||||
|
||||
for (j = 0; j < numChar; j++) {
|
||||
Context->Buffer[Context->Position++] = Str[j];
|
||||
}
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DERAddUTCTime(
|
||||
DERBuilderContext *Context,
|
||||
const char *Str
|
||||
)
|
||||
// Format of time MUST be YYMMDDhhmmssZ
|
||||
{
|
||||
uint32_t j, numChar = (uint32_t)strlen(Str);
|
||||
|
||||
ASRT(numChar == 13);
|
||||
CHECK_SPACE(Context);
|
||||
|
||||
Context->Buffer[Context->Position++] = 0x17;
|
||||
Context->Buffer[Context->Position++] = (uint8_t)numChar;
|
||||
|
||||
for (j = 0; j < numChar; j++) {
|
||||
Context->Buffer[Context->Position++] = Str[j];
|
||||
}
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DERAddIntegerFromArray(
|
||||
DERBuilderContext *Context,
|
||||
uint8_t *Val,
|
||||
uint32_t NumBytes
|
||||
)
|
||||
// Input integer is assumed unsigned with most signficant byte first.
|
||||
// A leading zero will be added if the most significant input bit is set.
|
||||
// Leading zeros in the input number will be removed.
|
||||
{
|
||||
uint32_t j, numLeadingZeros = 0;
|
||||
bool negative;
|
||||
|
||||
ASRT(NumBytes < 128);
|
||||
CHECK_SPACE2(Context, NumBytes);
|
||||
|
||||
for (j = 0; j < NumBytes; j++) {
|
||||
if (Val[j] != 0) {
|
||||
break;
|
||||
}
|
||||
numLeadingZeros++;
|
||||
}
|
||||
|
||||
negative = Val[numLeadingZeros] >= 128;
|
||||
Context->Buffer[Context->Position++] = 0x02;
|
||||
|
||||
if (negative) {
|
||||
Context->Buffer[Context->Position++] = (uint8_t)(NumBytes - numLeadingZeros + 1);
|
||||
Context->Buffer[Context->Position++] = 0;
|
||||
} else {
|
||||
Context->Buffer[Context->Position++] = (uint8_t)(NumBytes - numLeadingZeros);
|
||||
}
|
||||
|
||||
for (j = numLeadingZeros; j < NumBytes; j++) {
|
||||
Context->Buffer[Context->Position++] = Val[j];
|
||||
}
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DERAddInteger(
|
||||
DERBuilderContext *Context,
|
||||
int Val
|
||||
)
|
||||
{
|
||||
long valx = htonl(Val); // TODO: REMOVE USAGE
|
||||
int res = DERAddIntegerFromArray(Context, (uint8_t*)&valx, 4);
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
DERAddShortExplicitInteger(
|
||||
DERBuilderContext *Context,
|
||||
int Val
|
||||
)
|
||||
{
|
||||
long valx;
|
||||
ASRT(Val < 127);
|
||||
|
||||
Context->Buffer[Context->Position++] = 0xA0;
|
||||
Context->Buffer[Context->Position++] = 3;
|
||||
|
||||
valx = htonl(Val);
|
||||
return (DERAddIntegerFromArray(Context, (uint8_t*)&valx, 4));
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DERAddBoolean(
|
||||
DERBuilderContext *Context,
|
||||
bool Val
|
||||
)
|
||||
{
|
||||
CHECK_SPACE(Context);
|
||||
Context->Buffer[Context->Position++] = 0x01;
|
||||
Context->Buffer[Context->Position++] = 0x01;
|
||||
if (Val) {
|
||||
Context->Buffer[Context->Position++] = 0xFF;
|
||||
} else {
|
||||
Context->Buffer[Context->Position++] = 0x00;
|
||||
}
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DERAddBitString(
|
||||
DERBuilderContext *Context,
|
||||
uint8_t *BitString,
|
||||
uint32_t BitStringNumBytes
|
||||
)
|
||||
{
|
||||
int len = BitStringNumBytes + 1;
|
||||
|
||||
CHECK_SPACE2(Context, BitStringNumBytes);
|
||||
Context->Buffer[Context->Position++] = 0x03;
|
||||
EncodeInt(Context->Buffer + Context->Position, len);
|
||||
Context->Position += GetIntEncodedNumBytes(len);
|
||||
Context->Buffer[Context->Position++] = 0;
|
||||
memcpy(Context->Buffer + Context->Position, BitString, BitStringNumBytes);
|
||||
Context->Position += BitStringNumBytes;
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DERAddOctetString(
|
||||
DERBuilderContext *Context,
|
||||
uint8_t *OctetString,
|
||||
uint32_t OctetStringLen
|
||||
)
|
||||
{
|
||||
CHECK_SPACE2(Context, OctetStringLen);
|
||||
Context->Buffer[Context->Position++] = 0x04;
|
||||
EncodeInt(Context->Buffer + Context->Position, OctetStringLen);
|
||||
Context->Position += GetIntEncodedNumBytes(OctetStringLen);
|
||||
memcpy(Context->Buffer + Context->Position, OctetString, OctetStringLen);
|
||||
Context->Position += OctetStringLen;
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
DERStartSequenceOrSet(
|
||||
DERBuilderContext *Context,
|
||||
bool Sequence
|
||||
)
|
||||
{
|
||||
uint8_t tp = Sequence ? 0x30 : 0x31;
|
||||
|
||||
CHECK_SPACE(Context);
|
||||
ASRT(Context->CollectionPos < DER_MAX_NESTED);
|
||||
|
||||
Context->Buffer[Context->Position++] = tp;
|
||||
|
||||
// Note that no space is left for the length field. The length field
|
||||
// is added at DEREndSequence when we know how many bytes are needed.
|
||||
Context->CollectionStart[Context->CollectionPos++] = Context->Position;
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DERStartExplicit(
|
||||
DERBuilderContext *Context,
|
||||
uint32_t Num
|
||||
)
|
||||
{
|
||||
CHECK_SPACE(Context);
|
||||
ASRT(Context->CollectionPos < DER_MAX_NESTED);
|
||||
|
||||
Context->Buffer[Context->Position++] = 0xA0 + (uint8_t)Num;
|
||||
Context->CollectionStart[Context->CollectionPos++] = Context->Position;
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
int
|
||||
DERStartEnvelopingOctetString(
|
||||
DERBuilderContext *Context
|
||||
)
|
||||
{
|
||||
CHECK_SPACE(Context);
|
||||
ASRT(Context->CollectionPos < DER_MAX_NESTED);
|
||||
|
||||
Context->Buffer[Context->Position++] = 0x04;
|
||||
Context->CollectionStart[Context->CollectionPos++] = Context->Position;
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DERStartEnvelopingBitString(
|
||||
DERBuilderContext *Context
|
||||
)
|
||||
{
|
||||
CHECK_SPACE(Context);
|
||||
ASRT(Context->CollectionPos < DER_MAX_NESTED);
|
||||
|
||||
Context->Buffer[Context->Position++] = 0x03;
|
||||
|
||||
// The payload includes the numUnusedBits (always zero, for our endodings).
|
||||
Context->CollectionStart[Context->CollectionPos++] = Context->Position;
|
||||
|
||||
// No unused bits
|
||||
Context->Buffer[Context->Position++] = 0;
|
||||
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DERPopNesting(
|
||||
DERBuilderContext *Context
|
||||
)
|
||||
{
|
||||
int startPos, numBytes, encodedLenSize;
|
||||
|
||||
CHECK_SPACE(Context);
|
||||
ASRT(Context->CollectionPos > 0);
|
||||
|
||||
startPos = Context->CollectionStart[--Context->CollectionPos];
|
||||
numBytes = Context->Position - startPos;
|
||||
|
||||
// How big is the length field?
|
||||
encodedLenSize = GetIntEncodedNumBytes(numBytes);
|
||||
|
||||
// Make space for the length
|
||||
memmove(Context->Buffer + startPos + encodedLenSize,
|
||||
Context->Buffer + startPos,
|
||||
numBytes);
|
||||
|
||||
// Fill in the length
|
||||
EncodeInt(Context->Buffer + startPos, numBytes);
|
||||
|
||||
// Bump up the next-pointer
|
||||
Context->Position += encodedLenSize;
|
||||
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
DERTbsToCert(
|
||||
DERBuilderContext *Context
|
||||
)
|
||||
// This function assumes that Context contains a fully-formed "to be signed"
|
||||
// region of a certificate. DERTbsToCert copies the existing TBS region into
|
||||
// an enclosing SEQUENCE. This prepares the context to receive the signature
|
||||
// block to make a fully-formed certificate.
|
||||
{
|
||||
ASRT(Context->CollectionPos == 0);
|
||||
CHECK_SPACE(Context);
|
||||
|
||||
// Move up one byte to leave room for the SEQUENCE tag.
|
||||
// The length is filled in when the sequence is popped.
|
||||
memmove(Context->Buffer + 1, Context->Buffer, Context->Position);
|
||||
|
||||
// Fix up the length
|
||||
Context->Position++;
|
||||
|
||||
// Add a sequence tag
|
||||
Context->Buffer[0] = 0x30;
|
||||
|
||||
// Push the sequence into the collection stack
|
||||
Context->CollectionStart[Context->CollectionPos++] = 1;
|
||||
|
||||
// Context now contains a TBS region inside a SEQUENCE. Signature block next.
|
||||
return 0;
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
DERGetNestingDepth(
|
||||
DERBuilderContext *Context
|
||||
)
|
||||
{
|
||||
return Context->CollectionPos;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16_t hLen;
|
||||
uint16_t fLen;
|
||||
const char *header;
|
||||
const char *footer;
|
||||
} PEMHeadersFooters;
|
||||
|
||||
// We only have a small subset of potential PEM encodings
|
||||
const PEMHeadersFooters PEMhf[LAST_CERT_TYPE] = {
|
||||
{28, 26, "-----BEGIN CERTIFICATE-----\n", "-----END CERTIFICATE-----\n"},
|
||||
{27, 25, "-----BEGIN PUBLIC KEY-----\n", "-----END PUBLIC KEY-----\n\0"},
|
||||
{31, 29, "-----BEGIN EC PRIVATE KEY-----\n", "-----END EC PRIVATE KEY-----\n"},
|
||||
{36, 34, "-----BEGIN CERTIFICATE REQUEST-----\n", "-----END CERTIFICATE REQUEST-----\n"}
|
||||
};
|
||||
|
||||
int
|
||||
DERtoPEM(
|
||||
DERBuilderContext *Context,
|
||||
uint32_t Type,
|
||||
char *PEM,
|
||||
uint32_t *Length
|
||||
)
|
||||
// Note that this function does not support extra header information for
|
||||
// encrypted keys. Expand the header buffer to ~128 bytes to support this.
|
||||
{
|
||||
uint32_t b64Len, reqLen;
|
||||
|
||||
// Parameter validation
|
||||
if (!(Context) || !(Type < LAST_CERT_TYPE) || !(PEM)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Calculate required length for output buffer
|
||||
b64Len = Base64Length(Context->Position);
|
||||
reqLen = b64Len + PEMhf[Type].hLen + PEMhf[Type].fLen;
|
||||
|
||||
// Validate length of output buffer
|
||||
if (Length && (*Length < reqLen)) {
|
||||
*Length = reqLen;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Place header
|
||||
memcpy(PEM, PEMhf[Type].header, PEMhf[Type].hLen);
|
||||
PEM += PEMhf[Type].hLen;
|
||||
|
||||
// Encode bytes
|
||||
Base64Encode(Context->Buffer, Context->Position, PEM, NULL);
|
||||
PEM += b64Len;
|
||||
|
||||
// Place footer
|
||||
memcpy(PEM, PEMhf[Type].footer, PEMhf[Type].fLen);
|
||||
PEM += PEMhf[Type].fLen;
|
||||
|
||||
// Output buffer length
|
||||
if (Length) {
|
||||
*Length = reqLen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,96 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2014, AllSeen Alliance. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT).
|
||||
//
|
||||
#include "RiotHmac.h"
|
||||
|
||||
void
|
||||
RIOT_HMAC_SHA256_Init(
|
||||
RIOT_HMAC_SHA256_CTX *ctx,
|
||||
const uint8_t *key,
|
||||
size_t keyLen
|
||||
)
|
||||
{
|
||||
size_t cnt;
|
||||
|
||||
assert(ctx && key);
|
||||
|
||||
// if keyLen > 64, hash it and use it as key
|
||||
if (keyLen > HMAC_SHA256_BLOCK_LENGTH) {
|
||||
RIOT_SHA256_Block_ctx(&ctx->hashCtx, key, keyLen, ctx->opad);
|
||||
keyLen = SHA256_DIGEST_LENGTH;
|
||||
} else {
|
||||
memcpy(ctx->opad, key, keyLen);
|
||||
}
|
||||
//
|
||||
// the HMAC_SHA256 process
|
||||
//
|
||||
// SHA256((K XOR opad) || SHA256((K XOR ipad) || msg))
|
||||
//
|
||||
// K is the key
|
||||
// ipad is filled with 0x36
|
||||
// opad is filled with 0x5c
|
||||
// msg is the message
|
||||
//
|
||||
|
||||
//
|
||||
// prepare inner hash SHA256((K XOR ipad) || msg)
|
||||
// K XOR ipad
|
||||
//
|
||||
for (cnt = 0; cnt < keyLen; cnt++) {
|
||||
ctx->opad[cnt] ^= 0x36;
|
||||
}
|
||||
memset(&ctx->opad[keyLen], 0x36, sizeof(ctx->opad) - keyLen);
|
||||
|
||||
RIOT_SHA256_Init(&ctx->hashCtx);
|
||||
RIOT_SHA256_Update(&ctx->hashCtx, ctx->opad, HMAC_SHA256_BLOCK_LENGTH);
|
||||
|
||||
// Turn ipad into opad
|
||||
for (cnt = 0; cnt < sizeof(ctx->opad); cnt++) {
|
||||
ctx->opad[cnt] ^= (0x5c ^ 0x36);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RIOT_HMAC_SHA256_Update(
|
||||
RIOT_HMAC_SHA256_CTX *ctx,
|
||||
const uint8_t *data,
|
||||
size_t dataLen
|
||||
)
|
||||
{
|
||||
RIOT_SHA256_Update(&ctx->hashCtx, data, dataLen);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
RIOT_HMAC_SHA256_Final(
|
||||
RIOT_HMAC_SHA256_CTX *ctx,
|
||||
uint8_t *digest
|
||||
)
|
||||
{
|
||||
// complete inner hash SHA256(K XOR ipad, msg)
|
||||
RIOT_SHA256_Final(&ctx->hashCtx, digest);
|
||||
|
||||
// perform outer hash SHA256(K XOR opad, SHA256(K XOR ipad, msg))
|
||||
RIOT_SHA256_Init(&ctx->hashCtx);
|
||||
RIOT_SHA256_Update(&ctx->hashCtx, ctx->opad, HMAC_SHA256_BLOCK_LENGTH);
|
||||
RIOT_SHA256_Update(&ctx->hashCtx, digest, SHA256_DIGEST_LENGTH);
|
||||
RIOT_SHA256_Final(&ctx->hashCtx, digest);
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2014, AllSeen Alliance. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT).
|
||||
//
|
||||
#include "stdint.h"
|
||||
#include "RiotKdf.h"
|
||||
|
||||
#if HOST_IS_LITTLE_ENDIAN
|
||||
#define UINT32_TO_BIGENDIAN(i) \
|
||||
( ((i) & 0xff000000ULL >> 24) \
|
||||
| ((i) & 0x00ff0000ULL >> 8) \
|
||||
| ((i) & 0x0000ff00ULL << 8) \
|
||||
| ((i) & 0x000000ffULL << 24))
|
||||
#else
|
||||
#define UINT32_TO_BIG_ENDIAN(i) (i)
|
||||
#endif
|
||||
#define UINT32_FROM_BIGENDIAN uint32_tO_BIGENDIAN
|
||||
|
||||
//
|
||||
// Create the fixed content for a KDF
|
||||
// @param fixed buffer to receive the fixed content
|
||||
// @param fixedSize indicates the available space in fixed
|
||||
// @param label the label parameter (optional)
|
||||
// @param labelSize
|
||||
// @param context the context value (optional)
|
||||
// @param contextSize
|
||||
// @param numberOfBits the number of bits to be produced
|
||||
//
|
||||
size_t RIOT_KDF_FIXED(
|
||||
uint8_t *fixed,
|
||||
size_t fixedSize,
|
||||
const uint8_t *label,
|
||||
size_t labelSize,
|
||||
const uint8_t *context,
|
||||
size_t contextSize,
|
||||
uint32_t numberOfBits
|
||||
)
|
||||
{
|
||||
size_t total = (((label) ? labelSize : 0) + ((context) ? contextSize : 0) + 5);
|
||||
|
||||
assert(fixedSize >= total);
|
||||
|
||||
if (label) {
|
||||
memcpy(fixed, label, labelSize);
|
||||
fixed += labelSize;
|
||||
}
|
||||
*fixed++ = 0;
|
||||
if (context) {
|
||||
memcpy(fixed, context, contextSize);
|
||||
fixed += contextSize;
|
||||
}
|
||||
numberOfBits = UINT32_TO_BIGENDIAN(numberOfBits);
|
||||
memcpy(fixed, &numberOfBits, 4);
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Do KDF from SP800-108 -- HMAC based counter mode. This function does a single
|
||||
// iteration. The counter parameter is incremented before it is used so that
|
||||
// a caller can set counter to 0 for the first iteration.
|
||||
// @param out the output digest of a single iteration (a SHA256 digest)
|
||||
// @param key the HMAC key
|
||||
// @param keySize
|
||||
// @param counter the running counter value (may be NULL)
|
||||
// @param fixed the label parameter (optional)
|
||||
// @param fixedSize
|
||||
//
|
||||
void RIOT_KDF_SHA256(
|
||||
uint8_t *out,
|
||||
const uint8_t *key,
|
||||
size_t keySize,
|
||||
uint32_t *counter,
|
||||
const uint8_t *fixed,
|
||||
size_t fixedSize
|
||||
)
|
||||
{
|
||||
RIOT_HMAC_SHA256_CTX ctx;
|
||||
uint32_t ctr = counter ? ++*counter : 1;
|
||||
|
||||
assert(out && key && fixed);
|
||||
|
||||
// Start the HMAC
|
||||
RIOT_HMAC_SHA256_Init(&ctx, key, keySize);
|
||||
// Add the counter
|
||||
ctr = UINT32_TO_BIGENDIAN(ctr);
|
||||
RIOT_HMAC_SHA256_Update(&ctx, (uint8_t *)&ctr, 4);
|
||||
// Add fixed stuff
|
||||
RIOT_HMAC_SHA256_Update(&ctx, fixed, fixedSize);
|
||||
RIOT_HMAC_SHA256_Final(&ctx, out);
|
||||
}
|
|
@ -0,0 +1,467 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2001, Aaron D. Gifford
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2014, AllSeen Alliance. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT).
|
||||
//
|
||||
#include "stdint.h"
|
||||
#include "string.h" // memcpy/memset
|
||||
#include "RiotSha256.h"
|
||||
|
||||
/*** SHA-256 Machine Architecture Definitions *****************/
|
||||
/*
|
||||
* BYTE_ORDER NOTE:
|
||||
*
|
||||
* Please make sure that your system defines BYTE_ORDER. If your
|
||||
* architecture is little-endian, make sure it also defines
|
||||
* LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are
|
||||
* equivilent.
|
||||
*
|
||||
* If your system does not define the above, then you can do so by
|
||||
* hand like this:
|
||||
*
|
||||
* #define LITTLE_ENDIAN 1234
|
||||
* #define BIG_ENDIAN 4321
|
||||
*
|
||||
* And for little-endian machines, add:
|
||||
*
|
||||
* #define BYTE_ORDER LITTLE_ENDIAN
|
||||
*
|
||||
* Or for big-endian machines:
|
||||
*
|
||||
* #define BYTE_ORDER BIG_ENDIAN
|
||||
*
|
||||
* The FreeBSD machine this was written on defines BYTE_ORDER
|
||||
* appropriately by including <sys/types.h> (which in turn includes
|
||||
* <machine/endian.h> where the appropriate definitions are actually
|
||||
* made).
|
||||
*/
|
||||
#if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN)
|
||||
#define LITTLE_ENDIAN 1234
|
||||
#define BIG_ENDIAN 4321
|
||||
#if HOST_IS_LITTLE_ENDIAN
|
||||
#define BYTE_ORDER LITTLE_ENDIAN
|
||||
#else
|
||||
#define BYTE_ORDER BIG_ENDIAN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define the followingsha2_* types to types of the correct length on
|
||||
* the native architecture. Most BSD systems and Linux define u_intXX_t
|
||||
* types. Machines with very recent ANSI C headers, can use the
|
||||
* uintXX_t definitions from inttypes.h by defining SHA2_USE_INTTYPES_H
|
||||
* during compile or in the sha.h header file.
|
||||
*
|
||||
* Machines that support neither u_intXX_t nor inttypes.h's uintXX_t
|
||||
* will need to define these three typedefs below (and the appropriate
|
||||
* ones in sha.h too) by hand according to their system architecture.
|
||||
*
|
||||
* Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t
|
||||
* types and pointing out recent ANSI C support for uintXX_t in inttypes.h.
|
||||
*/
|
||||
|
||||
/*** SHA-256 Length Definitions ***********************/
|
||||
/* NOTE: Most of these are in sha2.h */
|
||||
#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8)
|
||||
|
||||
/*** ENDIAN REVERSAL MACROS *******************************************/
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
#if !defined(ALIGNED_ACCESS_REQUIRED)
|
||||
#define REVERSE32(w,x) { \
|
||||
sha2_word32 tmp = (w); \
|
||||
tmp = (tmp >> 16) | (tmp << 16); \
|
||||
(x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \
|
||||
}
|
||||
#else
|
||||
#define REVERSE32(w,x) { \
|
||||
sha2_uint8_t *b = (sha2_uint8_t*) &w; \
|
||||
sha2_word32 tmp = 0; \
|
||||
tmp = ((sha2_word32)*b++); \
|
||||
tmp = (tmp << 8) | ((sha2_word32)*b++); \
|
||||
tmp = (tmp << 8) | ((sha2_word32)*b++); \
|
||||
tmp = (tmp << 8) | ((sha2_word32)*b++); \
|
||||
(x) = tmp; \
|
||||
}
|
||||
#endif /* ALIGNED_ACCESS_REQUIRED */
|
||||
#define REVERSE64(w,x) { \
|
||||
sha2_word64 tmp = (w); \
|
||||
tmp = (tmp >> 32) | (tmp << 32); \
|
||||
tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \
|
||||
((tmp & 0x00ff00ff00ff00ffULL) << 8); \
|
||||
(x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \
|
||||
((tmp & 0x0000ffff0000ffffULL) << 16); \
|
||||
}
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
|
||||
/*
|
||||
* Macro for incrementally adding the unsigned 64-bit integer n to the
|
||||
* unsigned 128-bit integer (represented using a two-element array of
|
||||
* 64-bit words):
|
||||
*/
|
||||
#define ADDINC128(w,n) { \
|
||||
(w)[0] += (sha2_word64)(n); \
|
||||
if ((w)[0] < (n)) { \
|
||||
(w)[1]++; \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Macros for copying blocks of memory and for zeroing out ranges
|
||||
* of memory. Using these macros makes it easy to switch from
|
||||
* using memset()/memcpy() and using bzero()/bcopy().
|
||||
*
|
||||
* Please define either SHA2_USE_MEMSET_MEMCPY or define
|
||||
* SHA2_USE_BZERO_BCOPY depending on which function set you
|
||||
* choose to use:
|
||||
*/
|
||||
#if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY)
|
||||
/* Default to memset()/memcpy() if no option is specified */
|
||||
#define SHA2_USE_MEMSET_MEMCPY 1
|
||||
#endif
|
||||
#if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY)
|
||||
/* Abort with an error if BOTH options are defined */
|
||||
#error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both!
|
||||
#endif
|
||||
|
||||
#ifdef SHA2_USE_MEMSET_MEMCPY
|
||||
#define MEMSET_BZERO(p,l) memset((p), 0, (l))
|
||||
#define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l))
|
||||
#endif
|
||||
#ifdef SHA2_USE_BZERO_BCOPY
|
||||
#define MEMSET_BZERO(p,l) bzero((p), (l))
|
||||
#define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l))
|
||||
#endif
|
||||
|
||||
|
||||
/*** THE SIX LOGICAL FUNCTIONS ****************************************/
|
||||
/*
|
||||
* Bit shifting and rotation (used by the six SHA-XYZ logical functions:
|
||||
*
|
||||
* NOTE: The naming of R and S appears backwards here (R is a SHIFT and
|
||||
* S is a ROTATION) because the SHA-256/384/512 description document
|
||||
* (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this
|
||||
* same "backwards" definition.
|
||||
*/
|
||||
/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */
|
||||
#define R(b,x) ((x) >> (b))
|
||||
/* 32-bit Rotate-right (used in SHA-256): */
|
||||
#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b))))
|
||||
|
||||
/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */
|
||||
#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
|
||||
#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
|
||||
|
||||
/* Four of six logical functions used in SHA-256: */
|
||||
#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x)))
|
||||
#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x)))
|
||||
#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x)))
|
||||
#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x)))
|
||||
|
||||
/*** INTERNAL FUNCTION PROTOTYPES *************************************/
|
||||
/* NOTE: These should not be accessed directly from outside this
|
||||
* library -- they are intended for private internal visibility/use
|
||||
* only.
|
||||
*/
|
||||
static void SHA256_Transform(RIOT_SHA256_CONTEXT *, const sha2_word32 *);
|
||||
|
||||
/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/
|
||||
/* Hash constant words K for SHA-256: */
|
||||
static const sha2_word32 K256[64] = {
|
||||
0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL,
|
||||
0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL,
|
||||
0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL,
|
||||
0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL,
|
||||
0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
|
||||
0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL,
|
||||
0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL,
|
||||
0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL,
|
||||
0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL,
|
||||
0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
|
||||
0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL,
|
||||
0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL,
|
||||
0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL,
|
||||
0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL,
|
||||
0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
|
||||
0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
|
||||
};
|
||||
|
||||
/* Initial hash value H for SHA-256: */
|
||||
static const sha2_word32 sha256_initial_hash_value[8] = {
|
||||
0x6a09e667UL,
|
||||
0xbb67ae85UL,
|
||||
0x3c6ef372UL,
|
||||
0xa54ff53aUL,
|
||||
0x510e527fUL,
|
||||
0x9b05688cUL,
|
||||
0x1f83d9abUL,
|
||||
0x5be0cd19UL
|
||||
};
|
||||
|
||||
/*
|
||||
* Constant used by SHA256() functions for converting the
|
||||
* digest to a readable hexadecimal character string:
|
||||
*/
|
||||
//static const char *sha2_hex_digits = "0123456789abcdef";
|
||||
|
||||
/*** SHA-256: *********************************************************/
|
||||
void RIOT_SHA256_Init(RIOT_SHA256_CONTEXT *context)
|
||||
{
|
||||
if (context == (RIOT_SHA256_CONTEXT *)0) {
|
||||
return;
|
||||
}
|
||||
context->magic = HASH_MAGIC_VALUE;
|
||||
MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH);
|
||||
MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH);
|
||||
context->bitcount = 0;
|
||||
}
|
||||
|
||||
static void SHA256_Transform(RIOT_SHA256_CONTEXT *context, const sha2_word32 *data)
|
||||
{
|
||||
sha2_word32 a, b, c, d, e, f, g, h, s0, s1;
|
||||
sha2_word32 T1, T2, *W256;
|
||||
int j;
|
||||
|
||||
W256 = (sha2_word32 *)context->buffer;
|
||||
|
||||
/* Initialize registers with the prev. intermediate value */
|
||||
a = context->state[0];
|
||||
b = context->state[1];
|
||||
c = context->state[2];
|
||||
d = context->state[3];
|
||||
e = context->state[4];
|
||||
f = context->state[5];
|
||||
g = context->state[6];
|
||||
h = context->state[7];
|
||||
|
||||
j = 0;
|
||||
do {
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
/* Copy data while converting to host uint8_t order */
|
||||
REVERSE32(*data++,W256[j]);
|
||||
/* Apply the SHA-256 compression function to update a..h */
|
||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j];
|
||||
#else /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
/* Apply the SHA-256 compression function to update a..h with copy */
|
||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++);
|
||||
#endif /* BYTE_ORDER == LITTLE_ENDIAN */
|
||||
T2 = Sigma0_256(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 16);
|
||||
|
||||
do {
|
||||
/* Part of the message block expansion: */
|
||||
s0 = W256[(j+1)&0x0f];
|
||||
s0 = sigma0_256(s0);
|
||||
s1 = W256[(j+14)&0x0f];
|
||||
s1 = sigma1_256(s1);
|
||||
|
||||
/* Apply the SHA-256 compression function to update a..h */
|
||||
T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] +
|
||||
(W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0);
|
||||
T2 = Sigma0_256(a) + Maj(a, b, c);
|
||||
h = g;
|
||||
g = f;
|
||||
f = e;
|
||||
e = d + T1;
|
||||
d = c;
|
||||
c = b;
|
||||
b = a;
|
||||
a = T1 + T2;
|
||||
|
||||
j++;
|
||||
} while (j < 64);
|
||||
|
||||
/* Compute the current intermediate hash value */
|
||||
context->state[0] += a;
|
||||
context->state[1] += b;
|
||||
context->state[2] += c;
|
||||
context->state[3] += d;
|
||||
context->state[4] += e;
|
||||
context->state[5] += f;
|
||||
context->state[6] += g;
|
||||
context->state[7] += h;
|
||||
|
||||
/* Clean up */
|
||||
a = b = c = d = e = f = g = h = T1 = T2 = 0;
|
||||
}
|
||||
|
||||
void RIOT_SHA256_Update(RIOT_SHA256_CONTEXT *context, const sha2_uint8_t *data, size_t len)
|
||||
{
|
||||
unsigned int freespace, usedspace;
|
||||
|
||||
if (len == 0) {
|
||||
/* Calling with no data is valid - we do nothing */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (RIOT_SHA256_CONTEXT *)0 && data != (sha2_uint8_t *)0 && context->magic == HASH_MAGIC_VALUE);
|
||||
|
||||
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
|
||||
if (usedspace > 0) {
|
||||
/* Calculate how much free space is available in the buffer */
|
||||
freespace = SHA256_BLOCK_LENGTH - usedspace;
|
||||
|
||||
if (len >= freespace) {
|
||||
/* Fill the buffer completely and process it */
|
||||
MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace);
|
||||
context->bitcount += freespace << 3;
|
||||
len -= freespace;
|
||||
data += freespace;
|
||||
SHA256_Transform(context, (sha2_word32 *)context->buffer);
|
||||
} else {
|
||||
/* The buffer is not yet full */
|
||||
MEMCPY_BCOPY(&context->buffer[usedspace], data, len);
|
||||
context->bitcount += len << 3;
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (len >= SHA256_BLOCK_LENGTH) {
|
||||
/* Process as many complete blocks as we can */
|
||||
SHA256_Transform(context, (sha2_word32 *)data);
|
||||
context->bitcount += SHA256_BLOCK_LENGTH << 3;
|
||||
len -= SHA256_BLOCK_LENGTH;
|
||||
data += SHA256_BLOCK_LENGTH;
|
||||
}
|
||||
if (len > 0) {
|
||||
/* There's left-overs, so save 'em */
|
||||
MEMCPY_BCOPY(context->buffer, data, len);
|
||||
context->bitcount += len << 3;
|
||||
}
|
||||
/* Clean up: */
|
||||
usedspace = freespace = 0;
|
||||
}
|
||||
|
||||
void RIOT_SHA256_Final(RIOT_SHA256_CONTEXT *context, sha2_uint8_t *digest)
|
||||
{
|
||||
sha2_word32 *d = (sha2_word32 *)digest;
|
||||
unsigned int usedspace;
|
||||
|
||||
/* Sanity check: */
|
||||
assert(context != (RIOT_SHA256_CONTEXT *)0 && context->magic == HASH_MAGIC_VALUE);
|
||||
|
||||
/* If no digest buffer is passed, we don't bother doing this: */
|
||||
if (digest != (sha2_uint8_t *)0) {
|
||||
usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH;
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
/* Convert FROM host uint8_t order */
|
||||
REVERSE64(context->bitcount,context->bitcount);
|
||||
#endif
|
||||
if (usedspace > 0) {
|
||||
/* Begin padding with a 1 bit: */
|
||||
context->buffer[usedspace++] = 0x80;
|
||||
|
||||
if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) {
|
||||
/* Set-up for the last transform: */
|
||||
MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace);
|
||||
} else {
|
||||
if (usedspace < SHA256_BLOCK_LENGTH) {
|
||||
MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace);
|
||||
}
|
||||
/* Do second-to-last transform: */
|
||||
SHA256_Transform(context, (sha2_word32 *)context->buffer);
|
||||
|
||||
/* And set-up for the last transform: */
|
||||
MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
|
||||
}
|
||||
} else {
|
||||
/* Set-up for the last transform: */
|
||||
MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH);
|
||||
|
||||
/* Begin padding with a 1 bit: */
|
||||
*context->buffer = 0x80;
|
||||
}
|
||||
/* Set the bit count: */
|
||||
*(sha2_word64 *)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount;
|
||||
|
||||
/* Final transform: */
|
||||
SHA256_Transform(context, (sha2_word32 *)context->buffer);
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
{
|
||||
/* Convert TO host uint8_t order */
|
||||
int j;
|
||||
for (j = 0; j < 8; j++) {
|
||||
REVERSE32(context->state[j],context->state[j]);
|
||||
*d++ = context->state[j];
|
||||
}
|
||||
}
|
||||
#else
|
||||
MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Clean up state data: */
|
||||
MEMSET_BZERO(context, sizeof(RIOT_SHA256_CONTEXT));
|
||||
usedspace = 0;
|
||||
}
|
||||
|
||||
void RIOT_SHA256_Block_ctx(RIOT_SHA256_CONTEXT *context, const uint8_t *buf, size_t bufSize, uint8_t *digest)
|
||||
{
|
||||
RIOT_SHA256_Init(context);
|
||||
RIOT_SHA256_Update(context, buf, bufSize);
|
||||
RIOT_SHA256_Final(context, digest);
|
||||
}
|
||||
|
||||
void RIOT_SHA256_Block(const uint8_t *buf, size_t bufSize, uint8_t *digest)
|
||||
{
|
||||
RIOT_SHA256_CONTEXT context;
|
||||
RIOT_SHA256_Init(&context);
|
||||
RIOT_SHA256_Update(&context, buf, bufSize);
|
||||
RIOT_SHA256_Final(&context, digest);
|
||||
}
|
|
@ -0,0 +1,314 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "RiotDerEnc.h"
|
||||
#include "RiotX509Bldr.h"
|
||||
|
||||
#define ASRT(_X) if(!(_X)) {goto Error;}
|
||||
#define CHK(_X) if(((_X)) < 0) {goto Error;}
|
||||
|
||||
// OIDs. Note that the encoder expects a -1 sentinel.
|
||||
static int ecdsaWithSHA256OID[] = { 1,2,840,10045,4,3,2,-1 };
|
||||
static int ecPublicKeyOID[] = { 1,2,840,10045, 2,1,-1 };
|
||||
static int prime256v1OID[] = { 1,2,840,10045, 3,1,7,-1 };
|
||||
static int extKeyUsageOID[] = { 2,5,29,37,-1 };
|
||||
static int subjectAltNameOID[] = { 2,5,29,17,-1 };
|
||||
static int clientAuthOID[] = { 1,3,6,1,5,5,7,3,2,-1 };
|
||||
static int sha256OID[] = { 2,16,840,1,101,3,4,2,1,-1 };
|
||||
static int commonNameOID[] = { 2,5,4,3,-1 };
|
||||
static int countryNameOID[] = { 2,5,4,6,-1 };
|
||||
static int orgNameOID[] = { 2,5,4,10,-1 };
|
||||
|
||||
int riotOID[] = { 1,2,3,4,5,6,-1 };
|
||||
|
||||
int
|
||||
X509AddExtensions(
|
||||
DERBuilderContext *Tbs,
|
||||
uint8_t *DevIdPub,
|
||||
uint32_t DevIdPubLen,
|
||||
uint8_t *Fwid,
|
||||
uint32_t FwidLen
|
||||
)
|
||||
// Create the RIoT extensions. The RIoT subject altName + extended key usage.
|
||||
{
|
||||
CHK(DERStartExplicit(Tbs, 3));
|
||||
CHK( DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERAddOID(Tbs, extKeyUsageOID));
|
||||
CHK( DERAddBoolean(Tbs, true));
|
||||
CHK( DERStartEnvelopingOctetString(Tbs));
|
||||
CHK( DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERAddOID(Tbs, clientAuthOID));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK( DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERAddOID(Tbs, subjectAltNameOID));
|
||||
CHK( DERAddBoolean(Tbs, true));
|
||||
CHK( DERStartEnvelopingOctetString(Tbs));
|
||||
CHK( DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERStartExplicit(Tbs, 0));
|
||||
CHK( DERAddOID(Tbs, riotOID));
|
||||
CHK( DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERAddInteger(Tbs, 1));
|
||||
CHK( DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERAddOID(Tbs, ecPublicKeyOID));
|
||||
CHK( DERAddOID(Tbs, prime256v1OID));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK( DERAddBitString(Tbs, DevIdPub, DevIdPubLen));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK( DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERAddOID(Tbs, sha256OID));
|
||||
CHK( DERAddOctetString(Tbs, Fwid, FwidLen));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK(DERPopNesting(Tbs));
|
||||
|
||||
return 0;
|
||||
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
X509MakeAliasCert(
|
||||
DERBuilderContext *AliasCert,
|
||||
RIOT_ECC_SIGNATURE *TbsSig
|
||||
)
|
||||
// Create an ALias Certificate given a ready-to-sign TBS region in the context
|
||||
{
|
||||
uint8_t encBuffer[((BIGLEN - 1) * 4)];
|
||||
uint32_t encBufferLen = ((BIGLEN - 1) * 4);
|
||||
|
||||
// Elevate the "TBS" block into a real certificate,
|
||||
// i.e., copy it into an enclosing sequence.
|
||||
CHK(DERTbsToCert(AliasCert));
|
||||
CHK( DERStartSequenceOrSet(AliasCert, true));
|
||||
CHK( DERAddOID(AliasCert, ecdsaWithSHA256OID));
|
||||
CHK( DERPopNesting(AliasCert));
|
||||
CHK( DERStartEnvelopingBitString(AliasCert));
|
||||
CHK( DERStartSequenceOrSet(AliasCert, true));
|
||||
BigValToBigInt(encBuffer, &TbsSig->r);
|
||||
CHK( DERAddIntegerFromArray(AliasCert, encBuffer, encBufferLen));
|
||||
BigValToBigInt(encBuffer, &TbsSig->s);
|
||||
CHK( DERAddIntegerFromArray(AliasCert, encBuffer, encBufferLen));
|
||||
CHK( DERPopNesting(AliasCert));
|
||||
CHK( DERPopNesting(AliasCert));
|
||||
CHK(DERPopNesting(AliasCert));
|
||||
|
||||
ASRT(DERGetNestingDepth(AliasCert) == 0);
|
||||
return 0;
|
||||
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
X509AddX501Name(
|
||||
DERBuilderContext *Context,
|
||||
const char *CommonName,
|
||||
const char *OrgName,
|
||||
const char *CountryName
|
||||
)
|
||||
{
|
||||
CHK( DERStartSequenceOrSet(Context, true));
|
||||
CHK( DERStartSequenceOrSet(Context, false));
|
||||
CHK( DERStartSequenceOrSet(Context, true));
|
||||
CHK( DERAddOID(Context, commonNameOID));
|
||||
CHK( DERAddUTF8String(Context, CommonName));
|
||||
CHK( DERPopNesting(Context));
|
||||
CHK( DERPopNesting(Context));
|
||||
CHK( DERStartSequenceOrSet(Context, false));
|
||||
CHK( DERStartSequenceOrSet(Context, true));
|
||||
CHK( DERAddOID(Context, countryNameOID));
|
||||
CHK( DERAddUTF8String(Context, CountryName));
|
||||
CHK( DERPopNesting(Context));
|
||||
CHK( DERPopNesting(Context));
|
||||
CHK( DERStartSequenceOrSet(Context, false));
|
||||
CHK( DERStartSequenceOrSet(Context, true));
|
||||
CHK( DERAddOID(Context, orgNameOID));
|
||||
CHK( DERAddUTF8String(Context, OrgName));
|
||||
CHK( DERPopNesting(Context));
|
||||
CHK( DERPopNesting(Context));
|
||||
CHK( DERPopNesting(Context));
|
||||
|
||||
return 0;
|
||||
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int X509GetDEREncodedTBS(
|
||||
DERBuilderContext *Tbs,
|
||||
RIOT_X509_TBS_DATA *TbsData,
|
||||
RIOT_ECC_PUBLIC *AliasKeyPub,
|
||||
RIOT_ECC_PUBLIC *DevIdKeyPub,
|
||||
uint8_t *Fwid,
|
||||
uint32_t FwidLen
|
||||
)
|
||||
{
|
||||
uint8_t encBuffer[65];
|
||||
uint32_t encBufferLen;
|
||||
|
||||
CHK(DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERAddShortExplicitInteger(Tbs, 2));
|
||||
CHK( DERAddIntegerFromArray(Tbs, TbsData->SerialNum, RIOT_X509_SNUM_LEN));
|
||||
CHK( DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERAddOID(Tbs, ecdsaWithSHA256OID));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK( X509AddX501Name(Tbs, TbsData->IssuerCommon, TbsData->IssuerOrg, TbsData->IssuerCountry));
|
||||
CHK( DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERAddUTCTime(Tbs, TbsData->ValidFrom));
|
||||
CHK( DERAddUTCTime(Tbs, TbsData->ValidTo));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
CHK( X509AddX501Name(Tbs, TbsData->SubjectCommon, TbsData->SubjectOrg, TbsData->SubjectCountry));
|
||||
CHK( DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERStartSequenceOrSet(Tbs, true));
|
||||
CHK( DERAddOID(Tbs, ecPublicKeyOID));
|
||||
CHK( DERAddOID(Tbs, prime256v1OID));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
RiotCrypt_ExportEccPub(AliasKeyPub, encBuffer, &encBufferLen);
|
||||
CHK( DERAddBitString(Tbs, encBuffer, encBufferLen));
|
||||
CHK( DERPopNesting(Tbs));
|
||||
RiotCrypt_ExportEccPub(DevIdKeyPub, encBuffer, &encBufferLen);
|
||||
CHK( X509AddExtensions(Tbs, encBuffer, encBufferLen, Fwid, FwidLen));
|
||||
CHK(DERPopNesting(Tbs));
|
||||
|
||||
ASRT(DERGetNestingDepth(Tbs) == 0);
|
||||
return 0;
|
||||
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
X509GetDEREccPub(
|
||||
DERBuilderContext *Context,
|
||||
RIOT_ECC_PUBLIC Pub
|
||||
)
|
||||
{
|
||||
uint8_t encBuffer[65];
|
||||
uint32_t encBufferLen;
|
||||
|
||||
CHK(DERStartSequenceOrSet(Context, true));
|
||||
CHK( DERStartSequenceOrSet(Context, true));
|
||||
CHK( DERAddOID(Context, ecPublicKeyOID));
|
||||
CHK( DERAddOID(Context, prime256v1OID));
|
||||
CHK( DERPopNesting(Context));
|
||||
RiotCrypt_ExportEccPub(&Pub, encBuffer, &encBufferLen);
|
||||
CHK( DERAddBitString(Context, encBuffer, encBufferLen));
|
||||
CHK(DERPopNesting(Context));
|
||||
|
||||
ASRT(DERGetNestingDepth(Context) == 0);
|
||||
return 0;
|
||||
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
X509GetDEREcc(
|
||||
DERBuilderContext *Context,
|
||||
RIOT_ECC_PUBLIC Pub,
|
||||
RIOT_ECC_PRIVATE Priv
|
||||
)
|
||||
{
|
||||
uint8_t encBuffer[65];
|
||||
uint32_t encBufferLen;
|
||||
|
||||
CHK(DERStartSequenceOrSet(Context, true));
|
||||
CHK( DERAddInteger(Context, 1));
|
||||
BigValToBigInt(encBuffer, &Priv);
|
||||
CHK( DERAddOctetString(Context, encBuffer, 32));
|
||||
CHK( DERStartExplicit(Context, 0));
|
||||
CHK( DERAddOID(Context, prime256v1OID));
|
||||
CHK( DERPopNesting(Context));
|
||||
CHK( DERStartExplicit(Context, 1));
|
||||
RiotCrypt_ExportEccPub(&Pub, encBuffer, &encBufferLen);
|
||||
CHK( DERAddBitString(Context, encBuffer, encBufferLen));
|
||||
CHK( DERPopNesting(Context));
|
||||
CHK(DERPopNesting(Context));
|
||||
|
||||
ASRT(DERGetNestingDepth(Context) == 0);
|
||||
return 0;
|
||||
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
X509GetDERCsrTbs(
|
||||
DERBuilderContext *Context,
|
||||
RIOT_X509_TBS_DATA *TbsData,
|
||||
RIOT_ECC_PUBLIC* DeviceIDPub)
|
||||
{
|
||||
|
||||
uint8_t encBuffer[65];
|
||||
uint32_t encBufferLen;
|
||||
|
||||
CHK(DERStartSequenceOrSet(Context, true));
|
||||
CHK( DERAddInteger(Context, 0));
|
||||
CHK( X509AddX501Name(Context, TbsData->IssuerCommon, TbsData->IssuerOrg, TbsData->IssuerCountry));
|
||||
CHK( DERStartSequenceOrSet(Context, true));
|
||||
CHK( DERStartSequenceOrSet(Context, true));
|
||||
CHK( DERAddOID(Context, ecPublicKeyOID));
|
||||
CHK( DERAddOID(Context, prime256v1OID));
|
||||
CHK( DERPopNesting(Context));
|
||||
RiotCrypt_ExportEccPub(DeviceIDPub, encBuffer, &encBufferLen);
|
||||
CHK( DERAddBitString(Context, encBuffer, encBufferLen));
|
||||
CHK( DERPopNesting(Context));
|
||||
CHK(DERStartExplicit(Context,0));
|
||||
CHK(DERPopNesting(Context));
|
||||
CHK(DERPopNesting(Context));
|
||||
|
||||
ASRT(DERGetNestingDepth(Context) == 0);
|
||||
return 0;
|
||||
|
||||
Error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
X509GetDERCsr(
|
||||
DERBuilderContext *Context,
|
||||
RIOT_ECC_SIGNATURE *Signature
|
||||
)
|
||||
{
|
||||
|
||||
uint8_t encBuffer[((BIGLEN - 1) * 4)];
|
||||
uint32_t encBufferLen = ((BIGLEN - 1) * 4);
|
||||
|
||||
// Elevate the "TBS" block into a real certificate, i.e., copy it
|
||||
// into an enclosing sequence and then add the signature block.
|
||||
CHK(DERTbsToCert(Context));
|
||||
CHK( DERStartSequenceOrSet(Context, true));
|
||||
CHK( DERAddOID(Context, ecdsaWithSHA256OID));
|
||||
CHK( DERPopNesting(Context));
|
||||
CHK( DERStartEnvelopingBitString(Context));
|
||||
CHK( DERStartSequenceOrSet(Context, true));
|
||||
BigValToBigInt(encBuffer, &Signature->r);
|
||||
CHK( DERAddIntegerFromArray(Context, encBuffer, encBufferLen));
|
||||
BigValToBigInt(encBuffer, &Signature->s);
|
||||
CHK( DERAddIntegerFromArray(Context, encBuffer, encBufferLen));
|
||||
CHK( DERPopNesting(Context));
|
||||
CHK( DERPopNesting(Context));
|
||||
CHK(DERPopNesting(Context));
|
||||
|
||||
ASRT(DERGetNestingDepth(Context) == 0);
|
||||
return 0;
|
||||
|
||||
Error:
|
||||
return -1;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
#ifndef _RIOT_CRYPTO_AES128_H
|
||||
#define _RIOT_CRYPTO_AES128_H
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2012-2014, AllSeen Alliance. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT)
|
||||
//
|
||||
#include "RiotTarget.h"
|
||||
#include "RiotStatus.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define AES_CTR_MODE YES
|
||||
#define AES_CBC_MODE NO
|
||||
#define AES_ECB_MODE YES
|
||||
|
||||
#define AES128_ENCRYPT_SCHEDULE_LEN 48
|
||||
|
||||
#define AES_BLOCK_SIZE 16
|
||||
|
||||
typedef uint32_t aes128EncryptKey_t[AES128_ENCRYPT_SCHEDULE_LEN];
|
||||
|
||||
//
|
||||
// Enable AES allocating any resources required
|
||||
//
|
||||
// @param key The key in case this is required
|
||||
//
|
||||
void RIOT_AES128_Enable(const uint8_t *key, aes128EncryptKey_t *aes128EncryptKey);
|
||||
|
||||
//
|
||||
// Disable AES freeing any resources that were allocated
|
||||
//
|
||||
void RIOT_AES128_Disable(aes128EncryptKey_t *aes128EncryptKey);
|
||||
|
||||
//
|
||||
// AES counter mode encryption/decryption. Note that in
|
||||
// CTR mode encryption is its own inverse. This function uses the key
|
||||
// schedule created by RIOT_AES128_Enable()
|
||||
//
|
||||
// @param in The data to encrypt
|
||||
// @param out The encrypted data
|
||||
// @param len The length of the input data, must be multiple of 16
|
||||
// @param ctr Pointer to a 16 uint8_t counter block
|
||||
//
|
||||
void RIOT_AES_CTR_128(const aes128EncryptKey_t *aes128EncryptKey, const uint8_t *in,
|
||||
uint8_t *out, uint32_t len, uint8_t *ctr);
|
||||
|
||||
void RIOT_AES_CBC_128_ENCRYPT(const aes128EncryptKey_t *aes128EncryptKey,
|
||||
const uint8_t *in, uint8_t *out, uint32_t len,
|
||||
uint8_t *iv);
|
||||
|
||||
void RIOT_AES_ECB_128_ENCRYPT(const aes128EncryptKey_t *aes128EncryptKey,
|
||||
const uint8_t *in, uint8_t *out, size_t size);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
#ifndef RIOT_BASE64_H
|
||||
#define RIOT_BASE64_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define Base64Length(l) ((l == 0) ? (1) : (((((l - 1) / 3) + 1) * 4) + 1))
|
||||
|
||||
int
|
||||
Base64Encode(
|
||||
const unsigned char *Input,
|
||||
uint32_t Length,
|
||||
char *Output,
|
||||
uint32_t *OutLen
|
||||
);
|
||||
|
||||
int
|
||||
Base64Decode(
|
||||
const char *Input,
|
||||
unsigned char *Output,
|
||||
uint32_t *OutLen
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,208 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
|
||||
//
|
||||
// This source implements the interface between the RIoT framework and
|
||||
// its cryptographic functions.
|
||||
//
|
||||
|
||||
#ifndef _RIOT_CRYPTO_H
|
||||
#define _RIOT_CRYPTO_H
|
||||
|
||||
//
|
||||
// As the RIoT framework is minimalistic, it will normally support only one
|
||||
// flavor of each cryptographic operation, i.e., one key strength, one digest
|
||||
// size, etc.
|
||||
//
|
||||
// Macro definitions and typedefs in this header provide the level of
|
||||
// indirection to allow changing cryptographic primitives, parameters,
|
||||
// and/or underlying crypto libraries with no or minimal impact on the
|
||||
// reference code.
|
||||
//
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "RiotSha256.h"
|
||||
#include "RiotAes128.h"
|
||||
#include "RiotHmac.h"
|
||||
#include "RiotKdf.h"
|
||||
#include "RiotEcc.h"
|
||||
#include "RiotBase64.h"
|
||||
|
||||
// Size, in bytes, of a RIoT digest using the chosen hash algorithm.
|
||||
#define RIOT_DIGEST_LENGTH SHA256_DIGEST_LENGTH
|
||||
|
||||
// Size, in bytes, of a RIoT HMAC.
|
||||
#define RIOT_HMAC_LENGTH RIOT_DIGEST_LENGTH
|
||||
|
||||
// Size, in bytes, of internal keys used by the RIoT framework.
|
||||
// NOTE: This number of bytes is used for key derivation.
|
||||
#define RIOT_KEY_LENGTH RIOT_DIGEST_LENGTH
|
||||
|
||||
// Number of bits in internal symmetric keys used by the RIoT framework.
|
||||
// NOTE: This number of bits is used for key derivation. The symmetric
|
||||
// algorithm implemenbted by the RIoT framework may use only a
|
||||
// subset of these bytes for encryption.
|
||||
#define RIOT_KEY_BITS (RIOT_KEY_LENGTH * 8)
|
||||
|
||||
// Number of bytes in symmetric encryption keys used by the RIoT framework.
|
||||
// This number also includes IV/Counter bytes.
|
||||
#define RIOT_SYM_KEY_LENGTH (16 + 16)
|
||||
|
||||
// Size, in bytes, of encoded RIoT Key length
|
||||
#define RIOT_ENCODED_BUFFER_MAX (0x80)
|
||||
|
||||
// Maximal number of bytes in a label/context passed to the RIoT KDF routine.
|
||||
#define RIOT_MAX_KDF_CONTEXT_LENGTH RIOT_DIGEST_LENGTH
|
||||
|
||||
// Maximal number of bytes in a label/context passed to the RIoT KDF routine.
|
||||
#define RIOT_MAX_KDF_LABEL_LENGTH RIOT_DIGEST_LENGTH
|
||||
|
||||
// Maximal number of bytes in a RIOT_AIK certificate
|
||||
#define RIOT_MAX_CERT_LENGTH 2048
|
||||
|
||||
typedef ecc_publickey RIOT_ECC_PUBLIC;
|
||||
typedef ecc_privatekey RIOT_ECC_PRIVATE;
|
||||
typedef ecc_signature RIOT_ECC_SIGNATURE;
|
||||
|
||||
typedef enum {
|
||||
RIOT_ENCRYPT,
|
||||
RIOT_DECRYPT
|
||||
} RIOT_CRYPT_OP_TYPE;
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Kdf(
|
||||
uint8_t *result, // OUT: Buffer to receive the derived bytes
|
||||
size_t resultSize, // IN: Capacity of the result buffer
|
||||
const uint8_t *source, // IN: Initial data for derivation
|
||||
size_t sourceSize, // IN: Size of the source data in bytes
|
||||
const uint8_t *context, // IN: Derivation context (may be NULL)
|
||||
size_t contextSize, // IN: Size of the context in bytes
|
||||
const uint8_t *label, // IN: Label for derivation (may be NULL)
|
||||
size_t labelSize, // IN: Size of the label in bytes
|
||||
uint32_t bytesToDerive // IN: Number of bytes to be produced
|
||||
);
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Hash(
|
||||
uint8_t *result, // OUT: Buffer to receive the digest
|
||||
size_t resultSize, // IN: Capacity of the result buffer
|
||||
const void *data, // IN: Data to hash
|
||||
size_t dataSize // IN: Data size in bytes
|
||||
);
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Hash2(
|
||||
uint8_t *result, // OUT: Buffer to receive the digest
|
||||
size_t resultSize, // IN: Capacity of the result buffer
|
||||
const void *data1, // IN: 1st operand to hash
|
||||
size_t data1Size, // IN: 1st operand size in bytes
|
||||
const void *data2, // IN: 2nd operand to hash
|
||||
size_t data2Size // IN: 2nd operand size in bytes
|
||||
);
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Hmac(
|
||||
uint8_t *result, // OUT: Buffer to receive the HMAC
|
||||
size_t resultCapacity, // IN: Capacity of the result buffer
|
||||
const void *data, // IN: Data to HMAC
|
||||
size_t dataSize, // IN: Data size in bytes
|
||||
const uint8_t *key, // IN: HMAK key
|
||||
size_t keySize // IN: HMAC key size in bytes
|
||||
);
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Hmac2(
|
||||
uint8_t *result, // OUT: Buffer to receive the HMAK
|
||||
size_t resultCapacity, // IN: Capacity of the result buffer
|
||||
const void *data1, // IN: 1st operand to HMAC
|
||||
size_t data1Size, // IN: 1st operand size in bytes
|
||||
const void *data2, // IN: 2nd operand to HMAC
|
||||
size_t data2Size, // IN: 2nd operand size in bytes
|
||||
const uint8_t *key, // IN: HMAK key
|
||||
size_t keySize // IN: HMAC key size in bytes
|
||||
);
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_DeriveEccKey(
|
||||
RIOT_ECC_PUBLIC *publicPart, // OUT: TODO
|
||||
RIOT_ECC_PRIVATE *privatePart, // OUT: TODO
|
||||
const void *srcData, // IN: TODO
|
||||
size_t srcDataSize, // IN: TODO
|
||||
const uint8_t *label, // IN: TODO
|
||||
size_t labelSize // IN: TODO
|
||||
);
|
||||
|
||||
void
|
||||
RiotCrypt_ExportEccPub(
|
||||
RIOT_ECC_PUBLIC *a, // IN: TODO
|
||||
uint8_t *b, // OUT: TODO
|
||||
uint32_t *s // OUT: TODO
|
||||
);
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Sign(
|
||||
RIOT_ECC_SIGNATURE *sig, // OUT: TODO
|
||||
const void *data, // IN: TODO
|
||||
size_t dataSize, // IN: TODO
|
||||
const RIOT_ECC_PRIVATE *key // IN: TODO
|
||||
);
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_SignDigest(
|
||||
RIOT_ECC_SIGNATURE *sig, // OUT: TODO
|
||||
const uint8_t *digest, // IN: TODO
|
||||
size_t digestSize, // IN: TODO
|
||||
const RIOT_ECC_PRIVATE *key // IN: TODO
|
||||
);
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_Verify(
|
||||
const void *data, // IN: TODO
|
||||
size_t dataSize, // IN: TODO
|
||||
const RIOT_ECC_SIGNATURE *sig, // IN: TODO
|
||||
const RIOT_ECC_PUBLIC *key // IN: TODO
|
||||
);
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_VerifyDigest(
|
||||
const uint8_t *digest, // IN: TODO
|
||||
size_t digestSize, // IN: TODO
|
||||
const RIOT_ECC_SIGNATURE *sig, // IN: TODO
|
||||
const RIOT_ECC_PUBLIC *key // IN: TODO
|
||||
);
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_EccEncrypt(
|
||||
uint8_t *result, // OUT: Buffer to receive encrypted data
|
||||
size_t resultCapacity, // IN: Capacity of the result buffer
|
||||
RIOT_ECC_PUBLIC *ephKey, // OUT: Ephemeral key to produce
|
||||
const void *data, // IN: Data to encrypt
|
||||
size_t dataSize, // IN: Data size in bytes
|
||||
const RIOT_ECC_PUBLIC *key // IN: Encryption key
|
||||
);
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_EccDecrypt(
|
||||
uint8_t *result, // OUT: Buffer to receive decrypted data
|
||||
size_t resultCapacity, // IN: Capacity of the result buffer
|
||||
const void *data, // IN: Data to decrypt
|
||||
size_t dataSize, // IN: Data size in bytes
|
||||
RIOT_ECC_PUBLIC *ephKey, // IN: Ephemeral key to produce
|
||||
const RIOT_ECC_PRIVATE *key // IN: Decryption key
|
||||
);
|
||||
|
||||
RIOT_STATUS
|
||||
RiotCrypt_SymEncryptDecrypt(
|
||||
void *outData, // OUT: Output data
|
||||
size_t outSize, // IN: Size of output data
|
||||
const void *inData, // IN: Input data
|
||||
size_t inSize, // IN: Size of input data
|
||||
uint8_t key[RIOT_SYM_KEY_LENGTH] // IN/OUT: Symmetric key & IV
|
||||
);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,169 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2015, 2016
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DER_MAX_PEM 0x400
|
||||
#define DER_MAX_TBS 0x300
|
||||
#define DER_MAX_NESTED 0x10
|
||||
|
||||
//
|
||||
// Context structure for the DER-encoder. This structure contains a fixed-
|
||||
// length array for nested SEQUENCES (which imposes a nesting limit).
|
||||
// The buffer use for encoded data is caller-allocted.
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
uint8_t *Buffer; // Encoded data
|
||||
uint32_t Length; // Size, in bytes, of Buffer
|
||||
uint32_t Position; // Current buffer position
|
||||
|
||||
// SETS, SEQUENCES, etc. can be nested. This array contains the start of
|
||||
// the payload for collection types and is set by DERStartSequenceOrSet().
|
||||
// Collections are "popped" using DEREndSequenceOrSet().
|
||||
int CollectionStart[DER_MAX_NESTED];
|
||||
int CollectionPos;
|
||||
} DERBuilderContext;
|
||||
|
||||
// We only have a small subset of potential PEM encodings
|
||||
enum CertType {
|
||||
CERT_TYPE = 0,
|
||||
PUBLICKEY_TYPE,
|
||||
ECC_PRIVATEKEY_TYPE,
|
||||
CERT_REQ_TYPE,
|
||||
LAST_CERT_TYPE
|
||||
};
|
||||
|
||||
void
|
||||
DERInitContext(
|
||||
DERBuilderContext *Context,
|
||||
uint8_t *Buffer,
|
||||
uint32_t Length
|
||||
);
|
||||
|
||||
int
|
||||
DERGetEncodedLength(
|
||||
DERBuilderContext *Context
|
||||
);
|
||||
|
||||
|
||||
int
|
||||
DERAddOID(
|
||||
DERBuilderContext *Context,
|
||||
int *Values
|
||||
);
|
||||
|
||||
int
|
||||
DERAddUTF8String(
|
||||
DERBuilderContext *Context,
|
||||
const char *Str
|
||||
);
|
||||
|
||||
int
|
||||
DERAddPrintableString(
|
||||
DERBuilderContext *Context,
|
||||
const char *Str
|
||||
);
|
||||
|
||||
|
||||
int
|
||||
DERAddUTCTime(
|
||||
DERBuilderContext *Context,
|
||||
const char *Str
|
||||
);
|
||||
|
||||
int
|
||||
DERAddIntegerFromArray(
|
||||
DERBuilderContext *Context,
|
||||
uint8_t *Val,
|
||||
uint32_t NumBytes
|
||||
);
|
||||
|
||||
int
|
||||
DERAddInteger(
|
||||
DERBuilderContext *Context,
|
||||
int Val
|
||||
);
|
||||
|
||||
int
|
||||
DERAddShortExplicitInteger(
|
||||
DERBuilderContext *Context,
|
||||
int Val
|
||||
);
|
||||
|
||||
int
|
||||
DERAddBoolean(
|
||||
DERBuilderContext *Context,
|
||||
bool Val
|
||||
);
|
||||
|
||||
|
||||
int
|
||||
DERAddBitString(
|
||||
DERBuilderContext *Context,
|
||||
uint8_t *BitString,
|
||||
uint32_t BitStringNumBytes
|
||||
);
|
||||
|
||||
int
|
||||
DERAddOctetString(
|
||||
DERBuilderContext *Context,
|
||||
uint8_t *OctetString,
|
||||
uint32_t OctetStringLen
|
||||
);
|
||||
|
||||
int
|
||||
DERStartSequenceOrSet(
|
||||
DERBuilderContext *Context,
|
||||
bool Sequence
|
||||
);
|
||||
|
||||
int
|
||||
DERStartExplicit(
|
||||
DERBuilderContext *Context,
|
||||
uint32_t Num
|
||||
);
|
||||
|
||||
int
|
||||
DERStartEnvelopingOctetString(
|
||||
DERBuilderContext *Context
|
||||
);
|
||||
|
||||
int
|
||||
DERStartEnvelopingBitString(
|
||||
DERBuilderContext *Context
|
||||
);
|
||||
|
||||
int
|
||||
DERPopNesting(
|
||||
DERBuilderContext *Context
|
||||
);
|
||||
|
||||
int
|
||||
DERGetNestingDepth(
|
||||
DERBuilderContext *Context
|
||||
);
|
||||
|
||||
int
|
||||
DERTbsToCert(
|
||||
DERBuilderContext *Context
|
||||
);
|
||||
|
||||
int
|
||||
DERtoPEM(
|
||||
DERBuilderContext *Context,
|
||||
uint32_t Type,
|
||||
char *PEM,
|
||||
uint32_t *Length
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,194 @@
|
|||
#ifndef _RIOT_CRYPTO_ECC_H
|
||||
#define _RIOT_CRYPTO_ECC_H
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2014, AllSeen Alliance. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT).
|
||||
//
|
||||
#include "RiotTarget.h"
|
||||
#include "RiotStatus.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ECDSA_SIGN YES
|
||||
#define ECDSA_VERIFY YES
|
||||
#define ECDH_IN NO
|
||||
#define ECDH_OUT YES
|
||||
|
||||
#if ECDSA_SIZE || ECDH_OUT || ECDSA_SIGN
|
||||
#define USES_EPHEMERAL YES
|
||||
#else
|
||||
#define USES_EPHEMERAL NO
|
||||
#endif
|
||||
|
||||
#define BIGLEN 9
|
||||
//
|
||||
// For P256 bigval_t types hold 288-bit 2's complement numbers (9
|
||||
// 32-bit words). For P192 they hold 224-bit 2's complement numbers
|
||||
// (7 32-bit words).
|
||||
//
|
||||
// The representation is little endian by word and native endian
|
||||
// within each word.
|
||||
// The least significant word of the value is in the 0th word and there is an
|
||||
// extra word of zero at the top.
|
||||
//
|
||||
#define RIOT_ECC_PRIVATE_BYTES (4 * (BIGLEN - 1))
|
||||
#define RIOT_ECC_COORD_BYTES RIOT_ECC_PRIVATE_BYTES
|
||||
//
|
||||
// 4 is in lieu of sizeof(uint32_t), so that the macro is usable in #if conditions
|
||||
//
|
||||
typedef struct {
|
||||
uint32_t data[BIGLEN];
|
||||
} bigval_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
bigval_t x;
|
||||
bigval_t y;
|
||||
uint32_t infinity;
|
||||
} affine_point_t;
|
||||
|
||||
typedef struct {
|
||||
bigval_t r;
|
||||
bigval_t s;
|
||||
} ECDSA_sig_t;
|
||||
|
||||
typedef bigval_t ecc_privatekey;
|
||||
typedef affine_point_t ecc_publickey;
|
||||
typedef affine_point_t ecc_secret;
|
||||
typedef ECDSA_sig_t ecc_signature;
|
||||
|
||||
//
|
||||
// Convert a number from big endian by uint8_t to bigval_t. If the
|
||||
// size of the input number is larger than the initialization size
|
||||
// of a bigval_t ((BIGLEN - 1) * 4), it will be quietly truncated.
|
||||
//
|
||||
// @param out pointer to the bigval_t to be produced
|
||||
// @param in pointer to the big-endian value to convert
|
||||
// @param inSize number of bytes in the big-endian value
|
||||
//
|
||||
void
|
||||
BigIntToBigVal(bigval_t *tgt, const void *in, size_t inSize);
|
||||
|
||||
//
|
||||
// Convert a number from bigval_t to big endian by uint8_t.
|
||||
// The conversion will stop after the first (BIGLEN - 1) words have been converted.
|
||||
// The output size must be (BIGLEN = 1) * 4 bytes long.
|
||||
//
|
||||
// @param out pointer to the big endian value to be produced
|
||||
// @param in pointer to the bigval_t to convert
|
||||
//
|
||||
void
|
||||
BigValToBigInt(void *out, const bigval_t *tgt);
|
||||
|
||||
//
|
||||
// Generates the Ephemeral Diffie-Hellman key pair.
|
||||
//
|
||||
// @param publicKey The output public key
|
||||
// @param privateKey The output private key
|
||||
//
|
||||
// @return - RIOT_SUCCESS if the key pair is successfully generated.
|
||||
// - RIOT_ERR_SECURITY otherwise
|
||||
//
|
||||
RIOT_STATUS RIOT_GenerateDHKeyPair(ecc_publickey *publicKey, ecc_privatekey *privateKey);
|
||||
|
||||
//
|
||||
// Generates the Diffie-Hellman share secret.
|
||||
//
|
||||
// @param peerPublicKey The peer's public key
|
||||
// @param privateKey The private key
|
||||
// @param secret The output share secret
|
||||
//
|
||||
// @return - RIOT_SUCCESS if the share secret is successfully generated.
|
||||
// - RIOT_ERR_SECURITY otherwise
|
||||
//
|
||||
RIOT_STATUS RIOT_GenerateShareSecret(ecc_publickey *peerPublicKey,
|
||||
ecc_privatekey *privateKey,
|
||||
ecc_secret *secret);
|
||||
//
|
||||
// Generates the DSA key pair.
|
||||
//
|
||||
// @param publicKey The output public key
|
||||
// @param privateKey The output private key
|
||||
// @return - RIOT_SUCCESS if the key pair is successfully generated
|
||||
// - RIOT_ERR_SECURITY otherwise
|
||||
//
|
||||
RIOT_STATUS RIOT_GenerateDSAKeyPair(ecc_publickey *publicKey, ecc_privatekey *privateKey);
|
||||
|
||||
// *
|
||||
// Derives a DSA key pair from the supplied value and label
|
||||
//
|
||||
// @param publicKey OUT: public key
|
||||
// @param privateKey OUT: output private key
|
||||
// @param srcVal IN: Source value for derivation
|
||||
// @param label IN: Label for derivation.
|
||||
// @param labelSize IN: Label size. Should not exceed RIOT_ECC_PRIVATE_bytes.
|
||||
// @return - RIOT_SUCCESS
|
||||
//
|
||||
RIOT_STATUS
|
||||
RIOT_DeriveDsaKeyPair(ecc_publickey *publicKey, ecc_privatekey *privateKey,
|
||||
bigval_t *srcVal, const uint8_t *label, size_t labelSize);
|
||||
|
||||
//
|
||||
// Sign a digest using the DSA key
|
||||
// @param digest The digest to sign
|
||||
// @param signingPrivateKey The signing private key
|
||||
// @param sig The output signature
|
||||
// @return - RIOT_SUCCESS if the signing process succeeds
|
||||
// - RIOT_ERR_SECURITY otherwise
|
||||
//
|
||||
RIOT_STATUS RIOT_DSASignDigest(const uint8_t *digest, const ecc_privatekey *signingPrivateKey, ecc_signature *sig);
|
||||
|
||||
//
|
||||
// Sign a buffer using the DSA key
|
||||
// @param buf The buffer to sign
|
||||
// @param len The buffer len
|
||||
// @param signingPrivateKey The signing private key
|
||||
// @param sig The output signature
|
||||
// @return - RIOT_SUCCESS if the signing process succeeds
|
||||
// - RIOT_ERR_SECURITY otherwise
|
||||
//
|
||||
RIOT_STATUS RIOT_DSASign(const uint8_t *buf, uint16_t len, const ecc_privatekey *signingPrivateKey, ecc_signature *sig);
|
||||
|
||||
//
|
||||
// Verify DSA signature of a digest
|
||||
// @param digest The digest to sign
|
||||
// @param sig The signature
|
||||
// @param pubKey The signing public key
|
||||
// @return - RIOT_SUCCESS if the signature verification succeeds
|
||||
// - RIOT_ERR_SECURITY otherwise
|
||||
//
|
||||
RIOT_STATUS RIOT_DSAVerifyDigest(const uint8_t *digest, const ecc_signature *sig, const ecc_publickey *pubKey);
|
||||
|
||||
//
|
||||
// Verify DSA signature of a buffer
|
||||
// @param buf The buffer to sign
|
||||
// @param len The buffer len
|
||||
// @param sig The signature
|
||||
// @param pubKey The signing public key
|
||||
// @return - RIOT_SUCCESS if the signature verification succeeds
|
||||
// - RIOT_ERR_SECURITY otherwise
|
||||
//
|
||||
RIOT_STATUS RIOT_DSAVerify(const uint8_t *buf, uint16_t len, const ecc_signature *sig, const ecc_publickey *pubKey);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,65 @@
|
|||
#ifndef _RIOT_CRYPTO_SHA2_H
|
||||
#define _RIOT_CRYPTO_SHA2_H
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2014, AllSeen Alliance. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT).
|
||||
//
|
||||
#include "RiotTarget.h"
|
||||
#include "RiotStatus.h"
|
||||
#include "RiotSha256.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define HMAC_SHA256_DIGEST_LENGTH SHA256_DIGEST_LENGTH
|
||||
#define HMAC_SHA256_BLOCK_LENGTH 64
|
||||
|
||||
typedef struct _RIOT_HMAC_SHA256_CTX {
|
||||
RIOT_SHA256_CONTEXT hashCtx;
|
||||
uint8_t opad[HMAC_SHA256_BLOCK_LENGTH];
|
||||
} RIOT_HMAC_SHA256_CTX;
|
||||
|
||||
//
|
||||
// Initialize the HMAC context
|
||||
// @param ctx the HMAC context
|
||||
// @param key the key
|
||||
// @param keyLen the length of the key
|
||||
//
|
||||
void RIOT_HMAC_SHA256_Init(RIOT_HMAC_SHA256_CTX *ctx, const uint8_t *key, size_t keyLen);
|
||||
|
||||
//
|
||||
// Update the hash with data
|
||||
// @param ctx the HMAC context
|
||||
// @param data the data
|
||||
// @param dataLen the length of the data
|
||||
// @return
|
||||
//
|
||||
void RIOT_HMAC_SHA256_Update(RIOT_HMAC_SHA256_CTX *ctx, const uint8_t *data, size_t dataLen);
|
||||
|
||||
//
|
||||
// Retrieve the final digest for the HMAC
|
||||
// @param ctx the HMAC context
|
||||
// @param digest the buffer to hold the digest. Must be of size SHA256_DIGEST_LENGTH
|
||||
//
|
||||
void RIOT_HMAC_SHA256_Final(RIOT_HMAC_SHA256_CTX *ctx, uint8_t *digest);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,67 @@
|
|||
#ifndef _RIOT_CRYPTO_KDF_SHA256_H_
|
||||
#define _RIOT_CRYPTO_KDF_SHA256_H_
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2013, AllSeen Alliance. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "RiotHmac.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// *
|
||||
// Create the fixed content for a KDF
|
||||
// @param fixed buffer to receive the fixed content
|
||||
// @param fixedSize indicates the available space in fixed
|
||||
// @param label the label parameter (optional)
|
||||
// @param labelSize
|
||||
// @param context the context value (optional)
|
||||
// @param contextSize
|
||||
// @param numberOfBits the number of bits to be produced
|
||||
//
|
||||
size_t RIOT_KDF_FIXED(
|
||||
uint8_t *fixed,
|
||||
size_t fixedSize,
|
||||
const uint8_t *label,
|
||||
size_t labelSize,
|
||||
const uint8_t *context,
|
||||
size_t contextSize,
|
||||
uint32_t numberOfBits
|
||||
);
|
||||
|
||||
//
|
||||
// Do KDF from SP800-108 -- HMAC based counter mode. This function does a single
|
||||
// iteration
|
||||
// @param out the output digest of a single iteration (a SHA256 digest)
|
||||
// @param key the HMAC key
|
||||
// @param keySize
|
||||
// @param counter the running counter value (may be NULL)
|
||||
// @param fixed the label parameter (optional)
|
||||
// @param fixedSize
|
||||
//
|
||||
void RIOT_KDF_SHA256(
|
||||
uint8_t *out,
|
||||
const uint8_t *key,
|
||||
size_t keySize,
|
||||
uint32_t *counter,
|
||||
const uint8_t *fixed,
|
||||
size_t fixedSize
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2001, Aaron D. Gifford
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holder nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTOR(S) BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT).
|
||||
//
|
||||
#ifndef __RIOT_CRYPTO_SHA256_H__
|
||||
#define __RIOT_CRYPTO_SHA256_H__
|
||||
|
||||
#include "RiotTarget.h"
|
||||
|
||||
typedef int asb;
|
||||
|
||||
typedef uint8_t sha2_uint8_t; // Exactly 1 byte
|
||||
typedef uint32_t sha2_word32; // Exactly 4 bytes
|
||||
typedef uint64_t sha2_word64; // Exactly 8 bytes
|
||||
|
||||
#define SHA256_BLOCK_LENGTH 64
|
||||
#define SHA256_DIGEST_LENGTH 32
|
||||
|
||||
typedef uint64_t hashMagic_t;
|
||||
|
||||
#if HOST_IS_LITTLE_ENDIAN
|
||||
#define HASH_MAGIC_VALUE (0x4078746368736168LL)
|
||||
#else
|
||||
#define HASH_MAGIC_VALUE (0x6861736863747840LL)
|
||||
#endif
|
||||
|
||||
typedef struct _RIOT_SHA256_CONTEXT {
|
||||
uint32_t state[8];
|
||||
hashMagic_t magic;
|
||||
uint64_t bitcount;
|
||||
uint8_t buffer[SHA256_BLOCK_LENGTH];
|
||||
} RIOT_SHA256_CONTEXT;
|
||||
|
||||
//
|
||||
// Initialize the hash context
|
||||
// @param context the hash context
|
||||
//
|
||||
void RIOT_SHA256_Init(RIOT_SHA256_CONTEXT *context);
|
||||
|
||||
//
|
||||
// Update the digest using the specific bytes
|
||||
// @param context the hash context
|
||||
// @param buf the bytes to digest
|
||||
// @param bufSize the number of bytes to digest
|
||||
//
|
||||
void RIOT_SHA256_Update(RIOT_SHA256_CONTEXT *context,
|
||||
const sha2_uint8_t *data, size_t len);
|
||||
|
||||
//
|
||||
// Retrieve the final digest
|
||||
// @param context the hash context
|
||||
// @param digest the buffer to hold the digest. Must be of size SHA256_DIGEST_LENGTH
|
||||
//
|
||||
void RIOT_SHA256_Final(RIOT_SHA256_CONTEXT *context, sha2_uint8_t *digest);
|
||||
|
||||
//
|
||||
// Hash a block of data
|
||||
// @param context the hash context
|
||||
// @param buf the buffer containing the data to hash
|
||||
// @param bufSize the number of bytes in the buffer
|
||||
// @param digest the buffer to hold the digest. Must be of size SHA256_DIGEST_LENGTH
|
||||
//
|
||||
void RIOT_SHA256_Block_ctx(RIOT_SHA256_CONTEXT *context,
|
||||
const uint8_t *buf, size_t bufSize,
|
||||
uint8_t *digest);
|
||||
|
||||
//
|
||||
// Hash a block of data
|
||||
// @param buf the buffer containing the data to hash
|
||||
// @param bufSize the number of bytes in the buffer
|
||||
// @param digest the buffer to hold the digest. Must be of size SHA256_DIGEST_LENGTH
|
||||
//
|
||||
void RIOT_SHA256_Block(const uint8_t *buf, size_t bufSize,
|
||||
uint8_t *digest);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
#ifndef _RIOT_TARGET_H
|
||||
#define _RIOT_TARGET_H
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2012-2014, AllSeen Alliance. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
//
|
||||
// 4-MAY-2015; RIoT adaptation (DennisMa;MSFT).
|
||||
//
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
// TODO: Fix this so we actually get asserts on non-MSFT platforms
|
||||
#ifndef _MSC_VER
|
||||
#define assert(expr) ((void)0)
|
||||
#else
|
||||
#include <assert.h>
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#if _MSC_VER >= 1600 /* MSVC 2010 or higher */
|
||||
#include <stdint.h>
|
||||
#else
|
||||
typedef signed char int8_t; // 8-bit signed integer
|
||||
typedef unsigned char uint8_t; // 8-bit unsigned integer
|
||||
typedef signed short int16_t; // 16-bit signed integer
|
||||
typedef unsigned short uint16_t; // 16-bit unsigned integer
|
||||
typedef signed int int32_t; // 32-bit signed integer
|
||||
typedef unsigned int uint32_t; // 32-bit unsigned integer
|
||||
typedef signed long long int64_t; // 64-bit signed integer
|
||||
typedef unsigned long long uint64_t; // 64-bit unsigned integer
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// This macro is used to handle LIB_EXPORT of function and variable names in lieu
|
||||
// of a .def file. Visual Studio requires that functions be explicity exported and
|
||||
// imported.
|
||||
# define LIB_EXPORT __declspec(dllexport) // VS compatible version
|
||||
# define LIB_IMPORT __declspec(dllimport)
|
||||
// This is defined to indicate a function that does not return. Microsoft compilers
|
||||
// do not support the _Noretrun function parameter.
|
||||
# define NORETURN __declspec(noreturn)
|
||||
# define INLINE __inline
|
||||
#endif // _MSC_VER
|
||||
|
||||
#ifndef true
|
||||
#define true (1)
|
||||
#endif
|
||||
|
||||
#ifndef false
|
||||
#define false (0)
|
||||
#endif
|
||||
|
||||
#ifndef YES
|
||||
#define YES (1)
|
||||
#endif
|
||||
|
||||
#ifndef NO
|
||||
#define NO (0)
|
||||
#endif
|
||||
|
||||
#define WORD_ALIGN(x) ((x & 0x3) ? ((x >> 2) + 1) << 2 : x)
|
||||
#define HOST_IS_LITTLE_ENDIAN true
|
||||
#define HOST_IS_BIG_ENDIAN false
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
extern uint8_t dbgCONFIGUREME;
|
||||
extern uint8_t dbgINIT;
|
||||
extern uint8_t dbgNET;
|
||||
extern uint8_t dbgTARGET_CRYPTO;
|
||||
extern uint8_t dbgTARGET_NVRAM;
|
||||
extern uint8_t dbgTARGET_UTIL;
|
||||
|
||||
#endif
|
||||
|
||||
#define inline __inline
|
||||
|
||||
// Main method allows argc, argv
|
||||
#define MAIN_ALLOWS_ARGS
|
||||
|
||||
#ifdef ALL_SYMBOLS
|
||||
# define static
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,71 @@
|
|||
#ifndef _RIOT_X509_BLDR_H
|
||||
#define _RIOT_X509_BLDR_H
|
||||
|
||||
#include "RiotCrypt.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RIOT_X509_SNUM_LEN 0x05
|
||||
|
||||
// Const x509 "to be signed" data
|
||||
typedef struct
|
||||
{
|
||||
uint8_t SerialNum[RIOT_X509_SNUM_LEN];
|
||||
const char *IssuerCommon;
|
||||
const char *IssuerOrg;
|
||||
const char *IssuerCountry;
|
||||
const char *ValidFrom;
|
||||
const char *ValidTo;
|
||||
const char *SubjectCommon;
|
||||
const char *SubjectOrg;
|
||||
const char *SubjectCountry;
|
||||
} RIOT_X509_TBS_DATA;
|
||||
|
||||
int
|
||||
X509GetDEREncodedTBS(
|
||||
DERBuilderContext *Tbs,
|
||||
RIOT_X509_TBS_DATA *TbsData,
|
||||
RIOT_ECC_PUBLIC *AliasKeyPub,
|
||||
RIOT_ECC_PUBLIC *DevIdKeyPub,
|
||||
uint8_t *Fwid,
|
||||
uint32_t FwidLen
|
||||
);
|
||||
|
||||
int
|
||||
X509MakeAliasCert(
|
||||
DERBuilderContext *AliasCert,
|
||||
RIOT_ECC_SIGNATURE *TbsSig
|
||||
);
|
||||
|
||||
int
|
||||
X509GetDEREccPub(
|
||||
DERBuilderContext *Context,
|
||||
RIOT_ECC_PUBLIC Pub
|
||||
);
|
||||
|
||||
int
|
||||
X509GetDEREcc(
|
||||
DERBuilderContext *Context,
|
||||
RIOT_ECC_PUBLIC Pub,
|
||||
RIOT_ECC_PRIVATE Priv
|
||||
);
|
||||
|
||||
int
|
||||
X509GetDERCsrTbs(
|
||||
DERBuilderContext *Context,
|
||||
RIOT_X509_TBS_DATA *TbsData,
|
||||
RIOT_ECC_PUBLIC *DeviceIDPub
|
||||
);
|
||||
|
||||
int
|
||||
X509GetDERCsr(
|
||||
DERBuilderContext *Context,
|
||||
RIOT_ECC_SIGNATURE *Signature
|
||||
);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,28 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#ifndef _RIOT_DLL_H
|
||||
#define _RIOT_DLL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef RIOT_EXPORTS
|
||||
#define RIOT_API __declspec(dllexport)
|
||||
#else
|
||||
#define RIOT_API __declspec(dllimport)
|
||||
#endif
|
||||
|
||||
RIOT_API void RiotStart(const BYTE *, const uint32_t, const TCHAR *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,41 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#ifndef _RIOT_STATUS_H
|
||||
#define _RIOT_STATUS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum RIOT_STATUS {
|
||||
RIOT_SUCCESS = 0,
|
||||
RIOT_FAILURE = RIOT_SUCCESS + 0x80,
|
||||
RIOT_INVALID_PARAMETER,
|
||||
RIOT_LOAD_MODULE_FAILED,
|
||||
RIOT_BAD_FORMAT,
|
||||
RIOT_INVALID_BOOT_MODE,
|
||||
RIOT_INVALID_STATE,
|
||||
RIOT_INVALID_METADATA,
|
||||
RIOT_INVALID_DEVICE_ID,
|
||||
RIOT_INVALID_MODULE,
|
||||
RIOT_INVALID_MODULE_DIGEST,
|
||||
RIOT_MODULE_UPDATE_FAILED,
|
||||
RIOT_METADATA_WRITE_FAILED,
|
||||
RIOT_STATE_UPDATE_FAILED,
|
||||
RIOT_INVALID_VENDOR_SIGNING_KEY,
|
||||
RIOT_INVALID_VENDOR_SIGNATURE,
|
||||
RIOT_INVALID_DEVICE_SIGNATURE,
|
||||
RIOT_INVALID_TICKET_SIGNATURE,
|
||||
RIOT_MODULE_UPDATE_NOT_APPROVED,
|
||||
RIOT_FAILED_UPDATE_POLICY,
|
||||
} RIOT_STATUS;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,24 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#include "stdafx.h"
|
||||
|
||||
BOOL APIENTRY DllMain( HMODULE hModule,
|
||||
DWORD ul_reason_for_call,
|
||||
LPVOID lpReserved
|
||||
)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#include "stdafx.h"
|
|
@ -0,0 +1,19 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "targetver.h"
|
||||
#include <stdio.h>
|
||||
#include <tchar.h>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include "RIoT.h"
|
||||
#include "RiotDerEnc.h"
|
||||
#include "RiotX509Bldr.h"
|
||||
|
||||
#include "RIoTSim.h"
|
|
@ -0,0 +1,8 @@
|
|||
/*(Copyright)
|
||||
|
||||
Microsoft Copyright 2017
|
||||
Confidential Information
|
||||
|
||||
*/
|
||||
#pragma once
|
||||
#include <SDKDDKVer.h>
|
Загрузка…
Ссылка в новой задаче