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.
Dependents: mbed_DS28EC20_GPIO
DS28C36_DS2476.cpp
00001 /******************************************************************************* 00002 * Copyright (C) 2017 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 <algorithm> 00034 #include <MaximInterface/Links/I2CMaster.hpp> 00035 #include <MaximInterface/Utilities/Error.hpp> 00036 #include <MaximInterface/Utilities/RomId.hpp> 00037 #include "DS28C36_DS2476.hpp" 00038 00039 namespace MaximInterface { 00040 00041 using namespace Ecc256; 00042 using std::copy; 00043 00044 static error_code convertResultByte(uint_least8_t resultByte) { 00045 error_code errorCode; 00046 if (resultByte != 0xAA) { 00047 errorCode.assign((resultByte == 0x00) 00048 ? static_cast<int>(DS28C36::AuthenticationError) 00049 : resultByte, 00050 DS28C36::errorCategory()); 00051 } 00052 return errorCode; 00053 } 00054 00055 const int DS28C36::publicKeyAxPage; 00056 const int DS28C36::publicKeyAyPage; 00057 const int DS28C36::publicKeyBxPage; 00058 const int DS28C36::publicKeyByPage; 00059 const int DS28C36::publicKeyCxPage; 00060 const int DS28C36::publicKeyCyPage; 00061 const int DS28C36::privateKeyAPage; 00062 const int DS28C36::privateKeyBPage; 00063 const int DS28C36::privateKeyCPage; 00064 const int DS28C36::secretAPage; 00065 const int DS28C36::secretBPage; 00066 const int DS28C36::decrementCounterPage; 00067 const int DS28C36::romOptionsPage; 00068 const int DS28C36::gpioControlPage; 00069 const int DS28C36::publicKeySxPage; 00070 const int DS28C36::publicKeySyPage; 00071 const int DS28C36::memoryPages; 00072 00073 error_code DS28C36::writeMemory(int pageNum, Page::const_span page) { 00074 if (pageNum < 0 || pageNum >= memoryPages) { 00075 return make_error_code(InvalidParameterError); 00076 } 00077 00078 uint_least8_t buffer[1 + Page::size]; 00079 buffer[0] = pageNum; 00080 copy(page.begin(), page.end(), buffer + 1); 00081 error_code result = writeCommand(0x96, buffer); 00082 if (!result) { 00083 sleep(writeMemoryTimeMs); 00084 result = readFixedLengthResponse(make_span(buffer, 1)); 00085 if (!result) { 00086 result = convertResultByte(buffer[0]); 00087 } 00088 } 00089 return result; 00090 } 00091 00092 error_code DS28C36::readMemory(int pageNum, Page::span page) { 00093 if (pageNum < 0 || pageNum >= memoryPages) { 00094 return make_error_code(InvalidParameterError); 00095 } 00096 00097 const uint_least8_t parameter = pageNum; 00098 error_code result = writeCommand(0x69, make_span(¶meter, 1)); 00099 if (!result) { 00100 sleep(readMemoryTimeMs); 00101 array<uint_least8_t, 1 + Page::size> response; 00102 result = readFixedLengthResponse(response); 00103 if (!result) { 00104 result = convertResultByte(response[0]); 00105 copy(response.begin() + 1, response.end(), page.begin()); 00106 } 00107 } 00108 return result; 00109 } 00110 00111 error_code DS28C36::writeBuffer(span<const uint_least8_t> data) { 00112 return writeCommand(0x87, data); 00113 } 00114 00115 error_code DS28C36::readBuffer(std::vector<uint_least8_t> & data) { 00116 error_code result = writeCommand(0x5A); 00117 if (!result) { 00118 data.resize(80); 00119 span<uint_least8_t> dataSpan(data); 00120 result = readVariableLengthResponse(dataSpan); 00121 if (result) { 00122 data.clear(); 00123 } else { 00124 data.resize(dataSpan.size()); 00125 } 00126 } 00127 return result; 00128 } 00129 00130 error_code DS28C36::readPageProtection(int pageNum, 00131 PageProtection & protection) { 00132 if (pageNum < 0 || pageNum >= memoryPages) { 00133 return make_error_code(InvalidParameterError); 00134 } 00135 00136 uint_least8_t buffer = pageNum; 00137 error_code result = writeCommand(0xAA, make_span(&buffer, 1)); 00138 if (!result) { 00139 sleep(readMemoryTimeMs); 00140 result = readFixedLengthResponse(make_span(&buffer, 1)); 00141 if (!result) { 00142 protection = buffer; 00143 } 00144 } 00145 return result; 00146 } 00147 00148 error_code DS28C36::setPageProtection(int pageNum, 00149 const PageProtection & protection) { 00150 if (pageNum < 0 || pageNum >= memoryPages) { 00151 return make_error_code(InvalidParameterError); 00152 } 00153 00154 uint_least8_t buffer[] = {static_cast<uint_least8_t>(pageNum), 00155 static_cast<uint_least8_t>(protection.to_ulong())}; 00156 error_code result = writeCommand(0xC3, buffer); 00157 if (!result) { 00158 sleep(writeMemoryTimeMs); 00159 result = readFixedLengthResponse(make_span(buffer, 1)); 00160 if (!result) { 00161 result = convertResultByte(buffer[0]); 00162 } 00163 } 00164 return result; 00165 } 00166 00167 error_code DS28C36::decrementCounter() { 00168 error_code result = writeCommand(0xC9); 00169 if (!result) { 00170 sleep(writeMemoryTimeMs); 00171 uint_least8_t response; 00172 result = readFixedLengthResponse(make_span(&response, 1)); 00173 if (!result) { 00174 result = convertResultByte(response); 00175 } 00176 } 00177 return result; 00178 } 00179 00180 error_code DS28C36::readRng(span<uint_least8_t> data) { 00181 if ((data.size() < 1) || (data.size() > 64)) { 00182 return make_error_code(InvalidParameterError); 00183 } 00184 00185 data[0] = static_cast<uint_least8_t>(data.size() - 1); 00186 error_code result = writeCommand(0xD2, data.first(1)); 00187 if (!result) { 00188 sleep(sha256ComputationTimeMs); 00189 result = readFixedLengthResponse(data); 00190 } 00191 return result; 00192 } 00193 00194 error_code DS28C36::encryptedReadMemory(int pageNum, SecretNum secretNum, 00195 EncryptionChallenge::span challenge, 00196 Page::span data) { 00197 if (pageNum < 0 || pageNum >= memoryPages) { 00198 return make_error_code(InvalidParameterError); 00199 } 00200 00201 const uint_least8_t parameter = (secretNum << 6) | pageNum; 00202 error_code result = writeCommand(0x4B, make_span(¶meter, 1)); 00203 if (!result) { 00204 sleep(readMemoryTimeMs + sha256ComputationTimeMs); 00205 uint_least8_t response[1 + EncryptionChallenge::size + Page::size]; 00206 result = readFixedLengthResponse(response); 00207 if (!result) { 00208 result = convertResultByte(response[0]); 00209 const uint_least8_t * begin = response + 1; 00210 const uint_least8_t * end = begin + challenge.size(); 00211 copy(begin, end, challenge.begin()); 00212 begin = end; 00213 end = begin + data.size(); 00214 copy(begin, end, data.begin()); 00215 } 00216 } 00217 return result; 00218 } 00219 00220 error_code DS28C36::computeAndReadPageAuthentication(int pageNum, 00221 AuthType authType) { 00222 if (pageNum < 0 || pageNum >= memoryPages) { 00223 return make_error_code(InvalidParameterError); 00224 } 00225 00226 const uint_least8_t parameter = (authType << 5) | pageNum; 00227 return writeCommand(0xA5, make_span(¶meter, 1)); 00228 } 00229 00230 error_code 00231 DS28C36::computeAndReadPageAuthentication(int pageNum, KeyNum keyNum, 00232 Signature::span signature) { 00233 AuthType authType; 00234 switch (keyNum) { 00235 case KeyNumA: 00236 authType = EcdsaWithKeyA; 00237 break; 00238 case KeyNumB: 00239 authType = EcdsaWithKeyB; 00240 break; 00241 case KeyNumC: 00242 authType = EcdsaWithKeyC; 00243 break; 00244 default: 00245 return make_error_code(InvalidParameterError); 00246 } 00247 error_code result = computeAndReadPageAuthentication(pageNum, authType); 00248 if (!result) { 00249 sleep(readMemoryTimeMs + generateEcdsaSignatureTimeMs); 00250 uint_least8_t response[1 + 2 * Scalar::size]; 00251 result = readFixedLengthResponse(response); 00252 if (!result) { 00253 result = convertResultByte(response[0]); 00254 const uint_least8_t * begin = response + 1; 00255 const uint_least8_t * end = begin + signature.s.size(); 00256 copy(begin, end, signature.s.begin()); 00257 begin = end; 00258 end = begin + signature.r.size(); 00259 copy(begin, end, signature.r.begin()); 00260 } 00261 } 00262 return result; 00263 } 00264 00265 error_code DS28C36::computeAndReadPageAuthentication(int pageNum, 00266 SecretNum secretNum, 00267 Sha256::Hash::span hmac) { 00268 AuthType authType; 00269 switch (secretNum) { 00270 case SecretNumA: 00271 authType = HmacWithSecretA; 00272 break; 00273 case SecretNumB: 00274 authType = HmacWithSecretB; 00275 break; 00276 case SecretNumS: 00277 authType = HmacWithSecretS; 00278 break; 00279 default: 00280 return make_error_code(InvalidParameterError); 00281 } 00282 error_code result = computeAndReadPageAuthentication(pageNum, authType); 00283 if (!result) { 00284 sleep(readMemoryTimeMs + sha256ComputationTimeMs); 00285 array<uint_least8_t, 1 + Sha256::Hash::size> response; 00286 result = readFixedLengthResponse(response); 00287 if (!result) { 00288 result = convertResultByte(response[0]); 00289 copy(response.begin() + 1, response.end(), hmac.begin()); 00290 } 00291 } 00292 return result; 00293 } 00294 00295 error_code DS28C36::authenticatedSha2WriteMemory(int pageNum, 00296 SecretNum secretNum, 00297 Page::const_span page) { 00298 if (pageNum < 0 || pageNum >= memoryPages) { 00299 return make_error_code(InvalidParameterError); 00300 } 00301 00302 uint_least8_t buffer[1 + Page::size]; 00303 buffer[0] = (secretNum << 6) | pageNum; 00304 copy(page.begin(), page.end(), buffer + 1); 00305 error_code result = writeCommand(0x99, buffer); 00306 if (!result) { 00307 sleep(writeMemoryTimeMs + (2 * sha256ComputationTimeMs)); 00308 result = readFixedLengthResponse(make_span(buffer, 1)); 00309 if (!result) { 00310 result = convertResultByte(buffer[0]); 00311 } 00312 } 00313 return result; 00314 } 00315 00316 error_code DS28C36::computeAndLockSha2Secret(int pageNum, SecretNum msecretNum, 00317 SecretNum dsecretNum, 00318 bool writeProtectEnable) { 00319 // User pages only 00320 if (pageNum < 0 || pageNum > 15) { 00321 return make_error_code(InvalidParameterError); 00322 } 00323 00324 uint_least8_t buffer[] = { 00325 static_cast<uint_least8_t>((dsecretNum << 6) | (msecretNum << 4) | 00326 pageNum), 00327 static_cast<uint_least8_t>(writeProtectEnable ? 0x80 : 0x00)}; 00328 error_code result = writeCommand(0x3C, buffer); 00329 if (!result) { 00330 sleep(sha256ComputationTimeMs + 00331 ((writeProtectEnable ? 2 : 1) * writeMemoryTimeMs)); 00332 result = readFixedLengthResponse(make_span(buffer, 1)); 00333 if (!result) { 00334 result = convertResultByte(buffer[0]); 00335 } 00336 } 00337 return result; 00338 } 00339 00340 error_code DS28C36::generateEcc256KeyPair(KeyNum keyNum, 00341 bool writeProtectEnable) { 00342 if (keyNum == KeyNumS) { 00343 return make_error_code(InvalidParameterError); 00344 } 00345 00346 uint_least8_t buffer = keyNum; 00347 if (writeProtectEnable) { 00348 buffer |= 0x80; 00349 } 00350 error_code result = writeCommand(0xCB, make_span(&buffer, 1)); 00351 if (!result) { 00352 sleep(generateEccKeyPairTimeMs); 00353 result = readFixedLengthResponse(make_span(&buffer, 1)); 00354 if (!result) { 00355 result = convertResultByte(buffer); 00356 } 00357 } 00358 return result; 00359 } 00360 00361 error_code DS28C36::computeMultiblockHash(bool firstBlock, bool lastBlock, 00362 span<const uint_least8_t> data) { 00363 const span<const uint_least8_t>::index_type maxDataSize = 64; 00364 00365 if (data.size() < 1 || data.size() > maxDataSize) { 00366 return make_error_code(InvalidParameterError); 00367 } 00368 00369 uint_least8_t buffer[1 + maxDataSize]; 00370 buffer[0] = 0; 00371 if (firstBlock) { 00372 buffer[0] |= 0x40; 00373 } 00374 if (lastBlock) { 00375 buffer[0] |= 0x80; 00376 } 00377 copy(data.begin(), data.end(), buffer + 1); 00378 error_code result = writeCommand(0x33, make_span(buffer, data.size() + 1)); 00379 if (!result) { 00380 sleep(sha256ComputationTimeMs); 00381 result = readFixedLengthResponse(make_span(buffer, 1)); 00382 if (!result) { 00383 result = convertResultByte(buffer[0]); 00384 } 00385 } 00386 return result; 00387 } 00388 00389 error_code DS28C36::verifyEcdsaSignature(KeyNum keyNum, HashType hashType, 00390 Signature::const_span signature, 00391 PioState pioa, PioState piob) { 00392 uint_least8_t buffer[1 + 2 * Scalar::size]; 00393 buffer[0] = keyNum | (hashType << 2); 00394 if (pioa != Unchanged) { 00395 buffer[0] |= 0x20; 00396 } 00397 if (pioa == Conducting) { 00398 buffer[0] |= 0x10; 00399 } 00400 if (piob != Unchanged) { 00401 buffer[0] |= 0x80; 00402 } 00403 if (piob == Conducting) { 00404 buffer[0] |= 0x40; 00405 } 00406 uint_least8_t * bufferIt = 00407 copy(signature.r.begin(), signature.r.end(), buffer + 1); 00408 copy(signature.s.begin(), signature.s.end(), bufferIt); 00409 error_code result = writeCommand(0x59, buffer); 00410 if (!result) { 00411 sleep(verifyEsdsaSignatureOrComputeEcdhTimeMs + 00412 ((hashType == DataInBuffer) ? sha256ComputationTimeMs : 0)); 00413 result = readFixedLengthResponse(make_span(buffer, 1)); 00414 if (!result) { 00415 result = convertResultByte(buffer[0]); 00416 } 00417 } 00418 return result; 00419 } 00420 00421 error_code 00422 DS28C36::authenticateEcdsaPublicKey(bool authWrites, bool ecdh, KeyNum keyNum, 00423 int csOffset, 00424 Signature::const_span signature) { 00425 if (((keyNum != KeyNumA) && (keyNum != KeyNumB)) || (csOffset < 0) || 00426 (csOffset > 31)) { 00427 return make_error_code(InvalidParameterError); 00428 } 00429 00430 uint_least8_t buffer[1 + 2 * Scalar::size]; 00431 buffer[0] = (csOffset << 3) | (keyNum << 2); 00432 if (ecdh) { 00433 buffer[0] |= 0x02; 00434 } 00435 if (authWrites) { 00436 buffer[0] |= 0x01; 00437 } 00438 uint_least8_t * bufferIt = 00439 copy(signature.r.begin(), signature.r.end(), buffer + 1); 00440 copy(signature.s.begin(), signature.s.end(), bufferIt); 00441 error_code result = writeCommand(0xA8, buffer); 00442 if (!result) { 00443 sleep((ecdh ? 2 : 1) * verifyEsdsaSignatureOrComputeEcdhTimeMs); 00444 result = readFixedLengthResponse(make_span(buffer, 1)); 00445 if (!result) { 00446 result = convertResultByte(buffer[0]); 00447 } 00448 } 00449 return result; 00450 } 00451 00452 error_code DS28C36::authenticatedEcdsaWriteMemory(int pageNum, 00453 Page::const_span page) { 00454 if (pageNum < 0 || pageNum >= memoryPages) { 00455 return make_error_code(InvalidParameterError); 00456 } 00457 00458 uint_least8_t buffer[1 + Page::size]; 00459 buffer[0] = pageNum; 00460 copy(page.begin(), page.end(), buffer + 1); 00461 error_code result = writeCommand(0x89, buffer); 00462 if (!result) { 00463 sleep(verifyEsdsaSignatureOrComputeEcdhTimeMs + writeMemoryTimeMs + 00464 sha256ComputationTimeMs); 00465 result = readFixedLengthResponse(make_span(buffer, 1)); 00466 if (!result) { 00467 result = convertResultByte(buffer[0]); 00468 } 00469 } 00470 return result; 00471 } 00472 00473 error_code DS28C36::writeCommand(uint_least8_t command, 00474 span<const uint_least8_t> parameters) { 00475 error_code result = master->start(address_); 00476 if (result) { 00477 master->stop(); 00478 return result; 00479 } 00480 result = master->writeByte(command); 00481 if (result) { 00482 master->stop(); 00483 return result; 00484 } 00485 if (!parameters.empty()) { 00486 result = master->writeByte(static_cast<uint_least8_t>(parameters.size())); 00487 if (result) { 00488 master->stop(); 00489 return result; 00490 } 00491 result = master->writeBlock(parameters); 00492 if (result) { 00493 master->stop(); 00494 return result; 00495 } 00496 } 00497 result = master->stop(); 00498 return result; 00499 } 00500 00501 error_code DS28C36::readVariableLengthResponse(span<uint_least8_t> & response) { 00502 error_code result = master->start(address_ | 1); 00503 if (result) { 00504 master->stop(); 00505 return result; 00506 } 00507 uint_least8_t length; 00508 result = master->readByte(I2CMaster::Ack, length); 00509 if (result) { 00510 master->stop(); 00511 return result; 00512 } 00513 if (length > response.size()) { 00514 master->stop(); 00515 return make_error_code(InvalidResponseError); 00516 } 00517 response = response.first(length); 00518 if (!response.empty()) { 00519 result = master->readBlock(I2CMaster::Nack, response); 00520 if (result) { 00521 master->stop(); 00522 return result; 00523 } 00524 } 00525 result = master->stop(); 00526 return result; 00527 } 00528 00529 error_code DS28C36::readFixedLengthResponse(span<uint_least8_t> response) { 00530 const span<uint_least8_t>::index_type requestedResponseSize = response.size(); 00531 error_code result = readVariableLengthResponse(response); 00532 if (!result && response.size() != requestedResponseSize) { 00533 result = make_error_code(InvalidResponseError); 00534 } 00535 return result; 00536 } 00537 00538 const error_category & DS28C36::errorCategory() { 00539 static class : public error_category { 00540 public: 00541 virtual const char * name() const { return "DS28C36"; } 00542 00543 virtual std::string message(int condition) const { 00544 switch (condition) { 00545 case ProtectionError: 00546 return "Protection Error"; 00547 00548 case InvalidParameterError: 00549 return "Invalid Parameter Error"; 00550 00551 case InvalidSequenceError: 00552 return "Invalid Sequence Error"; 00553 00554 case InvalidEcdsaInputOrResultError: 00555 return "Invalid ECDSA Input or Result Error"; 00556 00557 case AuthenticationError: 00558 return "Authentication Error"; 00559 00560 case InvalidResponseError: 00561 return "Invalid Response Error"; 00562 00563 default: 00564 return defaultErrorMessage(condition); 00565 } 00566 } 00567 } instance; 00568 return instance; 00569 } 00570 00571 error_code DS2476::generateEcdsaSignature(KeyNum keyNum, 00572 Signature::span signature) { 00573 if (keyNum == KeyNumS) { 00574 return make_error_code(InvalidParameterError); 00575 } 00576 00577 const uint_least8_t parameter = keyNum; 00578 error_code result = writeCommand(0x1E, make_span(¶meter, 1)); 00579 if (!result) { 00580 sleep(generateEcdsaSignatureTimeMs); 00581 uint_least8_t response[1 + 2 * Scalar::size]; 00582 result = readFixedLengthResponse(response); 00583 if (!result) { 00584 result = convertResultByte(response[0]); 00585 const uint_least8_t * begin = response + 1; 00586 const uint_least8_t * end = begin + signature.s.size(); 00587 copy(begin, end, signature.s.begin()); 00588 begin = end; 00589 end = begin + signature.r.size(); 00590 copy(begin, end, signature.r.begin()); 00591 } 00592 } 00593 return result; 00594 } 00595 00596 error_code DS2476::computeSha2UniqueSecret(SecretNum msecretNum) { 00597 uint_least8_t buffer = msecretNum << 4; 00598 error_code result = writeCommand(0x55, make_span(&buffer, 1)); 00599 if (!result) { 00600 sleep(sha256ComputationTimeMs); 00601 result = readFixedLengthResponse(make_span(&buffer, 1)); 00602 if (!result) { 00603 convertResultByte(buffer); 00604 } 00605 } 00606 return result; 00607 } 00608 00609 error_code DS2476::computeSha2Hmac(Sha256::Hash::span hmac) { 00610 error_code result = writeCommand(0x2D); 00611 if (!result) { 00612 sleep(sha256ComputationTimeMs); 00613 array<uint_least8_t, 1 + Sha256::Hash::size> response; 00614 result = readFixedLengthResponse(response); 00615 if (!result) { 00616 result = convertResultByte(response[0]); 00617 copy(response.begin() + 1, response.end(), hmac.begin()); 00618 } 00619 } 00620 return result; 00621 } 00622 00623 error_code computeMultiblockHash(DS28C36 & ds28c36, 00624 span<const uint_least8_t> data) { 00625 error_code result; 00626 span<const uint_least8_t>::index_type dataIdx = 0; 00627 while (dataIdx < data.size() && !result) { 00628 const span<const uint_least8_t>::index_type remainingSize = 00629 data.size() - dataIdx; 00630 const span<const uint_least8_t>::index_type chunkSize = 00631 std::min<span<const uint_least8_t>::index_type>(remainingSize, 64); 00632 result = 00633 ds28c36.computeMultiblockHash(dataIdx == 0, remainingSize == chunkSize, 00634 data.subspan(dataIdx, chunkSize)); 00635 dataIdx += chunkSize; 00636 } 00637 return result; 00638 } 00639 00640 error_code verifyEcdsaSignature(DS28C36 & ds28c36, DS28C36::KeyNum publicKey, 00641 span<const uint_least8_t> data, 00642 Signature::const_span signature, 00643 DS28C36::PioState pioa, 00644 DS28C36::PioState piob) { 00645 error_code result = computeMultiblockHash(ds28c36, data); 00646 if (!result) { 00647 result = ds28c36.verifyEcdsaSignature(publicKey, DS28C36::THASH, signature, 00648 pioa, piob); 00649 } 00650 return result; 00651 } 00652 00653 error_code verifyEcdsaSignature(DS28C36 & ds28c36, 00654 PublicKey::const_span publicKey, 00655 span<const uint_least8_t> data, 00656 Signature::const_span signature, 00657 DS28C36::PioState pioa, 00658 DS28C36::PioState piob) { 00659 error_code result = 00660 ds28c36.writeMemory(DS28C36::publicKeySxPage, publicKey.x); 00661 if (!result) { 00662 result = ds28c36.writeMemory(DS28C36::publicKeySyPage, publicKey.y); 00663 } 00664 if (!result) { 00665 result = verifyEcdsaSignature(ds28c36, DS28C36::KeyNumS, data, signature, 00666 pioa, piob); 00667 } 00668 return result; 00669 } 00670 00671 error_code readRomIdAndManId(DS28C36 & ds28c36, RomId::span romId, 00672 ManId::span manId) { 00673 DS28C36::Page::array page; 00674 error_code result = ds28c36.readMemory(DS28C36::romOptionsPage, page); 00675 if (!result) { 00676 const DS28C36::RomOptions romOptions(page); 00677 copy(romOptions.romId(), romId); 00678 copy(romOptions.manId(), manId); 00679 } 00680 return result; 00681 } 00682 00683 error_code enableCoprocessor(DS2476 & ds2476) { 00684 DS2476::Page::array page; 00685 error_code result = ds2476.readMemory(DS2476::gpioControlPage, page); 00686 if (!result) { 00687 DS2476::GpioControl gpioControl(page); 00688 if (!gpioControl.pioaConducting()) { 00689 gpioControl.setPioaConducting(true); 00690 result = ds2476.writeMemory(DS2476::gpioControlPage, page); 00691 } 00692 } 00693 return result; 00694 } 00695 00696 error_code enableRomId(DS2476 & ds2476) { 00697 DS2476::Page::array page; 00698 error_code result = ds2476.readMemory(DS2476::romOptionsPage, page); 00699 if (!result) { 00700 DS2476::RomOptions romOptions(page); 00701 if (!romOptions.romBlockDisable()) { 00702 romOptions.setRomBlockDisable(true); 00703 result = ds2476.writeMemory(DS2476::romOptionsPage, page); 00704 } 00705 } 00706 return result; 00707 } 00708 00709 static void setAnonymous(RomId::span romId) { 00710 std::fill(romId.begin(), romId.end(), 0xFF); 00711 } 00712 00713 DS28C36::PageAuthenticationData & 00714 DS28C36::PageAuthenticationData::setAnonymousRomId() { 00715 setAnonymous(romId()); 00716 return *this; 00717 } 00718 00719 DS28C36::EncryptionHmacData & DS28C36::EncryptionHmacData::setAnonymousRomId() { 00720 setAnonymous(romId()); 00721 return *this; 00722 } 00723 00724 } // namespace MaximInterface
Generated on Tue Jul 12 2022 23:29:45 by
1.7.2