Maxim Integrated / Mbed OS MAXREFDES155#

Dependencies:   MaximInterface

Factory.cpp

Committer:
IanBenzMaxim
Date:
2017-04-06
Revision:
9:40dd19da90c3
Parent:
0:33d4e66780c0
Child:
13:6a6225690c2e

File content as of revision 9:40dd19da90c3:

/*******************************************************************************
* 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 (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 (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;
}