This commit is contained in:
Dennis Mattoon 2017-03-23 20:42:44 -07:00
Родитель 857d386b73
Коммит ee09fe471b
57 изменённых файлов: 7609 добавлений и 172 удалений

Просмотреть файл

@ -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>

55
Reference/DICE RIoT.sln Normal file
Просмотреть файл

@ -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

157
Reference/DICE/DICE.vcxproj Normal file
Просмотреть файл

@ -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>

210
Reference/DICE/DiceCore.cpp Normal file
Просмотреть файл

@ -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;
}

470
Reference/DICE/DiceSha256.c Normal file
Просмотреть файл

@ -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);
}

114
Reference/DICE/DiceSha256.h Normal file
Просмотреть файл

@ -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"

8
Reference/DICE/stdafx.h Normal file
Просмотреть файл

@ -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>

53
Reference/FW/Loader.cpp Normal file
Просмотреть файл

@ -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;
}

29
Reference/FW/Loader.h Normal file
Просмотреть файл

@ -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

113
Reference/FW/Loader.vcxproj Normal file
Просмотреть файл

@ -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>

24
Reference/FW/dllmain.cpp Normal file
Просмотреть файл

@ -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;
}

7
Reference/FW/stdafx.cpp Normal file
Просмотреть файл

@ -0,0 +1,7 @@
/*(Copyright)
Microsoft Copyright 2017
Confidential Information
*/
#include "stdafx.h"

15
Reference/FW/stdafx.h Normal file
Просмотреть файл

@ -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"

8
Reference/FW/targetver.h Normal file
Просмотреть файл

@ -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>