DeepCover Embedded Security in IoT: Public-key Secured Data Paths

Dependencies:   MaximInterface

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Factory.cpp Source File

Factory.cpp

00001 /*******************************************************************************
00002 * Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved.
00003 *
00004 * Permission is hereby granted, free of charge, to any person obtaining a
00005 * copy of this software and associated documentation files (the "Software"),
00006 * to deal in the Software without restriction, including without limitation
00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008 * and/or sell copies of the Software, and to permit persons to whom the
00009 * Software is furnished to do so, subject to the following conditions:
00010 *
00011 * The above copyright notice and this permission notice shall be included
00012 * in all copies or substantial portions of the Software.
00013 *
00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020 * OTHER DEALINGS IN THE SOFTWARE.
00021 *
00022 * Except as contained in this notice, the name of Maxim Integrated
00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024 * Products, Inc. Branding Policy.
00025 *
00026 * The mere transfer of this software does not imply any licenses
00027 * of trade secrets, proprietary technology, copyrights, patents,
00028 * trademarks, maskwork rights, or any other form of intellectual
00029 * property whatsoever. Maxim Integrated Products, Inc. retains all
00030 * ownership rights.
00031 *******************************************************************************/
00032 
00033 #include <MaximInterfaceDevices/DS28C36_DS2476.hpp>
00034 #include "Factory.hpp"
00035 
00036 #define TRY MaximInterfaceCore_TRY
00037 #define TRY_VALUE MaximInterfaceCore_TRY_VALUE
00038 
00039 using MaximInterfaceCore::none;
00040 using MaximInterfaceCore::Result;
00041 using MaximInterfaceDevices::DS28C36;
00042 using MaximInterfaceDevices::DS2476;
00043 
00044 // Authority (web server) public key x-component.
00045 static const DS28C36::Page::array authPublicKeyX = {
00046     0x7A, 0xB9, 0xCD, 0x00, 0x3F, 0x42, 0xF3, 0x30, 0x76, 0x25, 0x9B,
00047     0x6B, 0xFD, 0xC2, 0x6D, 0xE2, 0xDB, 0x59, 0xA8, 0xD9, 0xE0, 0x68,
00048     0x3E, 0x1B, 0xFF, 0x50, 0xCB, 0x6C, 0x18, 0xB6, 0xF2, 0xEB};
00049 
00050 // Authority (web server) public key y-component.
00051 static const DS28C36::Page::array authPublicKeyY = {
00052     0x7F, 0xFC, 0xEE, 0xDD, 0x77, 0xE9, 0x63, 0x07, 0x62, 0x37, 0x33,
00053     0x81, 0x17, 0x16, 0x58, 0x75, 0x12, 0x88, 0x85, 0x58, 0x57, 0xC0,
00054     0x15, 0xB8, 0x08, 0xDE, 0xB2, 0x3B, 0xD7, 0x8A, 0x9D, 0x2C};
00055 
00056 // Authority (web server) private key.
00057 static const DS28C36::Page::array authPrivateKey = {
00058     0xC5, 0x45, 0x5F, 0xFB, 0x45, 0xEA, 0x77, 0x0B, 0xF1, 0x1B, 0xE5,
00059     0xD2, 0x21, 0xAD, 0x35, 0xF5, 0x0B, 0x61, 0x7F, 0x66, 0xDB, 0xA0,
00060     0xBD, 0xB6, 0x64, 0x75, 0x21, 0x4E, 0xB0, 0x98, 0x2D, 0x8E};
00061 
00062 // Master secret for SHA-256 HMAC authentication.
00063 static const DS28C36::Page::array masterSecret = {
00064     0x6D, 0x52, 0xB6, 0x15, 0xDC, 0x80, 0xCF, 0xB1, 0x25, 0xB0, 0x76,
00065     0xB7, 0x7C, 0xAC, 0x00, 0xF2, 0xBC, 0x19, 0xBE, 0xD3, 0x2F, 0x9D,
00066     0xC1, 0x42, 0x2A, 0xA5, 0xF6, 0xAE, 0x71, 0xF2, 0x25, 0xB6};
00067 
00068 Result<void> provisionAuthenticator(DS28C36 & ds28c36) {
00069   // Check if already provisioned;
00070   if (const Result<DS28C36::PageProtection> protection =
00071           ds28c36.readPageProtection(DS28C36::gpioControlPage)) {
00072     if (protection.value().test(DS28C36::APH)) {
00073       return none;
00074     }
00075   } else {
00076     return protection.error();
00077   }
00078 
00079   const DS28C36::Page::array zeroPage = {};
00080   // Page 0 - 15
00081   for (int pageNum = 0; pageNum <= 15; ++pageNum) {
00082     TRY(ds28c36.writeMemory(pageNum, zeroPage));
00083   }
00084   // Page 16, 17, 22
00085   DS28C36::Page::array page;
00086   TRY(ds28c36.readRng(page));
00087   TRY(ds28c36.writeMemory(DS28C36::publicKeyAxPage, page));
00088   TRY(ds28c36.readRng(page));
00089   TRY(ds28c36.writeMemory(DS28C36::publicKeyAyPage, page));
00090   TRY(ds28c36.readRng(page));
00091   TRY(ds28c36.writeMemory(DS28C36::privateKeyAPage, page));
00092   // Page 18, 19, 23
00093   TRY(ds28c36.readRng(page));
00094   TRY(ds28c36.writeMemory(DS28C36::publicKeyBxPage, page));
00095   TRY(ds28c36.readRng(page));
00096   TRY(ds28c36.writeMemory(DS28C36::publicKeyByPage, page));
00097   TRY(ds28c36.readRng(page));
00098   TRY(ds28c36.writeMemory(DS28C36::privateKeyBPage, page));
00099   // Page 20, 21, 24
00100   TRY(ds28c36.readRng(page));
00101   TRY(ds28c36.writeMemory(DS28C36::publicKeyCxPage, page));
00102   TRY(ds28c36.readRng(page));
00103   TRY(ds28c36.writeMemory(DS28C36::publicKeyCyPage, page));
00104   TRY(ds28c36.readRng(page));
00105   TRY(ds28c36.writeMemory(DS28C36::privateKeyCPage, page));
00106   // Page 25
00107   TRY(ds28c36.writeMemory(DS28C36::secretAPage, masterSecret));
00108   TRY(ds28c36.writeBuffer(zeroPage));
00109   TRY(ds28c36.computeAndLockSha2Secret(0, DS28C36::SecretNumA,
00110                                        DS28C36::SecretNumA, false));
00111   // Page 26
00112   TRY(ds28c36.readRng(page));
00113   TRY(ds28c36.writeMemory(DS28C36::secretBPage, page));
00114   // Page 28
00115   TRY(ds28c36.setPageProtection(DS28C36::romOptionsPage, DS28C36::APH));
00116   // Page 29
00117   TRY(ds28c36.setPageProtection(DS28C36::gpioControlPage, DS28C36::APH));
00118   return none;
00119 }
00120 
00121 Result<void> provisionCoprocessor(DS2476 & ds2476) {
00122   // Check if already provisioned;
00123   if (const Result<DS2476::Page::array> page =
00124           ds2476.readMemory(DS2476::publicKeyCxPage)) {
00125     if (page.value() == authPublicKeyX) {
00126       return none;
00127     }
00128   } else {
00129     return page.error();
00130   }
00131 
00132   // Page 0, 1
00133   const DS2476::Page::array zeroPage = {};
00134   TRY(ds2476.writeMemory(0, zeroPage));
00135   TRY(ds2476.writeMemory(1, zeroPage));
00136   // Page 2 - 13
00137   DS2476::Page::array page;
00138   for (int pageNum = 2; pageNum <= 13; ++pageNum) {
00139     TRY(ds2476.readRng(page));
00140     TRY(ds2476.writeMemory(pageNum, page));
00141   }
00142   // Page 16, 17, 22
00143   TRY(ds2476.generateEcc256KeyPair(DS2476::KeyNumA, false));
00144   // Page 18, 19, 23
00145   TRY(ds2476.readRng(page));
00146   TRY(ds2476.writeMemory(DS2476::publicKeyBxPage, page));
00147   TRY(ds2476.readRng(page));
00148   TRY(ds2476.writeMemory(DS2476::publicKeyByPage, page));
00149   TRY(ds2476.readRng(page));
00150   TRY(ds2476.writeMemory(DS2476::privateKeyBPage, page));
00151   // Page 20, 21, 24
00152   TRY(ds2476.writeMemory(DS2476::publicKeyCxPage, authPublicKeyX));
00153   TRY(ds2476.writeMemory(DS2476::publicKeyCyPage, authPublicKeyY));
00154   TRY(ds2476.writeMemory(DS2476::privateKeyCPage, authPrivateKey));
00155   // Page 25
00156   TRY(ds2476.writeMemory(DS2476::secretAPage, masterSecret));
00157   // Page 26
00158   TRY(ds2476.readRng(page));
00159   TRY(ds2476.writeMemory(DS2476::secretBPage, page));
00160   // Page 29
00161   // TRY(ds2476.setPageProtection(DS2476::gpioControlPage, DS2476::APH));
00162   // Page 14, 15
00163   std::vector<uint8_t> publicKeyA;
00164   publicKeyA.reserve(page.size() * 2 + 1);
00165   TRY_VALUE(page, ds2476.readMemory(DS2476::publicKeyAxPage));
00166   publicKeyA.assign(page.begin(), page.end());
00167   TRY_VALUE(page, ds2476.readMemory(DS2476::publicKeyAyPage));
00168   publicKeyA.insert(publicKeyA.end(), page.begin(), page.end());
00169   publicKeyA.insert(publicKeyA.end(), 0x00); // Customization
00170   TRY(ds2476.writeBuffer(publicKeyA));
00171   MaximInterfaceCore::Ecc256::Signature::array writeCertificate;
00172   TRY_VALUE(writeCertificate, ds2476.generateEcdsaSignature(DS2476::KeyNumC));
00173   TRY(ds2476.writeMemory(14, writeCertificate.r));
00174   TRY(ds2476.writeMemory(15, writeCertificate.s));
00175   // Remove Private Key C and set protection
00176   TRY(ds2476.readRng(page));
00177   TRY(ds2476.writeMemory(DS2476::privateKeyCPage, page));
00178   // TRY(ds2476.setPageProtection(DS2476::publicKeyCxPage,
00179   //                              DS2476::PageProtection::AUTH));
00180   
00181   return none;
00182 }