Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: MaximInterface
Diff: Factory.cpp
- 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; +}