Maxim Integrated / Mbed OS MAXREFDES155#

Dependencies:   MaximInterface

Revision:
0:33d4e66780c0
Child:
9:40dd19da90c3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Factory.cpp	Fri Feb 24 11:23:12 2017 -0600
@@ -0,0 +1,297 @@
+/*******************************************************************************
+* Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a
+* copy of this software and associated documentation files (the "Software"),
+* to deal in the Software without restriction, including without limitation
+* the rights to use, copy, modify, merge, publish, distribute, sublicense,
+* and/or sell copies of the Software, and to permit persons to whom the
+* Software is furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included
+* in all copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+* IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
+* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+* OTHER DEALINGS IN THE SOFTWARE.
+*
+* Except as contained in this notice, the name of Maxim Integrated
+* Products, Inc. shall not be used except as stated in the Maxim Integrated
+* Products, Inc. Branding Policy.
+*
+* The mere transfer of this software does not imply any licenses
+* of trade secrets, proprietary technology, copyrights, patents,
+* trademarks, maskwork rights, or any other form of intellectual
+* property whatsoever. Maxim Integrated Products, Inc. retains all
+* ownership rights.
+*******************************************************************************/
+
+#include "DS2476.hpp"
+#include "SensorNode.hpp"
+#include "Factory.hpp"
+
+// Authority (web server) public key x-component.
+static const DS28C36::Page authPublicKeyX = {
+    0x7A, 0xB9, 0xCD, 0x00, 0x3F, 0x42, 0xF3, 0x30, 0x76, 0x25, 0x9B, 0x6B, 0xFD, 0xC2, 0x6D, 0xE2,
+    0xDB, 0x59, 0xA8, 0xD9, 0xE0, 0x68, 0x3E, 0x1B, 0xFF, 0x50, 0xCB, 0x6C, 0x18, 0xB6, 0xF2, 0xEB
+};
+
+// Authority (web server) public key y-component.
+static const DS28C36::Page authPublicKeyY = {
+    0x7F, 0xFC, 0xEE, 0xDD, 0x77, 0xE9, 0x63, 0x07, 0x62, 0x37, 0x33, 0x81, 0x17, 0x16, 0x58, 0x75,
+    0x12, 0x88, 0x85, 0x58, 0x57, 0xC0, 0x15, 0xB8, 0x08, 0xDE, 0xB2, 0x3B, 0xD7, 0x8A, 0x9D, 0x2C
+};
+
+// Authority (web server) private key.
+static const DS28C36::Page authPrivateKey = {
+    0xC5, 0x45, 0x5F, 0xFB, 0x45, 0xEA, 0x77, 0x0B, 0xF1, 0x1B, 0xE5, 0xD2, 0x21, 0xAD, 0x35, 0xF5,
+    0x0B, 0x61, 0x7F, 0x66, 0xDB, 0xA0, 0xBD, 0xB6, 0x64, 0x75, 0x21, 0x4E, 0xB0, 0x98, 0x2D, 0x8E
+};
+
+// Master secret for SHA-256 HMAC authentication.
+static const DS28C36::Page masterSecret = {
+    0x6D, 0x52, 0xB6, 0x15, 0xDC, 0x80, 0xCF, 0xB1, 0x25, 0xB0, 0x76, 0xB7, 0x7C, 0xAC, 0x00, 0xF2,
+    0xBC, 0x19, 0xBE, 0xD3, 0x2F, 0x9D, 0xC1, 0x42, 0x2A, 0xA5, 0xF6, 0xAE, 0x71, 0xF2, 0x25, 0xB6
+};
+
+static const DS28C36::Page zeroPage = { };
+
+static DS28C36::CmdResult generateRandomPage(DS28C36 & ds28c36, DS28C36::Page & page)
+{
+    DS28C36::Buffer data;
+    DS28C36::CmdResult result = ds28c36.readRng(page.size(), data);
+    if (result == DS28C36::Success)
+    {
+        std::copy(data.begin(), data.end(), page.begin());
+    }
+    return result;
+}
+
+bool provisionAuthenticator(DS28C36 & ds28c36)
+{
+    DS28C36::CmdResult result = DS28C36::Success;
+    
+    // Page 0 - 15
+    for (unsigned int pageNum = DS28C36::UserData0; pageNum <= DS28C36::UserData15; pageNum++)
+    {
+        result = ds28c36.writeMemory(pageNum, zeroPage);
+        if (result != DS28C36::Success)
+            return false;
+    }
+    // Page 16, 17, 22
+    DS28C36::Page page;
+    result = generateRandomPage(ds28c36, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = ds28c36.writeMemory(DS28C36::PublicKeyAX, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = generateRandomPage(ds28c36, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = ds28c36.writeMemory(DS28C36::PublicKeyAY, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = generateRandomPage(ds28c36, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = ds28c36.writeMemory(DS28C36::PrivateKeyA, page);
+    if (result != DS28C36::Success)
+        return false;
+    // Page 18, 19, 23
+    result = generateRandomPage(ds28c36, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = ds28c36.writeMemory(DS28C36::PublicKeyBX, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = generateRandomPage(ds28c36, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = ds28c36.writeMemory(DS28C36::PublicKeyBY, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = generateRandomPage(ds28c36, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = ds28c36.writeMemory(DS28C36::PrivateKeyB, page);
+    if (result != DS28C36::Success)
+        return false;
+    // Page 20, 21, 24
+    result = generateRandomPage(ds28c36, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = ds28c36.writeMemory(DS28C36::PublicKeyCX, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = generateRandomPage(ds28c36, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = ds28c36.writeMemory(DS28C36::PublicKeyCY, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = generateRandomPage(ds28c36, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = ds28c36.writeMemory(DS28C36::PrivateKeyC, page);
+    if (result != DS28C36::Success)
+        return false;
+    // Page 25
+    result = ds28c36.writeMemory(DS28C36::SecretA, masterSecret);
+    if (result != DS28C36::Success)
+        return false;
+    result = ds28c36.writeBuffer(DS28C36::Buffer(32, 0x00));
+    if (result != DS28C36::Success)
+        return false;
+    result = ds28c36.computeAndLockSha2Secret(DS28C36::UserData0, DS28C36::SecretNumA, DS28C36::SecretNumA, false);
+    if (result != DS28C36::Success)
+        return false;
+    // Page 26
+    result = generateRandomPage(ds28c36, page);
+    if (result != DS28C36::Success)
+        return false;
+    result = ds28c36.writeMemory(DS28C36::SecretB, page);
+    if (result != DS28C36::Success)
+        return false;
+    // Page 28
+    result = ds28c36.setPageProtection(DS28C36::RomOptions, DS28C36::PageProtection(DS28C36::PageProtection::APH));
+    if (result != DS28C36::Success)
+        return false;
+    // Page 29
+    result = ds28c36.setPageProtection(DS28C36::GpioControl, DS28C36::PageProtection(DS28C36::PageProtection::APH));
+    if (result != DS28C36::Success)
+        return false;
+        
+    return true;
+}
+
+bool provisionCoprocessor(DS2476 & ds2476)
+{    
+    // Page 0, 1
+    DS2476::CmdResult result = ds2476.writeMemory(DS2476::UserData0, zeroPage);
+    if (result != DS2476::Success)
+        return false;
+    result = ds2476.writeMemory(DS2476::UserData1, zeroPage);
+    if (result != DS2476::Success)
+        return false;
+    // Page 2 - 13
+    DS2476::Page page;
+    for (unsigned int pageNum = DS2476::UserData2; pageNum <= DS2476::UserData13; pageNum++)
+    {
+        result = generateRandomPage(ds2476, page);
+        if (result != DS2476::Success)
+            return false;
+        result = ds2476.writeMemory(pageNum, page);
+        if (result != DS2476::Success)
+            return false;
+    }
+    // Page 16, 17, 22
+    result = ds2476.generateEcc256KeyPair(DS2476::KeyNumA, false);
+    if (result != DS2476::Success)
+        return false;
+    // Page 18, 19, 23
+    result = generateRandomPage(ds2476, page);
+    if (result != DS2476::Success)
+        return false;
+    result = ds2476.writeMemory(DS2476::PublicKeyBX, page);
+    if (result != DS2476::Success)
+        return false;
+    result = generateRandomPage(ds2476, page);
+    if (result != DS2476::Success)
+        return false;
+    result = ds2476.writeMemory(DS2476::PublicKeyBY, page);
+    if (result != DS2476::Success)
+        return false;
+    result = generateRandomPage(ds2476, page);
+    if (result != DS2476::Success)
+        return false;
+    result = ds2476.writeMemory(DS2476::PrivateKeyB, page);
+    if (result != DS2476::Success)
+        return false;
+    // Page 20, 21, 24
+    result = ds2476.writeMemory(DS2476::PublicKeyCX, authPublicKeyX);
+    if (result != DS2476::Success)
+        return false;
+    result = ds2476.writeMemory(DS2476::PublicKeyCY, authPublicKeyY);
+    if (result != DS2476::Success)
+        return false;
+    result = ds2476.writeMemory(DS2476::PrivateKeyC, authPrivateKey);
+    if (result != DS2476::Success)
+        return false;
+    // Page 25
+    result = ds2476.writeMemory(DS2476::SecretA, masterSecret);
+    if (result != DS2476::Success)
+        return false;
+    // Page 26
+    result = generateRandomPage(ds2476, page);
+    if (result != DS2476::Success)
+        return false;
+    result = ds2476.writeMemory(DS2476::SecretB, page);
+    if (result != DS2476::Success)
+        return false;
+    // Page 29
+    /*result = ds2476.setPageProtection(DS2476::GpioControl, DS2476::PageProtection(DS2476::PageProtection::APH));
+    if (result != DS2476::Success)
+        return false;*/
+    // Page 14, 15
+    DS2476::Buffer publicKeyA;
+    publicKeyA.reserve(page.size() * 2 + 1);
+    result = ds2476.readMemory(DS2476::PublicKeyAX, page);
+    if (result != DS2476::Success)
+        return false;
+    publicKeyA.assign(page.begin(), page.end());
+    result = ds2476.readMemory(DS2476::PublicKeyAY, page);
+    if (result != DS2476::Success)
+        return false;
+    publicKeyA.insert(publicKeyA.end(), page.begin(), page.end());
+    publicKeyA.insert(publicKeyA.end(), 0x00); // Customization
+    result = ds2476.writeBuffer(publicKeyA);
+    if (result != DS2476::Success)
+        return false;
+    DS2476::Signature writeCertificate;
+    result = ds2476.generateEcdsaSignature(DS2476::KeyNumC, writeCertificate);
+    if (result != DS2476::Success)
+        return false;
+    result = ds2476.writeMemory(DS2476::UserData14, writeCertificate.r);
+    if (result != DS2476::Success)
+        return false;
+    result = ds2476.writeMemory(DS2476::UserData15, writeCertificate.s);
+    if (result != DS2476::Success)
+        return false;
+    // Remove Private Key C and set protection
+    result = generateRandomPage(ds2476, page);
+    if (result != DS2476::Success)
+        return false;
+    result = ds2476.writeMemory(DS2476::PrivateKeyC, page);
+    if (result != DS2476::Success)
+        return false;
+    /*result = ds2476.setPageProtection(DS2476::PublicKeyCX, DS2476::PageProtection(DS2476::PageProtection::AUTH));
+    if (result != DS2476::Success)
+        return false;*/
+    
+    return true;
+}
+
+bool checkAuthenticatorProvisioned(DS28C36 & ds28c36, bool & provisioned)
+{
+    DS28C36::PageProtection protection;
+    DS28C36::CmdResult result = ds28c36.readPageProtection(DS28C36::GpioControl, protection);
+    if (result != DS28C36::Success)
+        return false;
+    provisioned = protection.protectionEnabled(DS28C36::PageProtection::APH);
+    return true;
+}
+
+bool checkCoprocessorProvisioned(DS2476 & ds2476, bool & provisioned)
+{
+    DS2476::Page page;
+    DS2476::CmdResult result = ds2476.readMemory(DS2476::PublicKeyCX, page);
+    if (result != DS2476::Success)
+        return false;
+    provisioned = (page == authPublicKeyX);
+    return true;
+}