├── .gitignore ├── LICENSE ├── README.md ├── examples ├── Crypto_Examples │ └── Crypto_Examples.ino └── random │ └── random.ino ├── extras └── atmel_license.txt ├── library.properties └── src ├── api ├── AtEccX08.cpp ├── AtEccX08.h ├── AtSha204.cpp ├── AtSha204.h ├── CryptoBuffer.cpp └── CryptoBuffer.h ├── ateccX08-atmel ├── eccX08_comm.c ├── eccX08_comm.h ├── eccX08_comm_marshaling.c ├── eccX08_comm_marshaling.h ├── eccX08_config.h ├── eccX08_i2c.c ├── eccX08_lib_return_codes.h └── eccX08_physical.h ├── atsha204-atmel ├── Makefile ├── sha204_comm.c ├── sha204_comm.h ├── sha204_comm_marshaling.c ├── sha204_comm_marshaling.h ├── sha204_config.h ├── sha204_examples.c ├── sha204_examples.h ├── sha204_helper.c ├── sha204_helper.h ├── sha204_i2c.c ├── sha204_lib_return_codes.h ├── sha204_physical.h └── sha204_swi.c ├── common-atmel ├── avr_compatible.h ├── bitbang_config.h ├── bitbang_phys.c ├── i2c_phys.c ├── i2c_phys.h ├── swi_phys.h ├── timer_utilities.c ├── timer_utilities.h ├── uart_config.h └── uart_phys.c ├── cryptoauth.h ├── keywords.txt └── softcrypto ├── sha256-asm.S ├── sha256.h ├── sha_256.cpp └── sha_256.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | *.elf 30 | *.hex 31 | /TAGS 32 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | 167 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | cryptoauth-arduino 2 | ================== 3 | 4 | An Arduino library for Atmel's CryptoAuthentication Devices (ATSHA204x, 5 | ATECC108x and ATECC508A). 6 | 7 | This version is a fork of the original Cryptotronix cryptoauth-arduino library with the following changes: 8 | 9 | * Replace Atmel code with updated code that supports the ATECC508 chips 10 | * Update API to implement additional functionality to retrieve chip info, lock individual slots, add key selection to sign and verify functions. 11 | * Provide a comprehensive example/demo sketch covering personalization, public and private key generation, SHA256 hash generation, message signing and verification functions. 12 | 13 | Original Readme warning below: 14 | 15 | 16 | ***WARNING*** 17 | ------------- 18 | 19 | This software is in pre-alpha! It's probably best that you first configure the chip on a linux based platform using the [EClet driver](https://github.com/cryptotronix/eclet) for the 108 or the [hashlet driver](https://github.com/cryptotronix/hashlet) for the 204. Once configured, you'll have an easier time of using this library. 20 | 21 | In the example file is the basic get random function which will return a fixed test pattern if you haven't personalized your device. Once personalized (with the above linux drivers) you will get 32 bytes of random. 22 | 23 | Feel free to create a new issue for bugs and features requests. Pull requests are welcome too :) 24 | 25 | License 26 | --- 27 | 28 | Atmel's code is licensed under a custom open source license. It is 29 | included under `extras`. I share the interpretation of the license as 30 | [these guys](https://github.com/Pinoccio/library-atmel-lwm/blob/master/README.md). 31 | -------------------------------------------------------------------------------- /examples/random/random.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // Change to AtSha204() to use the 204 4 | AtEccX08 sha = AtEccX08(); 5 | 6 | void setup() { 7 | Serial.begin(9600); 8 | sha.enableDebug(&Serial); 9 | } 10 | 11 | void loop() { 12 | /* If you haven't personalized your device yet, you will recieve 13 | * this on your serial terminal: 14 | ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000ffff0000 15 | Success 16 | 17 | Otherwise, you'll get actual random bytes. 18 | */ 19 | if (0 == sha.getRandom(0)){ 20 | Serial.println("Success"); 21 | sha.rsp.dumpHex(&Serial); 22 | } 23 | else{ 24 | Serial.println("Failure"); 25 | } 26 | 27 | delay(1000); 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /extras/atmel_license.txt: -------------------------------------------------------------------------------- 1 | License Agreement (Crypto authentication UTILITIES) 2 | 3 | IT IS IMPORTANT THAT YOU READ THIS AGREEMENT CAREFULLY AND 4 | COMPLETELY. This License Agreement (“Agreement”) is a legally binding 5 | agreement between your employer (“Licensee”) and Atmel Corporation 6 | (“Atmel”). By clicking the “I Accept” button on this page or by 7 | downloading, installing or using any of the software available for 8 | download on this page (“Licensed Software”), you are indicating that 9 | you are binding Licensee to the terms of this Agreement, and that you 10 | are duly authorized by Licensee to do so. If you are not authorized to 11 | bind Licensee to the terms of this Agreement, or if Licensee does not 12 | agree to be bound by all of the terms of this Agreement, do not click 13 | the “I Accept” button and do not download, install or use any such 14 | software. 15 | 16 | 1. License Grant. Subject to the terms and conditions of this 17 | Agreement, Atmel grants Licensee a non-exclusive, non-transferable, 18 | non-sublicensable, limited license to: (a) internally use the Licensed 19 | Software solely in connection with an Atmel integrated circuit; and 20 | (b) to make one copy of the Licensed Software solely for backup 21 | purposes. 22 | 23 | 2. Restrictions. Licensee will not, and will have no right to, (a) 24 | use, copy, reproduce, modify, create derivative works of, sell, 25 | distribute, disclose or otherwise exploit any Licensed Software, 26 | except as expressly set forth in Section 1, or (b) decompile or 27 | otherwise reverse engineer any Licensed Software that is not provided 28 | in source code form, or otherwise derive or attempt to derive the 29 | source code of any such Licensed Software. Licensee will not remove, 30 | obscure or alter any trademark, copyright or other proprietary rights 31 | and ownership notices of Atmel or any of its licensors that appear in 32 | any Licensed Software, and Licensee will reproduce all such trademarks 33 | and proprietary rights and ownership notices on all copies of Licensed 34 | Software made by Licensee. 35 | 36 | 3. Ownership; Reserved Rights; License to Atmel. Atmel and its 37 | licensors will retain title to and ownership of the Licensed Software, 38 | including, without limitation, all copyrights, patents, trade secrets 39 | and other intellectual property rights in and to the Licensed 40 | Software. Nothing contained in this Agreement will be construed as 41 | conferring upon Licensee or any third party (whether by implication, 42 | operation of law, estoppel or otherwise) any right or license not 43 | expressly granted by Atmel to Licensee under this Agreement. 44 | 45 | 4. Term and Termination. This Agreement will remain in effect until 46 | terminated. Atmel or Licensee may terminate this Agreement at any time 47 | with written notice to the other. This Agreement will automatically 48 | terminate if Licensee fails to comply with the terms and conditions of 49 | this Agreement 50 | 51 | 5. Effect of Termination. Upon any termination of this Agreement, (a) 52 | all licenses granted to Licensee under this Agreement will terminate, 53 | (b) Licensee will discontinue all use of the Licensed Software, (c) 54 | Licensee will destroy all copies of the Licensed Software, and (d) the 55 | rights and obligations of the parties under Sections 2, 3, 5, 6, 7, 8, 56 | 9 and 10 will survive such termination. 57 | 58 | 6. Warranty Disclaimer. THE LICENSED SOFTWARE IS PROVIDED TO LICENSEE 59 | “AS IS” AND “WITH ALL FAULTS.” ATMEL DOES NOT MAKE, AND ATMEL HEREBY 60 | DISCLAIMS, ANY REPRESENTATIONS OR WARRANTIES OF ANY KIND (WHETHER 61 | EXPRESS, IMPLIED, STATUTORY OR OTHERWISE) IN CONNECTION WITH THE 62 | LICENSED SOFTWARE OR ANY OTHER ASPECT OF THIS AGREEMENT, INCLUDING, 63 | WITHOUT LIMITATION, ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS 64 | FOR A PARTICULAR PURPOSE, TITLE OR NON-INFRINGEMENT OF THIRD PARTY 65 | RIGHTS, AND ANY WARRANTIES THAT MAY ARISE FROM COURSE OF DEALING, 66 | COURSE OF PERFORMANCE OR USAGE OF TRADE. Atmel will have no 67 | obligation under this Agreement to correct any bugs, defects or errors 68 | in the Licensed Software. 69 | 70 | 7. Limitation of Liability. TO THE EXTENT PERMITTED BY APPLICABLE LAW, 71 | IN NO EVENT WILL ATMEL BE LIABLE TO LICENSEE OR ANY THIRD PARTY 72 | (WHETHER SUCH LIABILITY IS BASED ON CONTRACT, NEGLIGENCE, STRICT 73 | LIABILITY, OTHER TORT THEORY, CONTRIBUTION, BREACH OF WARRANTY, OR 74 | OTHER LEGAL OR EQUITABLE THEORY) FOR ANY SPECIAL, INDIRECT, 75 | INCIDENTAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES, OR ANY 76 | DAMAGES FOR LOSS OF PROFITS, LOSS OR INTERRUPTION OF BUSINESS, OR LOSS 77 | OF DATA, ARISING OUT OF OR RELATING TO THE LICENSED SOFTWARE OR ANY 78 | OTHER ASPECT OF THIS AGREEMENT, EVEN IF ATMEL has been advised of or 79 | should have known of the possibility of such damages. 80 | 81 | To the extent permitted by applicable law, IN NO EVENT WILL 82 | ATMEL’S TOTAL LIABILITY ARISING OUT OF OR RELATED TO THE 83 | LICENSED SOFTWARE OR ANY OTHER ASPECT OF THIS AGREEMENT 84 | (WHETHER UNDER CONTRACT, NEGLIGENCE, STRICT LIABILITY, 85 | CONTRIBUTION, BREACH OF WARRANTY, OR OTHER LEGAL OR EQUITABLE 86 | THEORY) EXCEED THE GREATER OF (A) THE AGGREGATE OF ALL LICENSE 87 | FEES PAID BY LICENSEE TO ATMEL FOR THE LICENSED SOFTWARE AND 88 | (B) ONE HUNDRED DOLLARS ($100). 89 | 90 | 8. Compliance with Laws; Export. Licensee will comply with the laws 91 | and regulations of the United States and all other relevant 92 | jurisdictions in connection with its activities related to the 93 | Licensed Software. Without limitation of the foregoing, Licensee 94 | acknowledges that certain laws and regulations of the United States 95 | and other jurisdictions may pertain to the export and re-export of the 96 | Licensed Software, and Licensee will not export or re-export any 97 | Licensed Software in any form without the appropriate governmental 98 | approvals, or otherwise in violation of any such laws or regulations. 99 | 100 | 9. Governing Law; Dispute Resolution. This Agreement is to be 101 | construed in accordance with and governed by the internal laws of the 102 | State of California (as permitted by Section 1646.5 of the California 103 | Civil Code or any similar successor provision), without giving effect 104 | to any choice of law rule that would cause the application of the laws 105 | of any jurisdiction other than the internal laws of the State of 106 | California to the rights and duties of the parties. This Agreement 107 | will not be governed by the U.N. Convention on the Sale of Goods, the 108 | application of which is expressly excluded. Except for actions for 109 | injunctive or other equitable relief, which may be brought in any 110 | court of competent jurisdiction, all disputes arising out of or 111 | related to this Agreement will be subject to the exclusive 112 | jurisdiction of the California state courts in Santa Clara County, 113 | California, or if there is exclusive federal jurisdiction, the United 114 | States District Court for the Northern District of California, and the 115 | Parties hereby consent to, and agree to submit to, the personal and 116 | exclusive jurisdiction and venue of such courts. 117 | 118 | 10. General. Licensee will not, and will have no right to, assign, 119 | delegate or otherwise transfer (whether voluntarily, by operation of 120 | law or otherwise) this Agreement or any of its rights or obligations 121 | hereunder to any third party without the prior written consent of 122 | Atmel, and any purported assignment, delegation or other transfer 123 | without such consent will have no force or effect. Subject to the 124 | foregoing, this Agreement will be binding upon and will inure to the 125 | benefit of the parties and their respective successors and permitted 126 | assigns. No failure of either party to enforce any right under this 127 | Agreement will be deemed a waiver of such right or any other right 128 | under this Agreement. Any waiver by a party of a breach of any 129 | provision of this Agreement by the other party hereunder will not be 130 | deemed to be a waiver of any subsequent breach of such provision or a 131 | waiver of any breach of any other provision of this Agreement. This 132 | Agreement may not be superseded, modified, or amended except in a 133 | writing signed by an officer of each party. If any provision of this 134 | Agreement is determined to be invalid, illegal or otherwise 135 | unenforceable, such provision will be enforced to the extent possible 136 | consistent with the intent of the parties, and the remaining 137 | provisions of this Agreement will remain in full force and 138 | effect. This Agreement will be fairly interpreted in accordance with 139 | its terms and without any strict construction in favor of or against 140 | either party. This Agreement will constitute the entire agreement 141 | between the parties relating to the subject matter hereof, and 142 | expressly supersedes and replaces all prior and contemporaneous 143 | agreements, proposals, quotations, negotiations and communications, 144 | written or oral, between the parties relating to such subject matter. 145 | 146 | Atmel Corporation 2325 Orchard Parkway San Jose, CA 95131 147 | http://www.atmel.com 148 | -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | name=CryptoAuth 2 | version=0.1 3 | author=Atmel Corporation, Cryptotronix, Thing Innovations 4 | maintainer=Josh Datko 5 | sentence=Device driver library for the Atmel ATSHA204, ATECC108 and ATECC508 6 | paragraph=Implements a communication layer for applications to interface with the ATSHA204, ATECC108 and ATECC508; 7 | url=https://github.com/cryptotronix/cryptoauth-arduino 8 | architectures=avr 9 | -------------------------------------------------------------------------------- /src/api/AtEccX08.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c++; c-file-style: "gnu" -*- 2 | * Copyright (C) 2014 Cryptotronix, LLC. 3 | * 4 | * This file is part of cryptoauth-arduino. 5 | * 6 | * cryptoauth-arduino is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * any later version. 10 | * 11 | * cryptoauth-arduino is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with cryptoauth-arduino. If not, see . 18 | * 19 | */ 20 | #ifndef LIB_ATECCX08_H_ 21 | #define LIB_ATECCX08_H_ 22 | 23 | #include "AtSha204.h" 24 | #include "../ateccX08-atmel/eccX08_physical.h" 25 | 26 | class AtEccX08 : public AtSha204 27 | { 28 | public: 29 | AtEccX08(); 30 | ~AtEccX08(); 31 | 32 | 33 | uint8_t wakeup(); 34 | uint8_t getRandom(bool update_seed = false); 35 | uint8_t personalize(const uint8_t * config_zone_data, uint8_t config_len, 36 | const uint8_t * otp_zone_data, uint8_t optlen); 37 | bool is_locked(const uint8_t ZONE); 38 | void burn_otp(); 39 | uint8_t lock_data_zone(); 40 | uint8_t lockKeySlot( uint8_t slotNum ); 41 | uint8_t sign(uint8_t key, uint8_t *data, int len_32); 42 | uint8_t verify(uint8_t *data, int len_32, 43 | uint8_t *pub_key, 44 | uint8_t *signature); 45 | uint8_t hash_verify(const uint8_t *data, int len, 46 | uint8_t *pub_key, 47 | uint8_t *signature); 48 | // uint8_t getPubKey(const uint8_t KEY_ID); 49 | // uint8_t genPrivateKey(const uint8_t KEY_ID); 50 | uint8_t genEccKey(const uint8_t KEY_ID, bool privateKey); 51 | uint8_t getSerialNumber(void); 52 | uint8_t getInfo(uint8_t info, uint16_t key_id); 53 | uint8_t getKeySlotConfig(void); 54 | uint8_t calculateSHA256( uint8_t *data, int len); //, uint8_t *outBuf ); 55 | 56 | 57 | protected: 58 | const uint8_t ADDRESS; 59 | const uint8_t getAddress() const; 60 | const uint8_t write(uint8_t zone, uint16_t address, uint8_t *new_value, 61 | uint8_t *mac, uint8_t size); 62 | void idle(); 63 | void burn_config(const uint8_t * data,uint8_t datalen); 64 | void burn_otp(const uint8_t * data,uint8_t datalen); 65 | 66 | uint8_t lock_config_zone(); 67 | uint8_t read_config_zone(uint8_t *config_data); 68 | int load_nonce(uint8_t *to_load, int len); 69 | int sign_tempkey(const uint8_t KEY_ID); 70 | uint8_t verify_tempkey( //const uint8_t KEY_ID, 71 | uint8_t *pub_key, 72 | uint8_t *signature); 73 | 74 | bool always_idle = true; 75 | bool always_wakeup = true; 76 | 77 | void disableIdleWake(); 78 | void enableIdleWake(); 79 | 80 | }; 81 | 82 | #endif 83 | -------------------------------------------------------------------------------- /src/api/AtSha204.cpp: -------------------------------------------------------------------------------- 1 | /* -*- mode: c++; c-file-style: "gnu" -*- 2 | * Copyright (C) 2014 Cryptotronix, LLC. 3 | * 4 | * This file is part of cryptoauth-arduino. 5 | * 6 | * cryptoauth-arduino is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * any later version. 10 | * 11 | * cryptoauth-arduino is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with cryptoauth-arduino. If not, see . 18 | * 19 | */ 20 | #include "AtSha204.h" 21 | #include "../atsha204-atmel/sha204_physical.h" 22 | #include "../atsha204-atmel/sha204_comm_marshaling.h" 23 | #include "../atsha204-atmel/sha204_lib_return_codes.h" 24 | 25 | AtSha204::AtSha204() 26 | { 27 | sha204p_init(); 28 | } 29 | 30 | 31 | AtSha204::~AtSha204() { } 32 | 33 | void AtSha204::idle() 34 | { 35 | sha204p_idle(); 36 | } 37 | 38 | uint8_t AtSha204::getRandom() 39 | { 40 | volatile uint8_t ret_code; 41 | 42 | uint8_t *random = &this->temp[SHA204_BUFFER_POS_DATA]; 43 | 44 | sha204p_wakeup(); 45 | 46 | ret_code = sha204m_random(this->command, this->temp, RANDOM_NO_SEED_UPDATE); 47 | if (ret_code == SHA204_SUCCESS) 48 | { 49 | this->rsp.copyBufferFrom(random, 32); 50 | } 51 | 52 | 53 | sha204p_idle(); 54 | return ret_code; 55 | } 56 | 57 | 58 | void AtSha204::enableDebug(Stream* stream) 59 | { 60 | this->debugStream = stream; 61 | } 62 | 63 | 64 | uint8_t AtSha204::macBasic(uint8_t *to_mac, int len) 65 | { 66 | uint16_t key_id = 0; 67 | uint8_t mode = MAC_MODE_CHALLENGE; 68 | uint8_t rc; 69 | 70 | if (MAC_CHALLENGE_SIZE != len) 71 | return SHA204_BAD_PARAM; 72 | 73 | sha204p_wakeup(); 74 | 75 | if (SHA204_SUCCESS == 76 | (rc = sha204m_mac(this->command, this->temp, mode, key_id, to_mac))) 77 | { 78 | this->rsp.copyBufferFrom(&this->temp[SHA204_BUFFER_POS_DATA], 32); 79 | } 80 | 81 | sha204p_idle(); 82 | return rc; 83 | 84 | } 85 | 86 | uint8_t AtSha204::checkMacBasic(uint8_t *to_mac, int len, uint8_t *rsp) 87 | { 88 | uint16_t key_id = 0; 89 | uint8_t mode = MAC_MODE_CHALLENGE; 90 | uint8_t other_data[13] = {0}; 91 | uint8_t rc; 92 | 93 | if (MAC_CHALLENGE_SIZE != len) 94 | return SHA204_BAD_PARAM; 95 | 96 | other_data[0] = 0x08; 97 | sha204p_wakeup(); 98 | 99 | rc = sha204m_check_mac(this->command, this->temp, 100 | mode, key_id, to_mac, rsp, other_data); 101 | 102 | sha204p_idle(); 103 | return rc; 104 | 105 | } 106 | 107 | 108 | uint8_t AtSha204::checkResponseStatus(uint8_t ret_code, uint8_t *response) const 109 | { 110 | if (ret_code != SHA204_SUCCESS) 111 | { 112 | return ret_code; 113 | } 114 | 115 | ret_code = response[SHA204_BUFFER_POS_STATUS]; 116 | 117 | return ret_code; 118 | } 119 | 120 | #define rotate_right(value, places) ((value >> places) | (value << (32 - places))) 121 | #define SHA256_BLOCK_SIZE (64) // bytes 122 | 123 | /** \brief This function creates a SHA256 digest on a little-endian system. 124 | * 125 | * Limitations: This function was implemented with the ATSHA204 CryptoAuth device 126 | * in mind. It will therefore only work for length values of len % 64 < 62. 127 | * 128 | * \param[in] len byte length of message 129 | * \param[in] message pointer to message 130 | * \param[out] digest SHA256 of message 131 | 132 | * TODO: Replace with ATSHA204 implementation 133 | */ 134 | void AtSha204::calculate_sha256(int32_t len, uint8_t *message, uint8_t *digest) 135 | { 136 | int32_t j, swap_counter, len_mod = len % sizeof(int32_t); 137 | uint32_t i, w_index; 138 | int32_t message_index = 0; 139 | uint32_t padded_len = len + 8; // 8 bytes for bit length 140 | uint32_t bit_len = len * 8; 141 | uint32_t s0, s1; 142 | uint32_t t1, t2; 143 | uint32_t maj, ch; 144 | uint32_t word_value; 145 | uint32_t rotate_register[8]; 146 | 147 | union { 148 | uint32_t w_word[SHA256_BLOCK_SIZE]; 149 | uint8_t w_byte[SHA256_BLOCK_SIZE * sizeof(int32_t)]; 150 | } w_union; 151 | 152 | uint32_t hash[] = { 153 | 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 154 | 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 155 | }; 156 | 157 | const uint32_t k[] = { 158 | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 159 | 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 160 | 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 161 | 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 162 | 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 163 | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 164 | 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 165 | 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 166 | }; 167 | 168 | // Process message. 169 | while (message_index <= padded_len) { 170 | 171 | // Break message into 64-byte blocks. 172 | w_index = 0; 173 | do { 174 | // Copy message chunk of four bytes (size of integer) into compression array. 175 | if (message_index < (len - len_mod)) { 176 | for (swap_counter = sizeof(int32_t) - 1; swap_counter >= 0; swap_counter--) 177 | // No padding needed. Swap four message bytes to chunk array. 178 | w_union.w_byte[swap_counter + w_index] = message[message_index++]; 179 | 180 | w_index += sizeof(int32_t); 181 | } 182 | else { 183 | // We reached last complete word of message {len - (len mod 4)}. 184 | // Swap remaining bytes if any, append '1' bit and pad remaining 185 | // bytes of the last word. 186 | for (swap_counter = sizeof(int32_t) - 1; 187 | swap_counter >= sizeof(int32_t) - len_mod; swap_counter--) 188 | w_union.w_byte[swap_counter + w_index] = message[message_index++]; 189 | w_union.w_byte[swap_counter + w_index] = 0x80; 190 | for (swap_counter--; swap_counter >= 0; swap_counter--) 191 | w_union.w_byte[swap_counter + w_index] = 0; 192 | 193 | // Switch to word indexing. 194 | w_index += sizeof(int32_t); 195 | w_index /= sizeof(int32_t); 196 | 197 | // Pad last block with zeros to a block length % 56 = 0 198 | // and pad the four high bytes of "len" since we work only 199 | // with integers and not with long integers. 200 | while (w_index < 15) 201 | w_union.w_word[w_index++] = 0; 202 | // Append original message length as 32-bit integer. 203 | w_union.w_word[w_index] = bit_len; 204 | // Indicate that the last block is being processed. 205 | message_index += SHA256_BLOCK_SIZE; 206 | // We are done with pre-processing last block. 207 | break; 208 | } 209 | } while (message_index % SHA256_BLOCK_SIZE); 210 | // Created one block. 211 | 212 | w_index = 16; 213 | while (w_index < SHA256_BLOCK_SIZE) { 214 | // right rotate for 32-bit variable in C: (value >> places) | (value << 32 - places) 215 | word_value = w_union.w_word[w_index - 15]; 216 | s0 = rotate_right(word_value, 7) ^ rotate_right(word_value, 18) ^ (word_value >> 3); 217 | 218 | word_value = w_union.w_word[w_index - 2]; 219 | s1 = rotate_right(word_value, 17) ^ rotate_right(word_value, 19) ^ (word_value >> 10); 220 | 221 | w_union.w_word[w_index] = w_union.w_word[w_index - 16] + s0 + w_union.w_word[w_index - 7] + s1; 222 | 223 | w_index++; 224 | } 225 | 226 | // Initialize hash value for this chunk. 227 | for (i = 0; i < 8; i++) 228 | rotate_register[i] = hash[i]; 229 | 230 | // hash calculation loop 231 | for (i = 0; i < SHA256_BLOCK_SIZE; i++) { 232 | s0 = rotate_right(rotate_register[0], 2) 233 | ^ rotate_right(rotate_register[0], 13) 234 | ^ rotate_right(rotate_register[0], 22); 235 | maj = (rotate_register[0] & rotate_register[1]) 236 | ^ (rotate_register[0] & rotate_register[2]) 237 | ^ (rotate_register[1] & rotate_register[2]); 238 | t2 = s0 + maj; 239 | s1 = rotate_right(rotate_register[4], 6) 240 | ^ rotate_right(rotate_register[4], 11) 241 | ^ rotate_right(rotate_register[4], 25); 242 | ch = (rotate_register[4] & rotate_register[5]) 243 | ^ (~rotate_register[4] & rotate_register[6]); 244 | t1 = rotate_register[7] + s1 + ch + k[i] + w_union.w_word[i]; 245 | 246 | rotate_register[7] = rotate_register[6]; 247 | rotate_register[6] = rotate_register[5]; 248 | rotate_register[5] = rotate_register[4]; 249 | rotate_register[4] = rotate_register[3] + t1; 250 | rotate_register[3] = rotate_register[2]; 251 | rotate_register[2] = rotate_register[1]; 252 | rotate_register[1] = rotate_register[0]; 253 | rotate_register[0] = t1 + t2; 254 | } 255 | 256 | // Add the hash of this block to current result. 257 | for (i = 0; i < 8; i++) 258 | hash[i] += rotate_register[i]; 259 | } 260 | 261 | // All blocks have been processed. 262 | // Concatenate the hashes to produce digest, MSB of every hash first. 263 | for (i = 0; i < 8; i++) { 264 | for (j = sizeof(int32_t) - 1; j >= 0; j--, hash[i] >>= 8) 265 | digest[i * sizeof(int32_t) + j] = hash[i] & 0xFF; 266 | } 267 | 268 | } 269 | 270 | -------------------------------------------------------------------------------- /src/api/AtSha204.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c++; c-file-style: "gnu" -*- 2 | * Copyright (C) 2014 Cryptotronix, LLC. 3 | * 4 | * This file is part of cryptoauth-arduino. 5 | * 6 | * cryptoauth-arduino is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * any later version. 10 | * 11 | * cryptoauth-arduino is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with cryptoauth-arduino. If not, see . 18 | * 19 | */ 20 | #ifndef LIB_ATSHA204_H_ 21 | #define LIB_ATSHA204_H_ 22 | 23 | #include 24 | #include "CryptoBuffer.h" 25 | #include "../atsha204-atmel/sha204_comm_marshaling.h" 26 | #include "../ateccX08-atmel/eccX08_physical.h" 27 | #include "../ateccX08-atmel/eccX08_comm.h" 28 | 29 | class AtSha204 30 | { 31 | public: 32 | AtSha204(); 33 | ~AtSha204(); 34 | 35 | CryptoBuffer rsp; 36 | uint8_t getRandom(); 37 | uint8_t macBasic(uint8_t *to_mac, int len); 38 | uint8_t checkMacBasic(uint8_t *to_mac, int len, uint8_t *rsp); 39 | void enableDebug(Stream* stream); 40 | void calculate_sha256(int32_t len, uint8_t *message, uint8_t *digest); 41 | 42 | 43 | protected: 44 | uint8_t command[ECCX08_CMD_SIZE_MAX]; 45 | uint8_t temp[ECCX08_RSP_SIZE_MAX]; 46 | Stream *debugStream = NULL; 47 | uint8_t checkResponseStatus(uint8_t ret_code, uint8_t *response) const; 48 | void idle(); 49 | 50 | }; 51 | 52 | 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/api/CryptoBuffer.cpp: -------------------------------------------------------------------------------- 1 | /* -*- mode: c++; c-file-style: "gnu" -*- 2 | * Copyright (C) 2014 Cryptotronix, LLC. 3 | * 4 | * This file is part of cryptoauth-arduino. 5 | * 6 | * cryptoauth-arduino is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * any later version. 10 | * 11 | * cryptoauth-arduino is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with cryptoauth-arduino. If not, see . 18 | * 19 | */ 20 | #include "CryptoBuffer.h" 21 | #include 22 | 23 | CryptoBuffer::CryptoBuffer() 24 | { 25 | this->clear(); 26 | } 27 | 28 | CryptoBuffer::~CryptoBuffer() { } 29 | 30 | void CryptoBuffer::clear() 31 | { 32 | memset(&this->buf[0], 0, this->getMaxBufferSize()); 33 | this->len = 0; 34 | } 35 | 36 | const int CryptoBuffer::getLength() 37 | { 38 | return this->len; 39 | } 40 | 41 | const uint8_t *CryptoBuffer::getPointer() 42 | { 43 | return this->buf; 44 | } 45 | 46 | const int CryptoBuffer::getMaxBufferSize() 47 | { 48 | return sizeof(this->buf); 49 | } 50 | 51 | void CryptoBuffer::copyBufferFrom(uint8_t *src, int len) 52 | { 53 | if (len <= this->getMaxBufferSize()) 54 | { 55 | memcpy (this->buf, src, len); 56 | this->len = len; 57 | } 58 | } 59 | 60 | const void CryptoBuffer::dumpHex(Stream* stream) 61 | { 62 | char temp[3] = {}; 63 | for (int x = 0; x < this->getLength(); x++){ 64 | sprintf(temp, "%02x",this->getPointer()[x]); 65 | stream->print(temp); 66 | } 67 | 68 | stream->write("\n"); 69 | } 70 | -------------------------------------------------------------------------------- /src/api/CryptoBuffer.h: -------------------------------------------------------------------------------- 1 | /* -*- mode: c++; c-file-style: "gnu" -*- 2 | * Copyright (C) 2014 Cryptotronix, LLC. 3 | * 4 | * This file is part of cryptoauth-arduino. 5 | * 6 | * cryptoauth-arduino is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * any later version. 10 | * 11 | * cryptoauth-arduino is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with cryptoauth-arduino. If not, see . 18 | * 19 | */ 20 | #ifndef LIB_CRYPTOBUFFER_H_ 21 | #define LIB_CRYPTOBUFFER_H_ 22 | 23 | #include 24 | #include "../ateccX08-atmel/eccX08_physical.h" 25 | class CryptoBuffer 26 | { 27 | public: 28 | CryptoBuffer(); 29 | ~CryptoBuffer(); 30 | 31 | const uint8_t *getPointer(); 32 | const int getMaxBufferSize(); 33 | const int getLength(); 34 | void copyBufferFrom(uint8_t *src, int len); 35 | const void dumpHex(Stream* stream); 36 | void clear(); 37 | 38 | protected: 39 | int len; 40 | 41 | uint8_t buf[ECCX08_RSP_SIZE_MAX]; 42 | 43 | }; 44 | 45 | 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /src/ateccX08-atmel/eccX08_comm.c: -------------------------------------------------------------------------------- 1 | // ATMEL Microcontroller Software Support - Colorado Springs, CO - 2 | // ---------------------------------------------------------------------------- 3 | // DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 4 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 5 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 6 | // DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 7 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 8 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 9 | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 10 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 11 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 12 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | // ---------------------------------------------------------------------------- 14 | 15 | /** \file 16 | * \brief Communication Layer of ECCX08 Library 17 | * \author Atmel Crypto Products 18 | * \date September 12, 2012 19 | */ 20 | #include "eccX08_comm.h" // definitions and declarations for the Communication module 21 | #include "eccX08_lib_return_codes.h" // declarations of function return codes 22 | 23 | 24 | 25 | /** \brief This function calculates CRC. 26 | * 27 | * \param[in] length number of bytes in buffer 28 | * \param[in] data pointer to data for which CRC should be calculated 29 | * \param[out] crc pointer to 16-bit CRC 30 | */ 31 | void eccX08c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc) 32 | { 33 | uint8_t counter; 34 | uint16_t crc_register = 0; 35 | uint16_t polynom = 0x8005; 36 | uint8_t shift_register; 37 | uint8_t data_bit, crc_bit; 38 | 39 | for (counter = 0; counter < length; counter++) 40 | { 41 | for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) 42 | { 43 | data_bit = (data[counter] & shift_register) ? 1 : 0; 44 | crc_bit = crc_register >> 15; 45 | crc_register <<= 1; 46 | if (data_bit != crc_bit) 47 | crc_register ^= polynom; 48 | } 49 | } 50 | 51 | crc[0] = (uint8_t) (crc_register & 0x00FF); 52 | crc[1] = (uint8_t) (crc_register >> 8); 53 | } 54 | 55 | 56 | /** \brief This function checks the consistency of a response. 57 | * \param[in] response pointer to response 58 | * \return status of the consistency check 59 | */ 60 | uint8_t eccX08c_check_crc(uint8_t *response) 61 | { 62 | uint8_t crc[ECCX08_CRC_SIZE]; 63 | uint8_t count = response[ECCX08_BUFFER_POS_COUNT]; 64 | 65 | count -= ECCX08_CRC_SIZE; 66 | eccX08c_calculate_crc(count, response, crc); 67 | 68 | return (crc[0] == response[count] && crc[1] == response[count + 1]) 69 | ? ECCX08_SUCCESS : ECCX08_BAD_CRC; 70 | } 71 | 72 | 73 | /** \brief This function wakes up a ECCX08 device 74 | * and receives a response. 75 | * \param[out] response pointer to four-byte response 76 | * \return status of the operation 77 | */ 78 | uint8_t eccX08c_wakeup(uint8_t *response) 79 | { 80 | uint8_t ret_code = eccX08p_wakeup(); 81 | if (ret_code != ECCX08_SUCCESS) 82 | return ret_code; 83 | 84 | ret_code = eccX08p_receive_response(ECCX08_RSP_SIZE_MIN, response); 85 | if (ret_code != ECCX08_SUCCESS) 86 | return ret_code; 87 | 88 | // Verify status response. 89 | if (response[ECCX08_BUFFER_POS_COUNT] != ECCX08_RSP_SIZE_MIN) 90 | ret_code = ECCX08_INVALID_SIZE; 91 | else if (response[ECCX08_BUFFER_POS_STATUS] != ECCX08_STATUS_BYTE_WAKEUP) 92 | ret_code = ECCX08_COMM_FAIL; 93 | else 94 | { 95 | if ((response[ECCX08_RSP_SIZE_MIN - ECCX08_CRC_SIZE] != 0x33) 96 | || (response[ECCX08_RSP_SIZE_MIN + 1 - ECCX08_CRC_SIZE] != 0x43)) 97 | ret_code = ECCX08_BAD_CRC; 98 | } 99 | if (ret_code != ECCX08_SUCCESS) 100 | delay_ms(ECCX08_COMMAND_EXEC_MAX); 101 | 102 | return ret_code; 103 | } 104 | 105 | 106 | /** \brief This function re-synchronizes communication. 107 | * 108 | Be aware that succeeding only after waking up the 109 | device could mean that it had gone to sleep and lost 110 | its TempKey in the process.\n 111 | Re-synchronizing communication is done in a maximum of 112 | three steps: 113 |
    114 |
  1. 115 | Try to re-synchronize without sending a Wake token. 116 | This step is implemented in the Physical layer. 117 |
  2. 118 |
  3. 119 | If the first step did not succeed send a Wake token. 120 |
  4. 121 |
  5. 122 | Try to read the Wake response. 123 |
  6. 124 |
125 | * 126 | * \param[in] size size of response buffer 127 | * \param[out] response pointer to Wake-up response buffer 128 | * \return status of the operation 129 | */ 130 | uint8_t eccX08c_resync(uint8_t size, uint8_t *response) 131 | { 132 | // Try to re-synchronize without sending a Wake token 133 | // (step 1 of the re-synchronization process). 134 | uint8_t ret_code = eccX08p_resync(size, response); 135 | if (ret_code == ECCX08_SUCCESS) 136 | return ret_code; 137 | 138 | // We lost communication. Send a Wake pulse and try 139 | // to receive a response (steps 2 and 3 of the 140 | // re-synchronization process). 141 | (void) eccX08p_sleep(); 142 | ret_code = eccX08c_wakeup(response); 143 | 144 | // Translate a return value of success into one 145 | // that indicates that the device had to be woken up 146 | // and might have lost its TempKey. 147 | return (ret_code == ECCX08_SUCCESS ? ECCX08_RESYNC_WITH_WAKEUP : ret_code); 148 | } 149 | 150 | 151 | /** \brief This function runs a communication sequence: 152 | * Append CRC to tx buffer, send command, delay, and verify response after receiving it. 153 | * 154 | * The first byte in tx buffer must be the byte count of the packet. 155 | * If CRC or count of the response is incorrect, or a command byte got "nacked" (TWI), 156 | * this function requests re-sending the response. 157 | * If the response contains an error status, this function resends the command. 158 | * 159 | * \param[in] tx_buffer pointer to command 160 | * \param[in] rx_size size of response buffer 161 | * \param[out] rx_buffer pointer to response buffer 162 | * \param[in] execution_delay Start polling for a response after this many ms . 163 | * \param[in] execution_timeout polling timeout in ms 164 | * \return status of the operation 165 | */ 166 | uint8_t eccX08c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer, 167 | uint8_t execution_delay, uint8_t execution_timeout) 168 | { 169 | uint8_t ret_code = ECCX08_FUNC_FAIL; 170 | uint8_t ret_code_resync; 171 | uint8_t n_retries_send; 172 | uint8_t n_retries_receive; 173 | uint8_t i; 174 | uint8_t status_byte; 175 | uint8_t count = tx_buffer[ECCX08_BUFFER_POS_COUNT]; 176 | uint8_t count_minus_crc = count - ECCX08_CRC_SIZE; 177 | uint16_t execution_timeout_us = (uint16_t) (execution_timeout * 1000) + ECCX08_RESPONSE_TIMEOUT; 178 | volatile uint16_t timeout_countdown; 179 | 180 | // Append CRC. 181 | eccX08c_calculate_crc(count_minus_crc, tx_buffer, tx_buffer + count_minus_crc); 182 | 183 | // Retry loop for sending a command and receiving a response. 184 | n_retries_send = ECCX08_RETRY_COUNT + 1; 185 | 186 | while ((n_retries_send-- > 0) && (ret_code != ECCX08_SUCCESS)) 187 | { 188 | // Send command. 189 | ret_code = eccX08p_send_command(count, tx_buffer); 190 | if (ret_code != ECCX08_SUCCESS) 191 | { 192 | if (eccX08c_resync(rx_size, rx_buffer) == ECCX08_RX_NO_RESPONSE) { 193 | // The device seems to be dead in the water. 194 | //debugStream->println("eccX08c_send_and_receive 1"); 195 | return ret_code; 196 | } else 197 | continue; 198 | } 199 | 200 | // Wait minimum command execution time and then start polling for a response. 201 | delay_ms(execution_delay); 202 | 203 | // Retry loop for receiving a response. 204 | n_retries_receive = ECCX08_RETRY_COUNT + 1; 205 | while (n_retries_receive-- > 0) 206 | { 207 | // Reset response buffer. 208 | for (i = 0; i < rx_size; i++) 209 | rx_buffer[i] = 0; 210 | 211 | // Poll for response. 212 | timeout_countdown = execution_timeout_us; 213 | do 214 | { 215 | // Send Dummy Write 216 | ret_code = eccX08p_send_command(0, NULL); 217 | timeout_countdown -= ECCX08_RESPONSE_TIMEOUT; 218 | } while ((timeout_countdown > ECCX08_RESPONSE_TIMEOUT) && (ret_code != ECCX08_SUCCESS)); 219 | if (ret_code == ECCX08_SUCCESS) 220 | { 221 | ret_code = eccX08p_receive_response(rx_size, rx_buffer); 222 | } 223 | else 224 | { 225 | //Serial.println("eccX08c_send_and_receive 2"); 226 | // Likely place ECCX08_RX_NO_RESPONSE is being set 227 | ret_code = ECCX08_RX_NO_RESPONSE; 228 | } 229 | 230 | if (ret_code == ECCX08_RX_NO_RESPONSE) 231 | { 232 | // We did not receive a response. Re-synchronize and send command again. 233 | if (eccX08c_resync(rx_size, rx_buffer) == ECCX08_RX_NO_RESPONSE) { 234 | // The device seems to be dead in the water. 235 | //Serial.println("eccX08c_send_and_receive 3"); 236 | return ret_code; 237 | } else 238 | break; 239 | } 240 | 241 | // Check whether we received a valid response. 242 | if (ret_code == ECCX08_INVALID_SIZE) 243 | { 244 | // We see 0xFF for the count when communication got out of sync. 245 | ret_code_resync = eccX08c_resync(rx_size, rx_buffer); 246 | if (ret_code_resync == ECCX08_SUCCESS) 247 | // We did not have to wake up the device. Try receiving response again. 248 | continue; 249 | if (ret_code_resync == ECCX08_RESYNC_WITH_WAKEUP) 250 | // We could re-synchronize, but only after waking up the device. 251 | // Re-send command. 252 | break; 253 | else 254 | // We failed to re-synchronize. 255 | return ret_code; 256 | } 257 | 258 | // We received a response of valid size. Check the consistency of the response. 259 | ret_code = eccX08c_check_crc(rx_buffer); 260 | if (ret_code == ECCX08_SUCCESS) 261 | { 262 | // Received valid response. 263 | if (rx_buffer[ECCX08_BUFFER_POS_COUNT] > ECCX08_RSP_SIZE_MIN) 264 | // Received non-status response. We are done. 265 | return ret_code; 266 | 267 | // Received status response. 268 | status_byte = rx_buffer[ECCX08_BUFFER_POS_STATUS]; 269 | 270 | // Translate the three possible device status error codes 271 | // into library return codes. 272 | if (status_byte == ECCX08_STATUS_BYTE_PARSE) 273 | return ECCX08_PARSE_ERROR; 274 | if (status_byte == ECCX08_STATUS_BYTE_EXEC) 275 | return ECCX08_CMD_FAIL; 276 | if (status_byte == ECCX08_STATUS_BYTE_COMM) 277 | { 278 | // In case of the device status byte indicating a communication 279 | // error this function exits the retry loop for receiving a response 280 | // and enters the overall retry loop 281 | // (send command / receive response). 282 | ret_code = ECCX08_STATUS_CRC; 283 | break; 284 | } 285 | 286 | // Received status response from CheckMAC, DeriveKey, GenDig, 287 | // Lock, Nonce, Pause, UpdateExtra, or Write command. 288 | return ret_code; 289 | } 290 | else 291 | { 292 | // Received response with incorrect CRC. 293 | ret_code_resync = eccX08c_resync(rx_size, rx_buffer); 294 | if (ret_code_resync == ECCX08_SUCCESS) 295 | // We did not have to wake up the device. Try receiving response again. 296 | continue; 297 | if (ret_code_resync == ECCX08_RESYNC_WITH_WAKEUP) 298 | // We could re-synchronize, but only after waking up the device. 299 | // Re-send command. 300 | break; 301 | else 302 | // We failed to re-synchronize. 303 | return ret_code; 304 | } // block end of check response consistency 305 | } // block end of receive retry loop 306 | } // block end of send and receive retry loop 307 | 308 | return ret_code; 309 | } 310 | -------------------------------------------------------------------------------- /src/ateccX08-atmel/eccX08_comm.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | // ATMEL Microcontroller Software Support - Colorado Springs, CO - 5 | // ---------------------------------------------------------------------------- 6 | // DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 7 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 8 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 9 | // DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 10 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 11 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 12 | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 13 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 14 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 15 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 16 | // ---------------------------------------------------------------------------- 17 | 18 | /** \file 19 | * \brief Definitions and Prototypes for Communication Layer of ECCX08 Library 20 | * \author Atmel Crypto Products 21 | * \date September 12, 2012 22 | */ 23 | #ifndef ECCX08_COMM_H 24 | # define ECCX08_COMM_H 25 | 26 | #include // data type definitions 27 | 28 | #include "eccX08_physical.h" // declarations that are common to all interface implementations 29 | 30 | 31 | //! maximum command delay 32 | #define ECCX08_COMMAND_EXEC_MAX ((uint8_t) (120.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5)) 33 | 34 | //! minimum number of bytes in command (from count byte to second CRC byte) 35 | #define ECCX08_CMD_SIZE_MIN ((uint8_t) 7) 36 | 37 | //! maximum size of command packet (Verify) 38 | #define ECCX08_CMD_SIZE_MAX ((uint8_t) 4 * 36 + 7) 39 | 40 | //! number of CRC bytes 41 | #define ECCX08_CRC_SIZE ((uint8_t) 2) 42 | 43 | //! buffer index of status byte in status response 44 | #define ECCX08_BUFFER_POS_STATUS (1) 45 | 46 | //! buffer index of first data byte in data response 47 | #define ECCX08_BUFFER_POS_DATA (1) 48 | 49 | //! status byte after wake-up 50 | #define ECCX08_STATUS_BYTE_WAKEUP ((uint8_t) 0x11) 51 | 52 | //! command parse error 53 | #define ECCX08_STATUS_BYTE_PARSE ((uint8_t) 0x03) 54 | 55 | //! command execution error 56 | #define ECCX08_STATUS_BYTE_EXEC ((uint8_t) 0x0F) 57 | 58 | //! communication error 59 | #define ECCX08_STATUS_BYTE_COMM ((uint8_t) 0xFF) 60 | 61 | 62 | void eccX08c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc); 63 | uint8_t ecc108c_check_crc(uint8_t *response); 64 | uint8_t eccX08c_wakeup(uint8_t *response); 65 | uint8_t ecc108c_resync(uint8_t size, uint8_t *response); 66 | uint8_t eccX08c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer, uint8_t execution_delay, uint8_t execution_timeout); 67 | 68 | #endif 69 | #ifdef __cplusplus 70 | } 71 | #endif 72 | -------------------------------------------------------------------------------- /src/ateccX08-atmel/eccX08_config.h: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // ATMEL Microcontroller Software Support - Colorado Springs, CO - 3 | // ---------------------------------------------------------------------------- 4 | // DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 5 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 6 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 7 | // DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 8 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 9 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 10 | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 11 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 12 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 13 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 14 | // ---------------------------------------------------------------------------- 15 | 16 | /** \file 17 | * \brief Definitions for Configurable Values of the ECCX08 Library 18 | * 19 | * This file contains several library configuration sections 20 | * for the three interfaces the library supports 21 | * (SWI using GPIO or UART, and I2C) and one that is common 22 | * to all interfaces. 23 | * \author Atmel Crypto Products 24 | * \date September 12, 2012 25 | */ 26 | #ifndef ECCX08_CONFIG_H 27 | # define ECCX08_CONFIG_H 28 | 29 | #include // data type definitions 30 | 31 | ////////////////////////////////////////////////////////////////////////// 32 | ////////// definitions common to all interfaces ////////////////////////// 33 | ////////////////////////////////////////////////////////////////////////// 34 | 35 | /** \brief maximum CPU clock deviation to higher frequency (crystal etc.) 36 | * This value is used to establish time related worst case numbers, for 37 | * example to calculate execution delays and timeouts. 38 | * \todo Get rid of this nonsense. 39 | */ 40 | #define CPU_CLOCK_DEVIATION_POSITIVE (1.01) 41 | 42 | /** \brief maximum CPU clock deviation to lower frequency (crystal etc.) 43 | * This value is used to establish time related worst case numbers, for 44 | * example to calculate execution delays and timeouts. 45 | */ 46 | #define CPU_CLOCK_DEVIATION_NEGATIVE (0.99) 47 | 48 | /** \brief number of command / response retries 49 | * 50 | * If communication is lost, re-synchronization includes waiting for the 51 | * longest possible execution time of a command. 52 | * This adds a #ECCX08_COMMAND_EXEC_MAX delay to every retry. 53 | * Every increment of the number of retries increases the time 54 | * the library is spending in the retry loop by #ECCX08_COMMAND_EXEC_MAX. 55 | */ 56 | #define ECCX08_RETRY_COUNT (1) 57 | 58 | 59 | ////////////////////////////////////////////////////////////////////////// 60 | ///////////// definitions specific to interface ////////////////////////// 61 | ////////////////////////////////////////////////////////////////////////// 62 | 63 | //! Define this if you are using GPIO for SWI communication. 64 | //#define ECCX08_SWI_BITBANG 65 | 66 | //! Define this if you are using a UART for SWI communication. 67 | //#define ECCX08_SWI_UART 68 | 69 | //! Define this if you are using TWI communication. 70 | #define ECCX08_I2C 71 | 72 | ////////////////////////////// GPIO configurations ////////////////////////////// 73 | #ifdef ECCX08_SWI_BITBANG 74 | 75 | //! #START_PULSE_TIME_OUT in us instead of loop counts 76 | # define SWI_RECEIVE_TIME_OUT ((uint16_t) 163) 77 | 78 | //! It takes 312.5 us to send a byte (9 single-wire bits / 230400 Baud * 8 flag bits). 79 | # define SWI_US_PER_BYTE ((uint16_t) 313) 80 | 81 | #endif 82 | 83 | 84 | ////////////////////////////// UART configurations ////////////////////////////// 85 | #ifdef ECCX08_SWI_UART 86 | 87 | //! receive timeout in us instead of loop counts 88 | # define SWI_RECEIVE_TIME_OUT ((uint16_t) 153) 89 | 90 | //! It takes 312.5 us to send a byte (9 single-wire bits / 230400 Baud * 8 flag bits). 91 | # define SWI_US_PER_BYTE ((uint16_t) 313) 92 | 93 | //! SWI response timeout is the sum of receive timeout and the time it takes to send the TX flag. 94 | # ifndef ECCX08_RESPONSE_TIMEOUT 95 | # define ECCX08_RESPONSE_TIMEOUT ((uint16_t) SWI_RECEIVE_TIME_OUT + SWI_US_PER_BYTE) 96 | # endif 97 | 98 | #endif 99 | 100 | 101 | ///////// SWI configurations common for GPIO and UART implementation //////////////////////// 102 | #if defined(ECCX08_SWI_BITBANG) || defined(ECCX08_SWI_UART) 103 | 104 | //! delay before sending a transmit flag in the synchronization routine 105 | # define ECCX08_SYNC_TIMEOUT ((uint8_t) 85) 106 | 107 | # ifndef ECCX08_RESPONSE_TIMEOUT 108 | //! SWI response timeout is the sum of receive timeout and the time it takes to send the TX flag. 109 | # define ECCX08_RESPONSE_TIMEOUT ((uint16_t) SWI_RECEIVE_TIME_OUT + SWI_US_PER_BYTE) 110 | # endif 111 | 112 | #endif 113 | 114 | 115 | ////////////////////////////// I2C configurations ////////////////////////////// 116 | #if defined(ECCX08_I2C) || defined(ECCX08_I2C_BITBANG) 117 | 118 | /** \brief For I2C, the response polling time is the time 119 | * it takes to send the I2C address. 120 | * 121 | * This value is used to timeout when waiting for a response. 122 | */ 123 | # define ECCX08_I2C_DEFAULT_ADDRESS ((uint8_t) 0xC0) 124 | 125 | # ifndef ECCX08_RESPONSE_TIMEOUT 126 | # define ECCX08_RESPONSE_TIMEOUT ((uint16_t) 37) 127 | # endif 128 | 129 | #endif 130 | 131 | 132 | #endif 133 | -------------------------------------------------------------------------------- /src/ateccX08-atmel/eccX08_i2c.c: -------------------------------------------------------------------------------- 1 | // ATMEL Microcontroller Software Support - Colorado Springs, CO - 2 | // ---------------------------------------------------------------------------- 3 | // DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 4 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 5 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 6 | // DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 7 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 8 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 9 | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 10 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 11 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 12 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 13 | // ---------------------------------------------------------------------------- 14 | 15 | /** \file 16 | * \brief Functions for I2C Physical Hardware Independent Layer of ECCX08 Library 17 | * \author Atmel Crypto Products 18 | * \date May 3, 2013 19 | */ 20 | //#define ECCX08_GPIO_WAKEUP 21 | #include 22 | 23 | #ifdef ECCX08_GPIO_WAKEUP 24 | # include //!< GPIO definitions 25 | #endif 26 | 27 | #ifdef ECCX08_I2C_BITBANG 28 | # include "i2c_phys_bitbang.h" // hardware dependent declarations for bit-banged I2C 29 | #else 30 | # include "../common-atmel/i2c_phys.h" // hardware dependent declarations for I2C 31 | #endif 32 | 33 | #include "eccX08_physical.h" // declarations that are common to all interface implementations 34 | #include "eccX08_lib_return_codes.h" // declarations of function return codes 35 | #include "../common-atmel/timer_utilities.h" // definitions for delay functions 36 | 37 | #include "Arduino.h" 38 | 39 | /** \brief This enumeration lists all packet types sent to a ECCX08 device. 40 | * 41 | * The following byte stream is sent to a ECCX08 I2C device: 42 | * {I2C start} {I2C address} {word address} [{data}] {I2C stop}. 43 | * Data are only sent after a word address of value #ECCX08_I2C_PACKET_FUNCTION_NORMAL. 44 | */ 45 | enum i2c_word_address 46 | { 47 | ECCX08_I2C_PACKET_FUNCTION_RESET, //!< Reset device. 48 | ECCX08_I2C_PACKET_FUNCTION_SLEEP, //!< Put device into Sleep mode. 49 | ECCX08_I2C_PACKET_FUNCTION_IDLE, //!< Put device into Idle mode. 50 | ECCX08_I2C_PACKET_FUNCTION_NORMAL //!< Write / evaluate data that follow this word address byte. 51 | }; 52 | 53 | 54 | /** \brief This enumeration lists flags for I2C read or write addressing. */ 55 | enum i2c_read_write_flag 56 | { 57 | I2C_WRITE = (uint8_t) 0x00, //!< write command flag 58 | I2C_READ = (uint8_t) 0x01 //!< read command flag 59 | }; 60 | 61 | 62 | //! I2C address is set when calling #eccX08p_init or #eccX08p_set_device_id. 63 | static uint8_t device_address; 64 | 65 | 66 | /** \brief This I2C function sets the I2C address. 67 | * Communication functions will use this address. 68 | * 69 | * \param[in] id I2C address 70 | */ 71 | void eccX08p_set_device_id(uint8_t id) 72 | { 73 | device_address = id; 74 | } 75 | 76 | 77 | /** \brief This I2C function initializes the hardware. 78 | */ 79 | void eccX08p_init(void) 80 | { 81 | i2c_enable(); 82 | device_address = ECCX08_I2C_DEFAULT_ADDRESS; 83 | } 84 | 85 | 86 | /** \brief This I2C function initializes the i2c speed. 87 | */ 88 | void eccX08p_i2c_set_spd(uint32_t spd_in_khz) 89 | { 90 | i2c_set_speed(spd_in_khz); 91 | i2c_enable(); 92 | } 93 | 94 | 95 | //#ifndef DEBUG_DIAMOND 96 | //# define DEBUG_DIAMOND 97 | //#endif 98 | /** \brief This I2C function generates a Wake-up pulse and delays. 99 | * \return status of the operation 100 | */ 101 | uint8_t eccX08p_wakeup(void) 102 | { 103 | #if !defined(ECCX08_GPIO_WAKEUP) && !defined(ECCX08_I2C_BITBANG) 104 | // Generate wakeup pulse by writing a 0 on the I2C bus. 105 | uint8_t dummy_byte = 0; 106 | uint8_t i2c_status = i2c_send_start(); 107 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 108 | return ECCX08_COMM_FAIL; 109 | 110 | // To send eight zero bits it takes 10E6 / I2C clock * 8 us. 111 | delay_10us(ECCX08_WAKEUP_PULSE_WIDTH - (uint8_t) (1000000.0 / 10.0 / I2C_CLOCK * 8.0)); 112 | 113 | // We have to send at least one byte between an I2C Start and an I2C Stop. 114 | (void) i2c_send_bytes(1, &dummy_byte); 115 | i2c_status = i2c_send_stop(); 116 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 117 | return ECCX08_COMM_FAIL; 118 | 119 | #else 120 | 121 | # if defined(ECCX08_I2C_BITBANG) 122 | // Generate wakeup pulse using the GPIO pin that is connected to SDA. 123 | i2c_data_low(); 124 | //i2c_clock_low(); 125 | delay_10us(ECCX08_WAKEUP_PULSE_WIDTH); 126 | //i2c_clock_high(); 127 | i2c_data_high(); 128 | # else 129 | // Generate wakeup pulse by disabling the I2C peripheral and 130 | // pulling SDA low. The I2C peripheral gets automatically 131 | // re-enabled when calling i2c_send_start(). 132 | // PORTD is used on the Microbase. You might have to use another 133 | // port for a different target. 134 | TWCR = 0; // Disable I2C. 135 | DDRD |= _BV(PD1); // Set SDA as output. 136 | PORTD &= ~_BV(PD1); // Set SDA low. 137 | delay_10us(ECCX08_WAKEUP_PULSE_WIDTH); 138 | PORTD |= _BV(PD1); // Set SDA high. 139 | # endif 140 | 141 | #endif 142 | 143 | // i2c_set_speed(400); 144 | // i2c_enable(); 145 | delay_10us(ECCX08_WAKEUP_DELAY); 146 | 147 | return ECCX08_SUCCESS; 148 | } 149 | 150 | 151 | /** \brief This function creates a Start condition and sends the TWI address. 152 | * \param[in] read #I2C_READ for reading, #I2C_WRITE for writing 153 | * \return status of the I2C operation 154 | */ 155 | static uint8_t eccX08p_send_slave_address(uint8_t read) 156 | { 157 | uint8_t sla = device_address | read; 158 | uint8_t ret_code = i2c_send_start(); 159 | if (ret_code != I2C_FUNCTION_RETCODE_SUCCESS) 160 | return ret_code; 161 | 162 | ret_code = i2c_send_bytes(1, &sla); 163 | 164 | if (ret_code != I2C_FUNCTION_RETCODE_SUCCESS) 165 | (void) i2c_send_stop(); 166 | 167 | return ret_code; 168 | } 169 | 170 | 171 | /** \brief This function sends a I2C packet enclosed by a I2C start and stop to a ECCX08 device. 172 | * 173 | * This function combines a I2C packet send sequence that is common to all packet types. 174 | * Only if word_address is #I2C_PACKET_FUNCTION_NORMAL, count and buffer parameters are 175 | * expected to be non-zero. 176 | * @param[in] word_address packet function code listed in #i2c_word_address 177 | * @param[in] count number of bytes in data buffer 178 | * @param[in] buffer pointer to data buffer 179 | * @return status of the operation 180 | */ 181 | static uint8_t eccX08p_i2c_send(uint8_t word_address, uint8_t count, uint8_t *buffer) 182 | { 183 | uint8_t i2c_status = eccX08p_send_slave_address(I2C_WRITE); 184 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 185 | return ECCX08_COMM_FAIL; 186 | 187 | i2c_status = i2c_send_bytes(1, &word_address); 188 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 189 | return ECCX08_COMM_FAIL; 190 | 191 | if (count == 0) { 192 | // We are done for packets that are not commands (Sleep, Idle, Reset). 193 | (void) i2c_send_stop(); 194 | return ECCX08_SUCCESS; 195 | } 196 | 197 | i2c_status = i2c_send_bytes(count, buffer); 198 | 199 | (void) i2c_send_stop(); 200 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 201 | return ECCX08_COMM_FAIL; 202 | else 203 | return ECCX08_SUCCESS; 204 | } 205 | 206 | 207 | /** \brief This I2C function sends a command to the device. 208 | * \param[in] count number of bytes to send 209 | * \param[in] command pointer to command buffer 210 | * \return status of the operation 211 | */ 212 | uint8_t eccX08p_send_command(uint8_t count, uint8_t *command) 213 | { 214 | return eccX08p_i2c_send(ECCX08_I2C_PACKET_FUNCTION_NORMAL, count, command); 215 | } 216 | 217 | 218 | /** \brief This I2C function puts the ECCX08 device into idle state. 219 | * \return status of the operation 220 | */ 221 | uint8_t eccX08p_idle(void) 222 | { 223 | return eccX08p_i2c_send(ECCX08_I2C_PACKET_FUNCTION_IDLE, 1, NULL); 224 | } 225 | 226 | 227 | /** \brief This I2C function puts the ECCX08 device into low-power state. 228 | * \return status of the operation 229 | */ 230 | uint8_t eccX08p_sleep(void) 231 | { 232 | return eccX08p_i2c_send(ECCX08_I2C_PACKET_FUNCTION_SLEEP, 1, NULL); 233 | } 234 | 235 | 236 | /** \brief This I2C function resets the I/O buffer of the ECCX08 device. 237 | * \return status of the operation 238 | */ 239 | uint8_t eccX08p_reset_io(void) 240 | { 241 | return eccX08p_i2c_send(ECCX08_I2C_PACKET_FUNCTION_RESET, 1, NULL); 242 | } 243 | 244 | 245 | /** \brief This I2C function receives a response from the ECCX08 device. 246 | * 247 | * @param[in] size size of rx buffer 248 | * @param[out] response pointer to rx buffer 249 | * @return status of the operation 250 | */ 251 | uint8_t eccX08p_receive_response(uint8_t size, uint8_t *response) 252 | { 253 | uint8_t count; 254 | 255 | // Address the device and indicate that bytes are to be read. 256 | uint8_t i2c_status = eccX08p_send_slave_address(I2C_READ); 257 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) { 258 | // Translate error so that the Communication layer 259 | // can distinguish between a real error or the 260 | // device being busy executing a command. 261 | if (i2c_status == I2C_FUNCTION_RETCODE_NACK) 262 | i2c_status = ECCX08_RX_NO_RESPONSE; 263 | 264 | return i2c_status; 265 | } 266 | 267 | // Receive count byte. 268 | i2c_status = i2c_receive_byte(response); 269 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 270 | return ECCX08_COMM_FAIL; 271 | 272 | count = response[ECCX08_BUFFER_POS_COUNT]; 273 | if ((count < ECCX08_RSP_SIZE_MIN) || (count > size)) { 274 | (void) i2c_send_stop(); 275 | return ECCX08_INVALID_SIZE; 276 | } 277 | 278 | i2c_status = i2c_receive_bytes(count - 1, &response[ECCX08_BUFFER_POS_DATA]); 279 | 280 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 281 | return ECCX08_COMM_FAIL; 282 | else 283 | return ECCX08_SUCCESS; 284 | } 285 | 286 | 287 | /** \brief This I2C function resynchronizes communication. 288 | * 289 | * Parameters are not used for I2C.\n 290 | * Re-synchronizing communication is done in a maximum of three steps 291 | * listed below. This function implements the first step. Since 292 | * steps 2 and 3 (sending a Wake-up token and reading the response) 293 | * are the same for I2C and SWI, they are 294 | * implemented in the communication layer (#eccX08c_resync). 295 |
    296 |
  1. 297 | To ensure an IO channel reset, the system should send 298 | the standard I2C software reset sequence, as follows: 299 |
      300 |
    • a Start condition
    • 301 |
    • nine cycles of SCL, with SDA held high
    • 302 |
    • another Start condition
    • 303 |
    • a Stop condition
    • 304 |
    305 | It should then be possible to send a read sequence and 306 | if synchronization has completed properly the ATECCX08 will 307 | acknowledge the device address. The chip may return data or 308 | may leave the bus floating (which the system will interpret 309 | as a data value of 0xFF) during the data periods.\n 310 | If the chip does acknowledge the device address, the system 311 | should reset the internal address counter to force the 312 | ATECCX08 to ignore any partial input command that may have 313 | been sent. This can be accomplished by sending a write 314 | sequence to word address 0x00 (Reset), followed by a 315 | Stop condition. 316 |
  2. 317 |
  3. 318 | If the chip does NOT respond to the device address with an ACK, 319 | then it may be asleep. In this case, the system should send a 320 | complete Wake token and wait t_whi after the rising edge. The 321 | system may then send another read sequence and if synchronization 322 | has completed the chip will acknowledge the device address. 323 |
  4. 324 |
  5. 325 | If the chip still does not respond to the device address with 326 | an acknowledge, then it may be busy executing a command. The 327 | system should wait the longest TEXEC and then send the 328 | read sequence, which will be acknowledged by the chip. 329 |
  6. 330 |
331 | * \param[in] size size of rx buffer 332 | * \param[out] response pointer to response buffer 333 | * \return status of the operation 334 | * \todo Run MAC test in a loop until a communication error occurs and this routine is executed. 335 | */ 336 | uint8_t eccX08p_resync(uint8_t size, uint8_t *response) 337 | { 338 | uint8_t nine_clocks = 0xFF; 339 | uint8_t ret_code = i2c_send_start(); 340 | 341 | // Do not evaluate the return code that most likely indicates error, 342 | // since nine_clocks is unlikely to be acknowledged. 343 | (void) i2c_send_bytes(1, &nine_clocks); 344 | 345 | // Send another Start. The function sends also one byte, 346 | // the I2C address of the device, because I2C specification 347 | // does not allow sending a Stop right after a Start condition. 348 | ret_code = eccX08p_send_slave_address(I2C_READ); 349 | 350 | // Send only a Stop if the above call succeeded. 351 | // Otherwise the above function has sent it already. 352 | if (ret_code == I2C_FUNCTION_RETCODE_SUCCESS) 353 | ret_code = i2c_send_stop(); 354 | 355 | // Return error status if we failed to re-sync. 356 | if (ret_code != I2C_FUNCTION_RETCODE_SUCCESS) 357 | return ECCX08_COMM_FAIL; 358 | 359 | // Try to send a Reset IO command if re-sync succeeded. 360 | return eccX08p_reset_io(); 361 | } 362 | -------------------------------------------------------------------------------- /src/ateccX08-atmel/eccX08_lib_return_codes.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | // ---------------------------------------------------------------------------- 5 | // ATMEL Microcontroller Software Support - Colorado Springs, CO - 6 | // ---------------------------------------------------------------------------- 7 | // DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 8 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 10 | // DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 11 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 12 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 13 | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 14 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 15 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 16 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 17 | // ---------------------------------------------------------------------------- 18 | 19 | /** \file 20 | * \brief ECCX08 Library Return Code Definitions 21 | * \author Atmel Crypto Products 22 | * \date September 12, 2012 23 | */ 24 | 25 | #ifndef ECCX08_LIB_RETURN_CODES_H 26 | # define ECCX08_LIB_RETURN_CODES_H 27 | 28 | #include // data type definitions 29 | 30 | 31 | #define ECCX08_SUCCESS ((uint8_t) 0x00) //!< Function succeeded. 32 | #define ECCX08_CHECKMAC_FAILED ((uint8_t) 0xD1) //!< response status byte indicates CheckMac failure 33 | #define ECCX08_PARSE_ERROR ((uint8_t) 0xD2) //!< response status byte indicates parsing error 34 | #define ECCX08_CMD_FAIL ((uint8_t) 0xD3) //!< response status byte indicates command execution error 35 | #define ECCX08_STATUS_CRC ((uint8_t) 0xD4) //!< response status byte indicates CRC error 36 | #define ECCX08_STATUS_UNKNOWN ((uint8_t) 0xD5) //!< response status byte is unknown 37 | #define ECCX08_FUNC_FAIL ((uint8_t) 0xE0) //!< Function could not execute due to incorrect condition / state. 38 | #define ECCX08_GEN_FAIL ((uint8_t) 0xE1) //!< unspecified error 39 | #define ECCX08_BAD_PARAM ((uint8_t) 0xE2) //!< bad argument (out of range, null pointer, etc.) 40 | #define ECCX08_INVALID_ID ((uint8_t) 0xE3) //!< invalid device id, id not set 41 | #define ECCX08_INVALID_SIZE ((uint8_t) 0xE4) //!< Count value is out of range or greater than buffer size. 42 | #define ECCX08_BAD_CRC ((uint8_t) 0xE5) //!< incorrect CRC received 43 | #define ECCX08_RX_FAIL ((uint8_t) 0xE6) //!< Timed out while waiting for response. Number of bytes received is > 0. 44 | #define ECCX08_RX_NO_RESPONSE ((uint8_t) 0xE7) //!< Not an error while the Command layer is polling for a command response. 45 | #define ECCX08_RESYNC_WITH_WAKEUP ((uint8_t) 0xE8) //!< re-synchronization succeeded, but only after generating a Wake-up 46 | 47 | #define ECCX08_COMM_FAIL ((uint8_t) 0xF0) //!< Communication with device failed. Same as in hardware dependent modules. 48 | #define ECCX08_TIMEOUT ((uint8_t) 0xF1) //!< Timed out while waiting for response. Number of bytes received is 0. 49 | 50 | 51 | #endif 52 | #ifdef __cplusplus 53 | } 54 | #endif 55 | -------------------------------------------------------------------------------- /src/ateccX08-atmel/eccX08_physical.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | // ---------------------------------------------------------------------------- 5 | // ATMEL Microcontroller Software Support - Colorado Springs, CO - 6 | // ---------------------------------------------------------------------------- 7 | // DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR 8 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 9 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 10 | // DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, 11 | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 12 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 13 | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 14 | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 15 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 16 | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 17 | // ---------------------------------------------------------------------------- 18 | 19 | /** \file 20 | * \brief Definitions and Prototypes for Physical Layer Interface of ECCX08 Library 21 | * \author Atmel Crypto Products 22 | * \date May 3, 2013 23 | */ 24 | #ifndef ECCX08_PHYSICAL_H 25 | # define ECCX08_PHYSICAL_H 26 | 27 | #include // data type definitions 28 | 29 | #include "eccX08_config.h" // configuration values 30 | 31 | 32 | #define ECCX08_RSP_SIZE_MIN ((uint8_t) 4) //!< minimum number of bytes in response 33 | #define ECCX08_RSP_SIZE_64 ((uint8_t) 67) //!< size of response packet containing 64 bytes data 34 | #define ECCX08_RSP_SIZE_32 ((uint8_t) 35) //!< size of response packet containing 32 bytes data 35 | #define ECCX08_RSP_SIZE_MAX ((uint8_t) 75) //!< maximum size of response packet 36 | 37 | #define ECCX08_BUFFER_POS_COUNT (0) //!< buffer index of count byte in command or response 38 | #define ECCX08_BUFFER_POS_DATA (1) //!< buffer index of data in response 39 | 40 | //! width of Wakeup pulse in 10 us units 41 | #define ECCX08_WAKEUP_PULSE_WIDTH (uint8_t) (12.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5) 42 | 43 | //! delay between Wakeup pulse and communication in 10 us units 44 | #define ECCX08_WAKEUP_DELAY (uint8_t) (100.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5) 45 | 46 | 47 | uint8_t eccX08p_send_command(uint8_t count, uint8_t *command); 48 | uint8_t eccX08p_receive_response(uint8_t size, uint8_t *response); 49 | void eccX08p_init(void); 50 | void eccX08p_i2c_set_spd(uint32_t spd_in_khz); 51 | void eccX08p_set_device_id(uint8_t id); 52 | uint8_t eccX08p_wakeup(void); 53 | uint8_t eccX08p_idle(void); 54 | uint8_t eccX08p_sleep(void); 55 | uint8_t eccX08p_reset_io(void); 56 | uint8_t eccX08p_resync(uint8_t size, uint8_t *response); 57 | 58 | #endif 59 | #ifdef __cplusplus 60 | } 61 | #endif 62 | -------------------------------------------------------------------------------- /src/atsha204-atmel/Makefile: -------------------------------------------------------------------------------- 1 | ##########------------------------------------------------------########## 2 | ########## Project-specific Details ########## 3 | ########## Check these every time you start a new project ########## 4 | ##########------------------------------------------------------########## 5 | 6 | MCU = atmega328p 7 | F_CPU = 16000000 8 | BAUD = 9600 9 | ## Also try BAUD = 19200 or 38400 if you're feeling lucky. 10 | 11 | ## This is where your main() routine lives 12 | MAIN = sha204_example_main.c 13 | 14 | ## If you've split your program into multiple .c / .h files, 15 | ## include the additional source (in same directory) here 16 | LOCAL_SOURCE = avr_compatible.h i2c_phys.c i2c_phys.h sha204_comm.c sha204_comm.h sha204_comm_marshaling.c sha204_comm_marshaling.h sha204_config.h sha204_examples.c sha204_examples.h sha204_helper.c sha204_helper.h sha204_i2c.c sha204_lib_return_codes.h sha204_physical.h timer_utilities.c timer_utilities.h USART.c USART.h binaryMacro.h macros.h pinDefines.h 17 | 18 | ## Here you can link to one more directory (and multiple .c files) 19 | EXTRA_SOURCE_DIR = 20 | EXTRA_SOURCE_FILES = 21 | 22 | ##########------------------------------------------------------########## 23 | ########## Programmer Defaults ########## 24 | ########## Set up once, then forget about it ########## 25 | ########## (Can override. See bottom of file.) ########## 26 | ##########------------------------------------------------------########## 27 | 28 | PROGRAMMER_TYPE = usbtiny 29 | # extra arguments to avrdude: baud rate, chip type, -F flag, etc. 30 | PROGRAMMER_ARGS = 31 | 32 | ##########------------------------------------------------------########## 33 | ########## Makefile Magic! ########## 34 | ########## Summary: ########## 35 | ########## We want a .hex file ########## 36 | ########## Compile source files into .elf ########## 37 | ########## Convert .elf file into .hex ########## 38 | ########## You shouldn't need to edit below. ########## 39 | ##########------------------------------------------------------########## 40 | 41 | ## Defined programs / locations 42 | CC = avr-gcc 43 | OBJCOPY = avr-objcopy 44 | OBJDUMP = avr-objdump 45 | AVRSIZE = avr-size 46 | AVRDUDE = avrdude 47 | 48 | ## Compilation options, type man avr-gcc if you're curious. 49 | CFLAGS = -mmcu=$(MCU) -DF_CPU=$(F_CPU)UL -DBAUD=$(BAUD) -Os -I. -I$(EXTRA_SOURCE_DIR) 50 | CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums 51 | CFLAGS += -Wall -Wstrict-prototypes 52 | CFLAGS += -g -ggdb 53 | CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections -Wl,--relax 54 | CFLAGS += -std=gnu99 55 | CFLAGS += -DSHA204_I2C 56 | ## CFLAGS += -Wl,-u,vfprintf -lprintf_flt -lm ## for floating-point printf 57 | ## CFLAGS += -Wl,-u,vfprintf -lprintf_min ## for smaller printf 58 | 59 | ## Lump target and extra source files together 60 | TARGET = $(strip $(basename $(MAIN))) 61 | SRC = $(TARGET).c 62 | EXTRA_SOURCE = $(addprefix $(EXTRA_SOURCE_DIR), $(EXTRA_SOURCE_FILES)) 63 | SRC += $(EXTRA_SOURCE) 64 | SRC += $(LOCAL_SOURCE) 65 | 66 | ## List of all header files 67 | HEADERS = $(SRC:.c=.h) 68 | 69 | ## For every .c file, compile an .o object file 70 | OBJ = $(SRC:.c=.o) 71 | 72 | ## Generic Makefile targets. (Only .hex file is necessary) 73 | all: $(TARGET).hex 74 | 75 | %.hex: %.elf 76 | $(OBJCOPY) -R .eeprom -O ihex $< $@ 77 | 78 | %.elf: $(SRC) 79 | $(CC) $(CFLAGS) $(SRC) --output $@ 80 | 81 | %.eeprom: %.elf 82 | $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@ 83 | 84 | debug: 85 | @echo 86 | @echo "Source files:" $(SRC) 87 | @echo "MCU, F_CPU, BAUD:" $(MCU), $(F_CPU), $(BAUD) 88 | @echo 89 | 90 | # Optionally create listing file from .elf 91 | # This creates approximate assembly-language equivalent of your code. 92 | # Useful for debugging time-sensitive bits, 93 | # or making sure the compiler does what you want. 94 | disassemble: $(TARGET).lst 95 | 96 | disasm: disassemble 97 | 98 | eeprom: $(TARGET).eeprom 99 | 100 | %.lst: %.elf 101 | $(OBJDUMP) -S $< > $@ 102 | 103 | # Optionally show how big the resulting program is 104 | size: $(TARGET).elf 105 | $(AVRSIZE) -C --mcu=$(MCU) $(TARGET).elf 106 | 107 | clean: 108 | rm -f $(TARGET).elf $(TARGET).hex $(TARGET).obj \ 109 | $(TARGET).o $(TARGET).d $(TARGET).eep $(TARGET).lst \ 110 | $(TARGET).lss $(TARGET).sym $(TARGET).map $(TARGET)~ \ 111 | $(TARGET).eeprom 112 | 113 | squeaky_clean: 114 | rm -f *.elf *.hex *.obj *.o *.d *.eep *.lst *.lss *.sym *.map *~ 115 | 116 | ##########------------------------------------------------------########## 117 | ########## Programmer-specific details ########## 118 | ########## Flashing code to AVR using avrdude ########## 119 | ##########------------------------------------------------------########## 120 | 121 | flash: $(TARGET).hex 122 | $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U flash:w:$< 123 | 124 | ## An alias 125 | program: flash 126 | 127 | flash_eeprom: $(TARGET).eeprom 128 | $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -U eeprom:w:$< 129 | 130 | avrdude_terminal: 131 | $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nt 132 | 133 | ## If you've got multiple programmers that you use, 134 | ## you can define them here so that it's easy to switch. 135 | ## To invoke, use something like `make flash_arduinoISP` 136 | flash_usbtiny: PROGRAMMER_TYPE = usbtiny 137 | flash_usbtiny: PROGRAMMER_ARGS = # USBTiny works with no further arguments 138 | flash_usbtiny: flash 139 | 140 | flash_usbasp: PROGRAMMER_TYPE = usbasp 141 | flash_usbasp: PROGRAMMER_ARGS = # USBasp works with no further arguments 142 | flash_usbasp: flash 143 | 144 | flash_arduinoISP: PROGRAMMER_TYPE = avrisp 145 | flash_arduinoISP: PROGRAMMER_ARGS = -b 19200 -P /dev/ttyACM0 146 | ## (for windows) flash_arduinoISP: PROGRAMMER_ARGS = -b 19200 -P com5 147 | flash_arduinoISP: flash 148 | 149 | flash_109: PROGRAMMER_TYPE = avr109 150 | flash_109: PROGRAMMER_ARGS = -b 9600 -P /dev/ttyUSB0 151 | flash_109: flash 152 | 153 | ##########------------------------------------------------------########## 154 | ########## Fuse settings and suitable defaults ########## 155 | ##########------------------------------------------------------########## 156 | 157 | ## Mega 48, 88, 168, 328 default values 158 | LFUSE = 0x62 159 | HFUSE = 0xdf 160 | EFUSE = 0x00 161 | 162 | ## Generic 163 | FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m 164 | 165 | fuses: 166 | $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) \ 167 | $(PROGRAMMER_ARGS) $(FUSE_STRING) 168 | show_fuses: 169 | $(AVRDUDE) -c $(PROGRAMMER_TYPE) -p $(MCU) $(PROGRAMMER_ARGS) -nv 170 | 171 | ## Called with no extra definitions, sets to defaults 172 | set_default_fuses: FUSE_STRING = -U lfuse:w:$(LFUSE):m -U hfuse:w:$(HFUSE):m -U efuse:w:$(EFUSE):m 173 | set_default_fuses: fuses 174 | 175 | ## Set the fuse byte for full-speed mode 176 | ## Note: can also be set in firmware for modern chips 177 | set_fast_fuse: LFUSE = 0xE2 178 | set_fast_fuse: FUSE_STRING = -U lfuse:w:$(LFUSE):m 179 | set_fast_fuse: fuses 180 | 181 | ## Set the EESAVE fuse byte to preserve EEPROM across flashes 182 | set_eeprom_save_fuse: HFUSE = 0xD7 183 | set_eeprom_save_fuse: FUSE_STRING = -U hfuse:w:$(HFUSE):m 184 | set_eeprom_save_fuse: fuses 185 | 186 | ## Clear the EESAVE fuse byte 187 | clear_eeprom_save_fuse: FUSE_STRING = -U hfuse:w:$(HFUSE):m 188 | clear_eeprom_save_fuse: fuses 189 | -------------------------------------------------------------------------------- /src/atsha204-atmel/sha204_comm.c: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Communication Layer of ATSHA204 Library 3 | * \author Atmel Crypto Products 4 | * \date January 15, 2013 5 | 6 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 7 | * 8 | * \atsha204_library_license_start 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 20 | * 3. The name of Atmel may not be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * 4. This software may only be redistributed and used in connection with an 24 | * Atmel integrated circuit. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 27 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 28 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 29 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 30 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 34 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 35 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 | * POSSIBILITY OF SUCH DAMAGE. 37 | * 38 | * \atsha204_library_license_stop 39 | */ 40 | 41 | #include "sha204_comm.h" // definitions and declarations for the Communication module 42 | #include "../common-atmel/timer_utilities.h" // definitions for delay functions 43 | #include "sha204_lib_return_codes.h" // declarations of function return codes 44 | 45 | 46 | /** \brief This function calculates CRC. 47 | * 48 | * \param[in] length number of bytes in buffer 49 | * \param[in] data pointer to data for which CRC should be calculated 50 | * \param[out] crc pointer to 16-bit CRC 51 | */ 52 | void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc) { 53 | uint8_t counter; 54 | uint16_t crc_register = 0; 55 | uint16_t polynom = 0x8005; 56 | uint8_t shift_register; 57 | uint8_t data_bit, crc_bit; 58 | 59 | for (counter = 0; counter < length; counter++) { 60 | for (shift_register = 0x01; shift_register > 0x00; shift_register <<= 1) { 61 | data_bit = (data[counter] & shift_register) ? 1 : 0; 62 | crc_bit = crc_register >> 15; 63 | crc_register <<= 1; 64 | if (data_bit != crc_bit) 65 | crc_register ^= polynom; 66 | } 67 | } 68 | crc[0] = (uint8_t) (crc_register & 0x00FF); 69 | crc[1] = (uint8_t) (crc_register >> 8); 70 | } 71 | 72 | 73 | /** \brief This function checks the consistency of a response. 74 | * \ingroup atsha204_communication 75 | * \param[in] response pointer to response 76 | * \return status of the consistency check 77 | */ 78 | uint8_t sha204c_check_crc(uint8_t *response) 79 | { 80 | uint8_t crc[SHA204_CRC_SIZE]; 81 | uint8_t count = response[SHA204_BUFFER_POS_COUNT]; 82 | 83 | count -= SHA204_CRC_SIZE; 84 | sha204c_calculate_crc(count, response, crc); 85 | 86 | return (crc[0] == response[count] && crc[1] == response[count + 1]) 87 | ? SHA204_SUCCESS : SHA204_BAD_CRC; 88 | } 89 | 90 | 91 | /** \brief This function wakes up a SHA204 device 92 | * and receives a response. 93 | * 94 | * \param[out] response pointer to four-byte response 95 | * \return status of the operation 96 | */ 97 | uint8_t sha204c_wakeup(uint8_t *response) 98 | { 99 | uint8_t ret_code = sha204p_wakeup(); 100 | if (ret_code != SHA204_SUCCESS) 101 | return ret_code; 102 | 103 | ret_code = sha204p_receive_response(SHA204_RSP_SIZE_MIN, response); 104 | if (ret_code != SHA204_SUCCESS) 105 | return ret_code; 106 | 107 | // Verify status response. 108 | if (response[SHA204_BUFFER_POS_COUNT] != SHA204_RSP_SIZE_MIN) 109 | ret_code = SHA204_INVALID_SIZE; 110 | else if (response[SHA204_BUFFER_POS_STATUS] != SHA204_STATUS_BYTE_WAKEUP) 111 | ret_code = SHA204_COMM_FAIL; 112 | else { 113 | if ((response[SHA204_RSP_SIZE_MIN - SHA204_CRC_SIZE] != 0x33) 114 | || (response[SHA204_RSP_SIZE_MIN + 1 - SHA204_CRC_SIZE] != 0x43)) 115 | ret_code = SHA204_BAD_CRC; 116 | } 117 | if (ret_code != SHA204_SUCCESS) 118 | delay_ms(SHA204_COMMAND_EXEC_MAX); 119 | 120 | return ret_code; 121 | } 122 | 123 | 124 | /** \brief This function re-synchronizes communication. 125 | * \ingroup atsha204_communication 126 | * 127 | Be aware that succeeding only after waking up the 128 | device could mean that it had gone to sleep and lost 129 | its TempKey in the process.\n 130 | Re-synchronizing communication is done in a maximum of 131 | three steps: 132 |
    133 |
  1. 134 | Try to re-synchronize without sending a Wake token. 135 | This step is implemented in the Physical layer. 136 |
  2. 137 |
  3. 138 | If the first step did not succeed send a Wake token. 139 |
  4. 140 |
  5. 141 | Try to read the Wake response. 142 |
  6. 143 |
144 | * 145 | * \param[in] size size of response buffer 146 | * \param[out] response pointer to Wake-up response buffer 147 | * \return status of the operation 148 | */ 149 | uint8_t sha204c_resync(uint8_t size, uint8_t *response) 150 | { 151 | // Try to re-synchronize without sending a Wake token 152 | // (step 1 of the re-synchronization process). 153 | uint8_t ret_code = sha204p_resync(size, response); 154 | if (ret_code == SHA204_SUCCESS) 155 | return ret_code; 156 | 157 | // We lost communication. Send a Wake pulse and try 158 | // to receive a response (steps 2 and 3 of the 159 | // re-synchronization process). 160 | (void) sha204p_sleep(); 161 | ret_code = sha204c_wakeup(response); 162 | 163 | // Translate a return value of success into one 164 | // that indicates that the device had to be woken up 165 | // and might have lost its TempKey. 166 | return (ret_code == SHA204_SUCCESS ? SHA204_RESYNC_WITH_WAKEUP : ret_code); 167 | } 168 | 169 | 170 | /** \brief This function runs a communication sequence. 171 | * 172 | * Append CRC to tx buffer, send command, delay, and verify response after receiving it. 173 | * 174 | * The first byte in tx buffer must be the byte count of the packet. 175 | * If CRC or count of the response is incorrect, or a command byte did not get acknowledged 176 | * (I2), this function requests the device to resend the response. 177 | * If the response contains an error status, this function resends the command. 178 | * 179 | * \param[in] tx_buffer pointer to command 180 | * \param[in] rx_size size of response buffer 181 | * \param[out] rx_buffer pointer to response buffer 182 | * \param[in] execution_delay Start polling for a response after this many ms. 183 | * \param[in] execution_timeout polling timeout in ms 184 | * \return status of the operation 185 | */ 186 | uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer, 187 | uint8_t execution_delay, uint8_t execution_timeout) 188 | { 189 | uint8_t ret_code = SHA204_FUNC_FAIL; 190 | uint8_t ret_code_resync; 191 | uint8_t n_retries_send; 192 | uint8_t n_retries_receive; 193 | uint8_t i; 194 | uint8_t status_byte; 195 | uint8_t count = tx_buffer[SHA204_BUFFER_POS_COUNT]; 196 | uint8_t count_minus_crc = count - SHA204_CRC_SIZE; 197 | uint16_t execution_timeout_us = (uint16_t) (execution_timeout * 1000) + SHA204_RESPONSE_TIMEOUT; 198 | volatile uint16_t timeout_countdown; 199 | 200 | // Append CRC. 201 | sha204c_calculate_crc(count_minus_crc, tx_buffer, tx_buffer + count_minus_crc); 202 | 203 | // Retry loop for sending a command and receiving a response. 204 | n_retries_send = SHA204_RETRY_COUNT + 1; 205 | 206 | while ((n_retries_send-- > 0) && (ret_code != SHA204_SUCCESS)) { 207 | 208 | // Send command. 209 | ret_code = sha204p_send_command(count, tx_buffer); 210 | if (ret_code != SHA204_SUCCESS) { 211 | if (sha204c_resync(rx_size, rx_buffer) == SHA204_RX_NO_RESPONSE) 212 | // The device seems to be dead in the water. 213 | return ret_code; 214 | else 215 | continue; 216 | } 217 | 218 | // Wait minimum command execution time and then start polling for a response. 219 | delay_ms(execution_delay); 220 | 221 | // Retry loop for receiving a response. 222 | n_retries_receive = SHA204_RETRY_COUNT + 1; 223 | while (n_retries_receive-- > 0) { 224 | 225 | // Reset response buffer. 226 | for (i = 0; i < rx_size; i++) 227 | rx_buffer[i] = 0; 228 | 229 | // Poll for response. 230 | timeout_countdown = execution_timeout_us; 231 | do { 232 | ret_code = sha204p_receive_response(rx_size, rx_buffer); 233 | timeout_countdown -= SHA204_RESPONSE_TIMEOUT; 234 | } while ((timeout_countdown > SHA204_RESPONSE_TIMEOUT) && (ret_code == SHA204_RX_NO_RESPONSE)); 235 | 236 | if (ret_code == SHA204_RX_NO_RESPONSE) { 237 | // We did not receive a response. Re-synchronize and send command again. 238 | if (sha204c_resync(rx_size, rx_buffer) == SHA204_RX_NO_RESPONSE) 239 | // The device seems to be dead in the water. 240 | return ret_code; 241 | else 242 | break; 243 | } 244 | 245 | // Check whether we received a valid response. 246 | if (ret_code == SHA204_INVALID_SIZE) { 247 | // We see 0xFF for the count when communication got out of sync. 248 | ret_code_resync = sha204c_resync(rx_size, rx_buffer); 249 | if (ret_code_resync == SHA204_SUCCESS) 250 | // We did not have to wake up the device. Try receiving response again. 251 | continue; 252 | if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP) 253 | // We could re-synchronize, but only after waking up the device. 254 | // Re-send command. 255 | break; 256 | else 257 | // We failed to re-synchronize. 258 | return ret_code; 259 | } 260 | 261 | // We received a response of valid size. 262 | // Check the consistency of the response. 263 | ret_code = sha204c_check_crc(rx_buffer); 264 | if (ret_code == SHA204_SUCCESS) { 265 | // Received valid response. 266 | if (rx_buffer[SHA204_BUFFER_POS_COUNT] > SHA204_RSP_SIZE_MIN) 267 | // Received non-status response. We are done. 268 | return ret_code; 269 | 270 | // Received status response. 271 | status_byte = rx_buffer[SHA204_BUFFER_POS_STATUS]; 272 | 273 | // Translate the three possible device status error codes 274 | // into library return codes. 275 | if (status_byte == SHA204_STATUS_BYTE_PARSE) 276 | return SHA204_PARSE_ERROR; 277 | if (status_byte == SHA204_STATUS_BYTE_EXEC) 278 | return SHA204_CMD_FAIL; 279 | if (status_byte == SHA204_STATUS_BYTE_COMM) { 280 | // In case of the device status byte indicating a communication 281 | // error this function exits the retry loop for receiving a response 282 | // and enters the overall retry loop 283 | // (send command / receive response). 284 | ret_code = SHA204_STATUS_CRC; 285 | break; 286 | } 287 | 288 | // Received status response from CheckMAC, DeriveKey, GenDig, 289 | // Lock, Nonce, Pause, UpdateExtra, or Write command. 290 | return ret_code; 291 | } 292 | 293 | else { 294 | // Received response with incorrect CRC. 295 | ret_code_resync = sha204c_resync(rx_size, rx_buffer); 296 | if (ret_code_resync == SHA204_SUCCESS) 297 | // We did not have to wake up the device. Try receiving response again. 298 | continue; 299 | if (ret_code_resync == SHA204_RESYNC_WITH_WAKEUP) 300 | // We could re-synchronize, but only after waking up the device. 301 | // Re-send command. 302 | break; 303 | else 304 | // We failed to re-synchronize. 305 | return ret_code; 306 | } // block end of check response consistency 307 | 308 | } // block end of receive retry loop 309 | 310 | } // block end of send and receive retry loop 311 | 312 | return ret_code; 313 | } 314 | -------------------------------------------------------------------------------- /src/atsha204-atmel/sha204_comm.h: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Definitions and Prototypes for Communication Layer of ATSHA204 Library 3 | * \author Atmel Crypto Products 4 | * \date January 15, 2013 5 | 6 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 7 | * 8 | * \atsha204_library_license_start 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 20 | * 3. The name of Atmel may not be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * 4. This software may only be redistributed and used in connection with an 24 | * Atmel integrated circuit. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 27 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 28 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 29 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 30 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 34 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 35 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 | * POSSIBILITY OF SUCH DAMAGE. 37 | * 38 | * \atsha204_library_license_stop 39 | */ 40 | 41 | #ifndef SHA204_COMM_H 42 | # define SHA204_COMM_H 43 | 44 | #include // data type definitions 45 | 46 | #include "sha204_physical.h" // declarations that are common to all interface implementations 47 | 48 | /** \defgroup atsha204_communication Module 02: Communication 49 | * 50 | * This module implements communication with the device. It does not depend on the interface 51 | * (SWI or I2C). 52 | * 53 | * Basic communication flow: 54 | * - Calculate CRC of command packet and append. 55 | * - Send command and repeat if it failed. 56 | * - Delay for minimum command execution time. 57 | * - Poll for response until maximum execution time. Repeat if communication failed. 58 | * 59 | * Retries are implemented including sending the command again depending on the type 60 | * of failure. A retry might include waking up the device which will be indicated by 61 | * an appropriate return status. The number of retries is defined with a macro and 62 | * can be set to 0 at compile time. 63 | @{ */ 64 | 65 | //! maximum command delay 66 | #define SHA204_COMMAND_EXEC_MAX ((uint8_t) (69.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5)) 67 | 68 | //! minimum number of bytes in command (from count byte to second CRC byte) 69 | #define SHA204_CMD_SIZE_MIN ((uint8_t) 7) 70 | 71 | //! maximum size of command packet (CheckMac) 72 | #define SHA204_CMD_SIZE_MAX ((uint8_t) 84) 73 | 74 | //! number of CRC bytes 75 | #define SHA204_CRC_SIZE ((uint8_t) 2) 76 | 77 | //! buffer index of status byte in status response 78 | #define SHA204_BUFFER_POS_STATUS (1) 79 | 80 | //! buffer index of first data byte in data response 81 | #define SHA204_BUFFER_POS_DATA (1) 82 | 83 | //! status byte after wake-up 84 | #define SHA204_STATUS_BYTE_WAKEUP ((uint8_t) 0x11) 85 | 86 | //! command parse error 87 | #define SHA204_STATUS_BYTE_PARSE ((uint8_t) 0x03) 88 | 89 | //! command execution error 90 | #define SHA204_STATUS_BYTE_EXEC ((uint8_t) 0x0F) 91 | 92 | //! communication error 93 | #define SHA204_STATUS_BYTE_COMM ((uint8_t) 0xFF) 94 | 95 | 96 | void sha204c_calculate_crc(uint8_t length, uint8_t *data, uint8_t *crc); 97 | uint8_t sha204c_wakeup(uint8_t *response); 98 | uint8_t sha204c_send_and_receive(uint8_t *tx_buffer, uint8_t rx_size, uint8_t *rx_buffer, 99 | uint8_t execution_delay, uint8_t execution_timeout); 100 | 101 | /** @} */ 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /src/atsha204-atmel/sha204_config.h: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Definitions for Configurable Values of the ATSHA204 Library 3 | * 4 | * This file contains several library configuration sections 5 | * for the three interfaces the library supports 6 | * (SWI using GPIO or UART, and I2C) and one that is common 7 | * to all interfaces. 8 | * \author Atmel Crypto Products 9 | * \date January 9, 2013 10 | 11 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 12 | * 13 | * \atsha204_library_license_start 14 | * 15 | * Redistribution and use in source and binary forms, with or without 16 | * modification, are permitted provided that the following conditions are met: 17 | * 18 | * 1. Redistributions of source code must retain the above copyright notice, 19 | * this list of conditions and the following disclaimer. 20 | * 21 | * 2. Redistributions in binary form must reproduce the above copyright notice, 22 | * this list of conditions and the following disclaimer in the documentation 23 | * and/or other materials provided with the distribution. 24 | * 25 | * 3. The name of Atmel may not be used to endorse or promote products derived 26 | * from this software without specific prior written permission. 27 | * 28 | * 4. This software may only be redistributed and used in connection with an 29 | * Atmel integrated circuit. 30 | * 31 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 32 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 33 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 34 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 35 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 40 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 | * POSSIBILITY OF SUCH DAMAGE. 42 | * 43 | * \atsha204_library_license_stop 44 | */ 45 | 46 | #ifndef SHA204_CONFIG_H 47 | # define SHA204_CONFIG_H 48 | 49 | #include // data type definitions 50 | 51 | /** \defgroup atsha204_config Module 07: Configuration Definitions 52 | * 53 | * Tune the values of these timing definitions for your system. 54 | * Always include this file no matter whether you use SWI or I2C. 55 | * Please refer to the actual file because Doxygen cannot parse 56 | * nested macros with the same name. 57 | @{ */ 58 | 59 | /** \name Configuration Definitions Common to All Interfaces 60 | @{ */ 61 | 62 | /** \brief maximum CPU clock deviation to higher frequency (crystal etc.) 63 | * This value is used to establish time related worst case numbers, for 64 | * example to calculate execution delays and timeouts. 65 | */ 66 | #define CPU_CLOCK_DEVIATION_POSITIVE (1.01) 67 | 68 | /** \brief maximum CPU clock deviation to lower frequency (crystal etc.) 69 | * This value is used to establish time related worst case numbers, for 70 | * example to calculate execution delays and timeouts. 71 | */ 72 | #define CPU_CLOCK_DEVIATION_NEGATIVE (0.99) 73 | 74 | /** \brief number of command / response retries 75 | * 76 | * If communication is lost, re-synchronization includes waiting for the 77 | * longest possible execution time of a command. 78 | * This adds a \ref SHA204_COMMAND_EXEC_MAX delay to every retry. 79 | * Every increment of the number of retries increases the time 80 | * the library is spending in the retry loop by \ref SHA204_COMMAND_EXEC_MAX. 81 | */ 82 | #define SHA204_RETRY_COUNT (1) 83 | 84 | /** @} */ 85 | 86 | 87 | /** \name Available Definitions for Interfaces 88 | * 89 | * \brief Either un-comment one of the definitions or place it in your project settings. 90 | * The definitions to choose from are: 91 | * - SHA204_SWI_BITBANG (SWI using GPIO peripheral) 92 | * - SHA204_SWI_UART (SWI using UART peripheral) 93 | * - SHA204_I2C (I2C using I2C peripheral) 94 | * 95 | @{ */ 96 | //! Dummy macro that allow Doxygen to parse this group. 97 | #define DOXYGEN_DUMMY 0 98 | // #define SHA204_SWI_BITBANG 99 | // #define SHA204_SWI_UART 100 | // #define SHA204_I2C 101 | 102 | /** @} */ 103 | 104 | #ifndef SHA204_SWI_BITBANG 105 | #ifndef SHA204_SWI_UART 106 | /* If not otherwise specified, this is an i2c library */ 107 | #define SHA204_I2C 108 | #endif 109 | #endif 110 | 111 | 112 | #ifdef SHA204_SWI_BITBANG 113 | /** \name Configuration Definitions for SWI (GPIO) Interface 114 | @{ */ 115 | 116 | /** \brief This value is the same as START_PULSE_TIME_OUT in 117 | * bitbang_config.h, but in us instead of loop counts. 118 | */ 119 | # define SWI_RECEIVE_TIME_OUT ((uint16_t) 163) 120 | 121 | //! It takes 312.5 us to send a byte (9 single-wire bits / 230400 Baud * 8 flag bits). 122 | # define SWI_US_PER_BYTE ((uint16_t) 313) 123 | 124 | /** @} */ 125 | #endif 126 | 127 | 128 | 129 | #ifdef SHA204_SWI_UART 130 | /** \name Configuration Definitions for SWI (UART) Interface 131 | @{ */ 132 | 133 | //! receive timeout in us instead of loop counts 134 | # define SWI_RECEIVE_TIME_OUT ((uint16_t) 153) 135 | 136 | //! It takes 312.5 us to send a byte (9 single-wire bits / 230400 Baud * 8 flag bits). 137 | # define SWI_US_PER_BYTE ((uint16_t) 313) 138 | 139 | //! SWI response timeout is the sum of receive timeout and the time it takes to send the TX flag. 140 | # ifndef SHA204_RESPONSE_TIMEOUT 141 | # define SHA204_RESPONSE_TIMEOUT ((uint16_t) SWI_RECEIVE_TIME_OUT + SWI_US_PER_BYTE) 142 | # endif 143 | 144 | /** @} */ 145 | 146 | #endif 147 | 148 | 149 | 150 | #if defined(SHA204_SWI_BITBANG) || defined(SHA204_SWI_UART) 151 | /** \name Configuration Definitions for SWI Interface, Common to GPIO and UART 152 | @{ */ 153 | 154 | //! delay before sending a transmit flag in the synchronization routine 155 | # define SHA204_SYNC_TIMEOUT ((uint8_t) 85) 156 | 157 | //! SWI response timeout is the sum of receive timeout and the time it takes to send the TX flag. 158 | # ifndef SHA204_RESPONSE_TIMEOUT 159 | # define SHA204_RESPONSE_TIMEOUT ((uint16_t) SWI_RECEIVE_TIME_OUT + SWI_US_PER_BYTE) 160 | # endif 161 | 162 | /** @} */ 163 | 164 | #endif 165 | 166 | 167 | 168 | #ifdef SHA204_I2C 169 | /** \name Configuration Definitions for I2C Interface 170 | @{ */ 171 | 172 | /** \brief For I2C, the response polling time is the time 173 | * it takes to send the I2C address. 174 | * 175 | * This value is used to timeout when waiting for a response. 176 | */ 177 | # ifndef SHA204_RESPONSE_TIMEOUT 178 | # define SHA204_RESPONSE_TIMEOUT ((uint16_t) 37) 179 | # endif 180 | 181 | /** @} */ 182 | 183 | #endif 184 | 185 | 186 | /** @} */ 187 | 188 | #endif 189 | -------------------------------------------------------------------------------- /src/atsha204-atmel/sha204_examples.h: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Application Examples That Use the ATSHA204 Library 3 | * \author Atmel Crypto Products 4 | * \date January 9, 2013 5 | 6 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 7 | * 8 | * \atsha204_library_license_start 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 20 | * 3. The name of Atmel may not be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * 4. This software may only be redistributed and used in connection with an 24 | * Atmel integrated circuit. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 27 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 28 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 29 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 30 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 34 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 35 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 | * POSSIBILITY OF SUCH DAMAGE. 37 | * 38 | * \atsha204_library_license_stop 39 | * 40 | * Example functions are given that demonstrate the device. 41 | * The examples demonstrate client / host scenarios with a random challenge. 42 | * Using a random challenge makes replay attacks impossible. 43 | * Examples that need two devices (advanced examples) run only with 44 | * I2C devices or SWI devices using GPIO. When running the advanced examples 45 | * with SWI devices, their SDA cannot be shared. Therefore, these examples run 46 | * only in the bit-banged and not in the UART implementation of SWI. 47 | * It is possible for SWI devices to share SDA, but then the Pause command 48 | * has to be used to idle all devices except one to communicate with. 49 | * In such a system, the Selector byte of every device has to be unique 50 | * and not 0 which is the default when shipped. 51 | */ 52 | #ifndef SHA204_EXAMPLES_H 53 | # define SHA204_EXAMPLES_H 54 | 55 | #include // data type definitions 56 | 57 | 58 | /** \ingroup sha204_examples Example Definitions 59 | @{ */ 60 | 61 | /** \brief This definition selects a simple MAC / CheckMac example using 62 | * an ATSHA204 as the host (key storage and SHA-256 calculation). 63 | */ 64 | #define SHA204_EXAMPLE_CHECKMAC_DEVICE 1 65 | 66 | /** \brief This definition selects a simple MAC / CheckMac example using 67 | * firmware as the host (key storage and SHA-256 calculation). 68 | */ 69 | #define SHA204_EXAMPLE_CHECKMAC_FIRMWARE 2 70 | 71 | /** \brief This definition selects an advanced MAC / CheckMac example using 72 | * a derived key. This example runs only with two devices. 73 | */ 74 | #define SHA204_EXAMPLE_DERIVE_KEY 3 75 | 76 | /** \brief This definition selects an advanced MAC / CheckMac example using 77 | * a diversified key. This example runs only with two devices. 78 | */ 79 | #define SHA204_EXAMPLE_DIVERSIFY_KEY 4 80 | 81 | /** \brief This definition selects a utility that changes the I2C default 82 | * address of the device to SHA204_HOST_ADDRESS. 83 | * 84 | * You need to change the address on one device from its default 85 | * in order to run the advanced MAC / CheckMac examples. 86 | */ 87 | #define SHA204_EXAMPLE_CHANGE_I2C_ADDRESS 5 88 | 89 | /** \brief This definition selects a utility that reads all 88 bytes from 90 | * the configuration zone. 91 | * 92 | * This gives you easy access to the device configuration 93 | * (e.g. serial number, lock status, configuration of keys). 94 | */ 95 | #define SHA204_EXAMPLE_READ_CONFIG_ZONE 6 96 | 97 | /** -------------------- Define an example. -------------------------- 98 | * 99 | */ 100 | #define SHA204_EXAMPLE SHA204_EXAMPLE_CHECKMAC_DEVICE 101 | 102 | /** \brief Use this definition if you like to lock the configuration zone 103 | of the host during personalization. 104 | 105 | Once the configuration zone is locked you cannot modify 106 | the configuration zone anymore, but the ATSHA204 device will then generate 107 | true random numbers instead of a 0xFFFF0000FFFF0000... sequence. 108 | The example assumes that the data line of the host is 109 | much less accessible by an adversary than the data line of the client. 110 | Therefore, the example requests a random number from the host and not 111 | the client, since an adversary could take over the data line and 112 | inject a number of her choice. 113 | */ 114 | #define SHA204_EXAMPLE_CONFIG_WITH_LOCK 0 115 | 116 | /** @} */ 117 | 118 | 119 | #ifdef SHA204_I2C 120 | /** \brief I2C address for client device 121 | If you have two devices at your disposal you can run an example as a real-world 122 | host / client scenario. You have to change the address of one of the devices 123 | by writing it to configuration zone address 16. 124 | Be aware that bit 3 of the I2C address is also used to configure the input level 125 | reference (see data sheet table 2-1). 126 | To change the address you can run the \ref SHA204_EXAMPLE_READ_CONFIG_ZONE example. 127 | */ 128 | # define SHA204_CLIENT_ADDRESS (0xC8) 129 | /** \brief I2C address for host device 130 | To make the simple Mac / CheckMac I2C examples work out-of-the-box without 131 | changing the I2C address for the host device, you can make the host address the 132 | same as the client address. See \ref SHA204_CLIENT_ADDRESS. 133 | */ 134 | //# define SHA204_HOST_ADDRESS SHA204_CLIENT_ADDRESS 135 | # define SHA204_HOST_ADDRESS (0xCA) 136 | #else 137 | /** \ingroup sha204_examples Device Selectors 138 | These settings have an effect only when using bit-banging where the SDA of every 139 | device is connected to its own GPIO pin. When using only one UART the SDA of both 140 | devices is connected to the same GPIO pin. In that case you have create a 141 | version of \ref sha204p_set_device_id that would use a Pause command. (Refer 142 | to data sheet about the Pause command.) 143 | @{ */ 144 | # define SHA204_CLIENT_ADDRESS (0x00) 145 | # define SHA204_HOST_ADDRESS (0x01) 146 | /** @} */ 147 | #endif 148 | 149 | // Check example selection against project selection. 150 | #if (SHA204_EXAMPLE == SHA204_EXAMPLE_DERIVE_KEY || SHA204_EXAMPLE == SHA204_EXAMPLE_DIVERSIFY_KEY) 151 | # ifdef SHA204_SWI_UART 152 | # error The selected example will not run under the UART project. 153 | # elif SHA204_CLIENT_ADDRESS == SHA204_HOST_ADDRESS 154 | # error The selected example needs different addresses for client and host. 155 | # endif 156 | #endif 157 | #if (SHA204_EXAMPLE == SHA204_EXAMPLE_CHANGE_I2C_ADDRESS && !defined(SHA204_I2C)) 158 | # error The selected example will only run under the I2C project. 159 | #endif 160 | 161 | 162 | /** \ingroup sha204_examples Key Identifiers Used by the Examples 163 | Do not change these key identifiers since related values (configuration addresses) 164 | are hard-coded in associated functions. 165 | @{ */ 166 | #define SHA204_KEY_ID ( 0) 167 | #define SHA204_KEY_PARENT (13) 168 | #define SHA204_KEY_CHILD (10) 169 | /** @} */ 170 | 171 | #define sha204e_wakeup_sleep() {sha204p_wakeup(); sha204p_sleep();} 172 | 173 | uint8_t sha204e_checkmac_device(void); 174 | uint8_t sha204e_checkmac_firmware(void); 175 | uint8_t sha204e_checkmac_derived_key(void); 176 | uint8_t sha204e_checkmac_diversified_key(void); 177 | uint8_t sha204e_change_i2c_address(void); 178 | uint8_t sha204e_read_config_zone(uint8_t device_id, uint8_t *config_data); 179 | 180 | #endif 181 | -------------------------------------------------------------------------------- /src/atsha204-atmel/sha204_i2c.c: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Functions for I2C Physical Hardware Independent Layer of ATSHA204 Library 3 | * \author Atmel Crypto Products 4 | * \date January 11, 2013 5 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 6 | * 7 | * \atsha204_library_license_start 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. The name of Atmel may not be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * 4. This software may only be redistributed and used in connection with an 23 | * Atmel integrated circuit. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 26 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 28 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 29 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | * POSSIBILITY OF SUCH DAMAGE. 36 | * 37 | * \atsha204_library_license_stop 38 | */ 39 | #define SHA204_GPIO_WAKEUP 40 | 41 | #ifdef SHA204_GPIO_WAKEUP 42 | # include // GPIO definitions 43 | #endif 44 | 45 | #include "../common-atmel/i2c_phys.h" // hardware dependent declarations for I2C 46 | #include "sha204_physical.h" // declarations that are common to all interface implementations 47 | #include "sha204_lib_return_codes.h" // declarations of function return codes 48 | #include "../common-atmel/timer_utilities.h" // definitions for delay 49 | // Functions 50 | #include "Arduino.h" 51 | 52 | /** \defgroup sha204_i2c Module 05: I2C Abstraction Module 53 | * 54 | * These functions and definitions abstract the I2C hardware. They implement the functions 55 | * declared in \ref sha204_physical.h. 56 | @{ */ 57 | 58 | 59 | /** \brief I2C address used at ATSHA204 library startup. */ 60 | #define SHA204_I2C_DEFAULT_ADDRESS ((uint8_t) 0xC8) 61 | 62 | 63 | /** \brief This enumeration lists all packet types sent to a SHA204 device. 64 | * 65 | * The following byte stream is sent to a ATSHA204 I2C device: 66 | * {I2C start} {I2C address} {word address} [{data}] {I2C stop}. 67 | * Data are only sent after a word address of value #SHA204_I2C_PACKET_FUNCTION_NORMAL. 68 | */ 69 | enum i2c_word_address { 70 | SHA204_I2C_PACKET_FUNCTION_RESET, //!< Reset device. 71 | SHA204_I2C_PACKET_FUNCTION_SLEEP, //!< Put device into Sleep mode. 72 | SHA204_I2C_PACKET_FUNCTION_IDLE, //!< Put device into Idle mode. 73 | SHA204_I2C_PACKET_FUNCTION_NORMAL //!< Write / evaluate data that follow this word address byte. 74 | }; 75 | 76 | 77 | /** \brief This enumeration lists flags for I2C read or write addressing. */ 78 | enum i2c_read_write_flag { 79 | I2C_WRITE = (uint8_t) 0x00, //!< write command flag 80 | I2C_READ = (uint8_t) 0x01 //!< read command flag 81 | }; 82 | 83 | 84 | //! I2C address is set when calling #sha204p_init or #sha204p_set_device_id. 85 | static uint8_t device_address; 86 | 87 | 88 | /** \brief This function sets the I2C address. 89 | * Communication functions will use this address. 90 | * 91 | * \param[in] id I2C address 92 | */ 93 | void sha204p_set_device_id(uint8_t id) 94 | { 95 | device_address = id; 96 | } 97 | 98 | 99 | /** \brief This function initializes the hardware. 100 | */ 101 | void sha204p_init(void) 102 | { 103 | i2c_enable(); 104 | device_address = SHA204_I2C_DEFAULT_ADDRESS; 105 | } 106 | 107 | // todo Let the updateDistro script delete lines that refer to 108 | // DEBUG_DIAMOND. 109 | #ifndef DEBUG_DIAMOND 110 | # define DEBUG_DIAMOND 111 | #endif 112 | /** \brief This function generates a Wake-up pulse and delays. 113 | * \return status of the operation 114 | */ 115 | uint8_t sha204p_wakeup(void) 116 | { 117 | #ifndef SHA204_GPIO_WAKEUP 118 | // Generate wakeup pulse by writing a 0 on the I2C bus. 119 | uint8_t dummy_byte = 0; 120 | uint8_t i2c_status = i2c_send_start(); 121 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 122 | return SHA204_COMM_FAIL; 123 | 124 | // To send eight zero bits it takes 10E6 / I2C clock * 8 us. 125 | delay_10us(SHA204_WAKEUP_PULSE_WIDTH - (uint8_t) (1000000.0 / 10.0 / I2C_CLOCK * 8.0)); 126 | 127 | // We have to send at least one byte between an I2C Start and an I2C Stop. 128 | (void) i2c_send_bytes(1, &dummy_byte); 129 | i2c_status = i2c_send_stop(); 130 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 131 | return SHA204_COMM_FAIL; 132 | #else 133 | // Generate wakeup pulse by disabling the I2C peripheral and 134 | // pulling SDA low. The I2C peripheral gets automatically 135 | // re-enabled when calling i2c_send_start(). 136 | TWCR = 0; // Disable I2C. 137 | pinMode(SDA, OUTPUT); 138 | digitalWrite(SDA, LOW); 139 | #ifndef DEBUG_DIAMOND 140 | delay_10us(SHA204_WAKEUP_PULSE_WIDTH); 141 | #else 142 | delay_10us(10); 143 | #endif 144 | digitalWrite(SDA, HIGH); 145 | #endif 146 | 147 | delay_ms(SHA204_WAKEUP_DELAY); 148 | 149 | return SHA204_SUCCESS; 150 | } 151 | 152 | 153 | /** \brief This function creates a Start condition and sends the 154 | * I2C address. 155 | * \param[in] read #I2C_READ for reading, #I2C_WRITE for writing 156 | * \return status of the I2C operation 157 | */ 158 | static uint8_t sha204p_send_slave_address(uint8_t read) 159 | { 160 | uint8_t sla = device_address | read; 161 | uint8_t ret_code = i2c_send_start(); 162 | if (ret_code != I2C_FUNCTION_RETCODE_SUCCESS) 163 | return ret_code; 164 | 165 | ret_code = i2c_send_bytes(1, &sla); 166 | 167 | if (ret_code != I2C_FUNCTION_RETCODE_SUCCESS) 168 | (void) i2c_send_stop(); 169 | 170 | return ret_code; 171 | } 172 | 173 | 174 | /** \brief This function sends a I2C packet enclosed by 175 | * a I2C start and stop to the device. 176 | * 177 | This function combines a I2C packet send sequence that 178 | is common to all packet types. Only if word_address is 179 | #I2C_PACKET_FUNCTION_NORMAL, count and buffer parameters are 180 | expected to be non-zero. 181 | * @param[in] word_address packet function code listed in #i2c_word_address 182 | * @param[in] count number of bytes in data buffer 183 | * @param[in] buffer pointer to data buffer 184 | * @return status of the operation 185 | */ 186 | static uint8_t sha204p_i2c_send(uint8_t word_address, uint8_t count, uint8_t *buffer) 187 | { 188 | uint8_t i2c_status = sha204p_send_slave_address(I2C_WRITE); 189 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 190 | return SHA204_COMM_FAIL; 191 | 192 | i2c_status = i2c_send_bytes(1, &word_address); 193 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 194 | return SHA204_COMM_FAIL; 195 | 196 | if (count == 0) { 197 | // We are done for packets that are not commands (Sleep, Idle, Reset). 198 | (void) i2c_send_stop(); 199 | return SHA204_SUCCESS; 200 | } 201 | 202 | i2c_status = i2c_send_bytes(count, buffer); 203 | 204 | (void) i2c_send_stop(); 205 | 206 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 207 | return SHA204_COMM_FAIL; 208 | else 209 | return SHA204_SUCCESS; 210 | } 211 | 212 | 213 | /** \brief This function sends a command to the device. 214 | * \param[in] count number of bytes to send 215 | * \param[in] command pointer to command buffer 216 | * \return status of the operation 217 | */ 218 | uint8_t sha204p_send_command(uint8_t count, uint8_t *command) 219 | { 220 | return sha204p_i2c_send(SHA204_I2C_PACKET_FUNCTION_NORMAL, count, command); 221 | } 222 | 223 | 224 | /** \brief This function puts the device into idle state. 225 | * \return status of the operation 226 | */ 227 | uint8_t sha204p_idle(void) 228 | { 229 | return sha204p_i2c_send(SHA204_I2C_PACKET_FUNCTION_IDLE, 0, NULL); 230 | } 231 | 232 | 233 | /** \brief This function puts the device into low-power state. 234 | * \return status of the operation 235 | */ 236 | uint8_t sha204p_sleep(void) 237 | { 238 | return sha204p_i2c_send(SHA204_I2C_PACKET_FUNCTION_SLEEP, 0, NULL); 239 | } 240 | 241 | 242 | /** \brief This function resets the I/O buffer of the device. 243 | * \return status of the operation 244 | */ 245 | uint8_t sha204p_reset_io(void) 246 | { 247 | return sha204p_i2c_send(SHA204_I2C_PACKET_FUNCTION_RESET, 0, NULL); 248 | } 249 | 250 | 251 | /** \brief This function receives a response from the device. 252 | * 253 | * \param[in] size size of rx buffer 254 | * \param[out] response pointer to rx buffer 255 | * \return status of the operation 256 | */ 257 | uint8_t sha204p_receive_response(uint8_t size, uint8_t *response) 258 | { 259 | uint8_t count; 260 | 261 | // Address the device and indicate that bytes are to be read. 262 | uint8_t i2c_status = sha204p_send_slave_address(I2C_READ); 263 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) { 264 | // Translate error so that the Communication layer 265 | // can distinguish between a real error or the 266 | // device being busy executing a command. 267 | if (i2c_status == I2C_FUNCTION_RETCODE_NACK) 268 | i2c_status = SHA204_RX_NO_RESPONSE; 269 | 270 | return i2c_status; 271 | } 272 | 273 | // Receive count byte. 274 | i2c_status = i2c_receive_byte(response); 275 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 276 | return SHA204_COMM_FAIL; 277 | 278 | count = response[SHA204_BUFFER_POS_COUNT]; 279 | if ((count < SHA204_RSP_SIZE_MIN) || (count > size)) { 280 | (void) i2c_send_stop(); 281 | return SHA204_INVALID_SIZE; 282 | } 283 | 284 | i2c_status = i2c_receive_bytes(count - 1, &response[SHA204_BUFFER_POS_DATA]); 285 | 286 | if (i2c_status != I2C_FUNCTION_RETCODE_SUCCESS) 287 | return SHA204_COMM_FAIL; 288 | else 289 | return SHA204_SUCCESS; 290 | } 291 | 292 | 293 | /** \brief This function resynchronizes communication. 294 | * 295 | * Parameters are not used for I2C.\n 296 | * Re-synchronizing communication is done in a maximum of three steps 297 | * listed below. This function implements the first step. Since 298 | * steps 2 and 3 (sending a Wake-up token and reading the response) 299 | * are the same for I2C and SWI, they are 300 | * implemented in the communication layer (#sha204c_resync). 301 |
    302 |
  1. 303 | To ensure an IO channel reset, the system should send 304 | the standard I2C software reset sequence, as follows: 305 |
      306 |
    • a Start condition
    • 307 |
    • nine cycles of SCL, with SDA held high
    • 308 |
    • another Start condition
    • 309 |
    • a Stop condition
    • 310 |
    311 | It should then be possible to send a read sequence and 312 | if synchronization has completed properly the ATSHA204 will 313 | acknowledge the device address. The chip may return data or 314 | may leave the bus floating (which the system will interpret 315 | as a data value of 0xFF) during the data periods.\n 316 | If the chip does acknowledge the device address, the system 317 | should reset the internal address counter to force the 318 | ATSHA204 to ignore any partial input command that may have 319 | been sent. This can be accomplished by sending a write 320 | sequence to word address 0x00 (Reset), followed by a 321 | Stop condition. 322 |
  2. 323 |
  3. 324 | If the chip does NOT respond to the device address with an ACK, 325 | then it may be asleep. In this case, the system should send a 326 | complete Wake token and wait t_whi after the rising edge. The 327 | system may then send another read sequence and if synchronization 328 | has completed the chip will acknowledge the device address. 329 |
  4. 330 |
  5. 331 | If the chip still does not respond to the device address with 332 | an acknowledge, then it may be busy executing a command. The 333 | system should wait the longest TEXEC and then send the 334 | read sequence, which will be acknowledged by the chip. 335 |
  6. 336 |
337 | * \param[in] size size of rx buffer 338 | * \param[out] response pointer to response buffer 339 | * \return status of the operation 340 | */ 341 | uint8_t sha204p_resync(uint8_t size, uint8_t *response) 342 | { 343 | uint8_t nine_clocks = 0xFF; 344 | uint8_t ret_code = i2c_send_start(); 345 | 346 | // Do not evaluate the return code that most likely indicates error, 347 | // since nine_clocks is unlikely to be acknowledged. 348 | (void) i2c_send_bytes(1, &nine_clocks); 349 | 350 | // Send another Start. The function sends also one byte, 351 | // the I2C address of the device, because I2C specification 352 | // does not allow sending a Stop right after a Start condition. 353 | ret_code = sha204p_send_slave_address(I2C_READ); 354 | 355 | // Send only a Stop if the above call succeeded. 356 | // Otherwise the above function has sent it already. 357 | if (ret_code == I2C_FUNCTION_RETCODE_SUCCESS) 358 | ret_code = i2c_send_stop(); 359 | 360 | // Return error status if we failed to re-sync. 361 | if (ret_code != I2C_FUNCTION_RETCODE_SUCCESS) 362 | return SHA204_COMM_FAIL; 363 | 364 | // Try to send a Reset IO command if re-sync succeeded. 365 | return sha204p_reset_io(); 366 | } 367 | 368 | /** @} */ 369 | -------------------------------------------------------------------------------- /src/atsha204-atmel/sha204_lib_return_codes.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | /** \file 5 | * \brief Definitions for ATSHA204 Library Return Codes 6 | * \author Atmel Crypto Products 7 | * \date January 15, 2013 8 | * 9 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 10 | * 11 | * \atsha204_library_license_start 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions are met: 15 | * 16 | * 1. Redistributions of source code must retain the above copyright notice, 17 | * this list of conditions and the following disclaimer. 18 | * 19 | * 2. Redistributions in binary form must reproduce the above copyright notice, 20 | * this list of conditions and the following disclaimer in the documentation 21 | * and/or other materials provided with the distribution. 22 | * 23 | * 3. The name of Atmel may not be used to endorse or promote products derived 24 | * from this software without specific prior written permission. 25 | * 26 | * 4. This software may only be redistributed and used in connection with an 27 | * Atmel integrated circuit. 28 | * 29 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 30 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 31 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 32 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 33 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 38 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39 | * POSSIBILITY OF SUCH DAMAGE. 40 | * 41 | * \atsha204_library_license_stop 42 | */ 43 | 44 | #ifndef SHA204_LIB_RETURN_CODES_H 45 | # define SHA204_LIB_RETURN_CODES_H 46 | 47 | #include // data type definitions 48 | 49 | 50 | /** \defgroup atsha204_status Module 08: Library Return Codes 51 | * 52 | @{ */ 53 | 54 | #define SHA204_SUCCESS ((uint8_t) 0x00) //!< Function succeeded. 55 | #define SHA204_CHECKMAC_FAILED ((uint8_t) 0xD1) //!< response status byte indicates CheckMac failure 56 | #define SHA204_PARSE_ERROR ((uint8_t) 0xD2) //!< response status byte indicates parsing error 57 | #define SHA204_CMD_FAIL ((uint8_t) 0xD3) //!< response status byte indicates command execution error 58 | #define SHA204_STATUS_CRC ((uint8_t) 0xD4) //!< response status byte indicates CRC error 59 | #define SHA204_STATUS_UNKNOWN ((uint8_t) 0xD5) //!< response status byte is unknown 60 | #define SHA204_FUNC_FAIL ((uint8_t) 0xE0) //!< Function could not execute due to incorrect condition / state. 61 | #define SHA204_GEN_FAIL ((uint8_t) 0xE1) //!< unspecified error 62 | #define SHA204_BAD_PARAM ((uint8_t) 0xE2) //!< bad argument (out of range, null pointer, etc.) 63 | #define SHA204_INVALID_ID ((uint8_t) 0xE3) //!< invalid device id, id not set 64 | #define SHA204_INVALID_SIZE ((uint8_t) 0xE4) //!< Count value is out of range or greater than buffer size. 65 | #define SHA204_BAD_CRC ((uint8_t) 0xE5) //!< incorrect CRC received 66 | #define SHA204_RX_FAIL ((uint8_t) 0xE6) //!< Timed out while waiting for response. Number of bytes received is > 0. 67 | #define SHA204_RX_NO_RESPONSE ((uint8_t) 0xE7) //!< Not an error while the Command layer is polling for a command response. 68 | #define SHA204_RESYNC_WITH_WAKEUP ((uint8_t) 0xE8) //!< Re-synchronization succeeded, but only after generating a Wake-up 69 | 70 | #define SHA204_COMM_FAIL ((uint8_t) 0xF0) //!< Communication with device failed. Same as in hardware dependent modules. 71 | #define SHA204_TIMEOUT ((uint8_t) 0xF1) //!< Timed out while waiting for response. Number of bytes received is 0. 72 | 73 | /** @} */ 74 | 75 | #endif 76 | #ifdef __cplusplus 77 | } 78 | #endif 79 | -------------------------------------------------------------------------------- /src/atsha204-atmel/sha204_physical.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | /** \file 5 | * \brief Definitions and Prototypes for Physical Layer Interface of ATSHA204 Library 6 | * \author Atmel Crypto Products 7 | * \date January 11, 2013 8 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 9 | * 10 | * \atsha204_library_license_start 11 | * 12 | * Redistribution and use in source and binary forms, with or without 13 | * modification, are permitted provided that the following conditions are met: 14 | * 15 | * 1. Redistributions of source code must retain the above copyright notice, 16 | * this list of conditions and the following disclaimer. 17 | * 18 | * 2. Redistributions in binary form must reproduce the above copyright notice, 19 | * this list of conditions and the following disclaimer in the documentation 20 | * and/or other materials provided with the distribution. 21 | * 22 | * 3. The name of Atmel may not be used to endorse or promote products derived 23 | * from this software without specific prior written permission. 24 | * 25 | * 4. This software may only be redistributed and used in connection with an 26 | * Atmel integrated circuit. 27 | * 28 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 29 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 30 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 31 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 32 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 36 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 37 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 | * POSSIBILITY OF SUCH DAMAGE. 39 | * 40 | * \atsha204_library_license_stop 41 | */ 42 | #ifndef SHA204_PHYSICAL_H 43 | # define SHA204_PHYSICAL_H 44 | 45 | #include // data type definitions 46 | 47 | #include "sha204_config.h" // configuration values 48 | 49 | 50 | /** \defgroup sha204_physical Module 03: Header File for Interface Abstraction Modules 51 | * 52 | * \brief This header file contains definitions and function prototypes for SWI and I2C. 53 | * The prototypes are the same for both interfaces but are of course implemented differently. 54 | * Always include this file no matter whether you use SWI or I2C. 55 | @{ */ 56 | 57 | #define SHA204_RSP_SIZE_MIN ((uint8_t) 4) //!< minimum number of bytes in response 58 | #define SHA204_RSP_SIZE_MAX ((uint8_t) 35) //!< maximum size of response packet 59 | 60 | #define SHA204_BUFFER_POS_COUNT (0) //!< buffer index of count byte in command or response 61 | #define SHA204_BUFFER_POS_DATA (1) //!< buffer index of data in response 62 | 63 | //! width of Wakeup pulse in 10 us units 64 | #define SHA204_WAKEUP_PULSE_WIDTH (uint8_t) (6.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5) 65 | 66 | //! delay between Wakeup pulse and communication in ms 67 | #define SHA204_WAKEUP_DELAY (uint8_t) (3.0 * CPU_CLOCK_DEVIATION_POSITIVE + 0.5) 68 | 69 | 70 | uint8_t sha204p_send_command(uint8_t count, uint8_t *command); 71 | uint8_t sha204p_receive_response(uint8_t size, uint8_t *response); 72 | void sha204p_init(void); 73 | void sha204p_set_device_id(uint8_t id); 74 | uint8_t sha204p_wakeup(void); 75 | uint8_t sha204p_idle(void); 76 | uint8_t sha204p_sleep(void); 77 | uint8_t sha204p_reset_io(void); 78 | uint8_t sha204p_resync(uint8_t size, uint8_t *response); 79 | 80 | /** @} */ 81 | 82 | #endif 83 | #ifdef __cplusplus 84 | } 85 | #endif 86 | -------------------------------------------------------------------------------- /src/atsha204-atmel/sha204_swi.c: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Functions for Single Wire, Hardware Independent Physical Layer of ATSHA204 Library 3 | * 4 | * Possible return codes from send functions in the hardware dependent module 5 | * are SWI_FUNCTION_RETCODE_SUCCESS and SWI_FUNCTION_RETCODE_TIMEOUT. These 6 | * are the same values in swi_phys.h and sha204_lib_return_codes.h. No return code 7 | * translation is needed in these cases (e.g. #sha204p_idle, #sha204p_sleep). 8 | * 9 | * \author Atmel Crypto Products 10 | * \date January 11, 2013 11 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 12 | * 13 | * \atsha204_library_license_start 14 | * 15 | * Redistribution and use in source and binary forms, with or without 16 | * modification, are permitted provided that the following conditions are met: 17 | * 18 | * 1. Redistributions of source code must retain the above copyright notice, 19 | * this list of conditions and the following disclaimer. 20 | * 21 | * 2. Redistributions in binary form must reproduce the above copyright notice, 22 | * this list of conditions and the following disclaimer in the documentation 23 | * and/or other materials provided with the distribution. 24 | * 25 | * 3. The name of Atmel may not be used to endorse or promote products derived 26 | * from this software without specific prior written permission. 27 | * 28 | * 4. This software may only be redistributed and used in connection with an 29 | * Atmel integrated circuit. 30 | * 31 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 32 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 33 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 34 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 35 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 40 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 41 | * POSSIBILITY OF SUCH DAMAGE. 42 | * 43 | * \atsha204_library_license_stop 44 | */ 45 | 46 | #include "../common-atmel/swi_phys.h" // hardware dependent declarations for SWI 47 | #include "sha204_physical.h" // declarations that are common to all interface implementations 48 | #include "sha204_lib_return_codes.h" // declarations of function return codes 49 | #include "../common-atmel/timer_utilities.h" // definitions for delay functions 50 | 51 | #if defined(SHA204_SWI_BITBANG) || defined(SHA204_SWI_UART) 52 | /** \defgroup sha204_swi Module 04: SWI Abstraction Module 53 | * 54 | * These functions and definitions abstract the SWI hardware. They implement the functions 55 | * declared in \ref sha204_physical.h. 56 | @{ */ 57 | 58 | 59 | #define SHA204_SWI_FLAG_CMD ((uint8_t) 0x77) //!< flag preceding a command 60 | #define SHA204_SWI_FLAG_TX ((uint8_t) 0x88) //!< flag requesting a response 61 | #define SHA204_SWI_FLAG_IDLE ((uint8_t) 0xBB) //!< flag requesting to go into Idle mode 62 | #define SHA204_SWI_FLAG_SLEEP ((uint8_t) 0xCC) //!< flag requesting to go into Sleep mode 63 | 64 | 65 | /** \brief This function initializes the hardware. 66 | */ 67 | void sha204p_init(void) 68 | { 69 | swi_enable(); 70 | } 71 | 72 | 73 | /** \brief This function selects the GPIO pin used for communication. 74 | * It has no effect when using a UART. 75 | * 76 | * \param[in] id index into array of pins 77 | */ 78 | void sha204p_set_device_id(uint8_t id) 79 | { 80 | swi_set_device_id(id); 81 | } 82 | 83 | 84 | /** \brief This function sends a command to the device. 85 | * 86 | * \param[in] count number of bytes to send 87 | * \param[in] command pointer to command buffer 88 | * \return status of the operation 89 | */ 90 | uint8_t sha204p_send_command(uint8_t count, uint8_t *command) 91 | { 92 | uint8_t ret_code = swi_send_byte(SHA204_SWI_FLAG_CMD); 93 | if (ret_code != SWI_FUNCTION_RETCODE_SUCCESS) 94 | return SHA204_COMM_FAIL; 95 | 96 | return swi_send_bytes(count, command); 97 | } 98 | 99 | 100 | /** \brief This function receives a response from the device. 101 | * 102 | * \param[in] size number of bytes to receive 103 | * \param[out] response pointer to response buffer 104 | * \return status of the operation 105 | */ 106 | uint8_t sha204p_receive_response(uint8_t size, uint8_t *response) 107 | { 108 | uint8_t count_byte; 109 | uint8_t i; 110 | uint8_t ret_code; 111 | 112 | for (i = 0; i < size; i++) 113 | response[i] = 0; 114 | 115 | (void) swi_send_byte(SHA204_SWI_FLAG_TX); 116 | 117 | ret_code = swi_receive_bytes(size, response); 118 | if (ret_code == SWI_FUNCTION_RETCODE_SUCCESS || ret_code == SWI_FUNCTION_RETCODE_RX_FAIL) { 119 | count_byte = response[SHA204_BUFFER_POS_COUNT]; 120 | if ((count_byte < SHA204_RSP_SIZE_MIN) || (count_byte > size)) 121 | return SHA204_INVALID_SIZE; 122 | 123 | return SHA204_SUCCESS; 124 | } 125 | 126 | // Translate error so that the Communication layer 127 | // can distinguish between a real error or the 128 | // device being busy executing a command. 129 | if (ret_code == SWI_FUNCTION_RETCODE_TIMEOUT) 130 | return SHA204_RX_NO_RESPONSE; 131 | else 132 | return SHA204_RX_FAIL; 133 | } 134 | 135 | 136 | /** \brief This function generates a Wake-up pulse and delays. 137 | * 138 | * \return success 139 | */ 140 | uint8_t sha204p_wakeup(void) 141 | { 142 | swi_set_signal_pin(0); 143 | delay_10us(SHA204_WAKEUP_PULSE_WIDTH); 144 | swi_set_signal_pin(1); 145 | delay_ms(SHA204_WAKEUP_DELAY); 146 | return SHA204_SUCCESS; 147 | } 148 | 149 | 150 | /** \brief This function puts the device into idle state. 151 | * 152 | * \return status of the operation 153 | */ 154 | uint8_t sha204p_idle() 155 | { 156 | return swi_send_byte(SHA204_SWI_FLAG_IDLE); 157 | } 158 | 159 | 160 | /** \brief This function puts the device into low-power state. 161 | * 162 | * \return status of the operation 163 | */ 164 | uint8_t sha204p_sleep() { 165 | return swi_send_byte(SHA204_SWI_FLAG_SLEEP); 166 | } 167 | 168 | 169 | /** \brief This function is only a dummy since the 170 | * functionality does not exist for the SWI 171 | * version of the SHA204 device. 172 | * 173 | * \return success 174 | */ 175 | uint8_t sha204p_reset_io(void) 176 | { 177 | return SHA204_SUCCESS; 178 | } 179 | 180 | 181 | /** \brief This function re-synchronizes communication. 182 | * 183 | Re-synchronizing communication is done in a maximum of five 184 | steps listed below. This function implements the first three steps. 185 | Since steps 4 and 5 (sending a Wake-up token and reading the 186 | response) are the same for TWI and SWI, they are implemented 187 | in the communication layer (#sha204c_resync).\n 188 | If the chip is not busy when the system sends a transmit flag, 189 | the chip should respond within t_turnaround. If t_exec has not 190 | already passed, the chip may be busy and the system should poll or 191 | wait until the maximum tEXEC time has elapsed. If the chip still 192 | does not respond to a second transmit flag within t_turnaround, 193 | it may be out of synchronization. At this point the system may 194 | take the following steps to reestablish communication: 195 |
    196 |
  1. Wait t_timeout.
  2. 197 |
  3. Send the transmit flag.
  4. 198 |
  5. 199 | If the chip responds within t_turnaround, 200 | then the system may proceed with more commands. 201 |
  6. 202 |
  7. Send a Wake token, wait t_whi, and send the transmit flag.
  8. 203 |
  9. 204 | The chip should respond with a 0x11 return status within 205 | t_turnaround, after which the system may proceed with more commands. 206 |
  10. 207 |
208 | 209 | * \param[in] size size of rx buffer 210 | * \param[out] response pointer to response buffer 211 | * \return status of the operation 212 | */ 213 | uint8_t sha204p_resync(uint8_t size, uint8_t *response) 214 | { 215 | delay_ms(SHA204_SYNC_TIMEOUT); 216 | return sha204p_receive_response(size, response); 217 | } 218 | 219 | #endif 220 | 221 | /** @} */ 222 | -------------------------------------------------------------------------------- /src/common-atmel/avr_compatible.h: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief AVR USART Register Compatibility Definitions 3 | * \author Atmel Crypto Products 4 | * \date January 14, 2013 5 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 6 | * 7 | * \atsha204_library_license_start 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. The name of Atmel may not be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * 4. This software may only be redistributed and used in connection with an 23 | * Atmel integrated circuit. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 26 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 28 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 29 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | * POSSIBILITY OF SUCH DAMAGE. 36 | * 37 | * \atsha204_library_license_stop 38 | */ 39 | 40 | #ifndef AVR_COMPATIBLE_H 41 | # define AVR_COMPATIBLE_H 42 | 43 | 44 | /** \defgroup atsha204_avr_compatible Module 15: AVR UART Definitions 45 | 46 | * This module contains mappings of UART port definitions for 47 | * the AT90USB1287 micro-controller. 48 | */ 49 | 50 | // port mappings for AT90USB1287 that has only one UART 51 | 52 | // definitions for UART control and status registers 53 | #define UCSRA UCSR1A //!< UART control and status register A 54 | #define UCSRB UCSR1B //!< UART control and status register B 55 | #define UCSRC UCSR1C //!< UART control and status register C 56 | 57 | // definition for UART data register 58 | #define UDR UDR1 //!< UART data register 59 | 60 | // definitions for UART baud rate registers 61 | #define UBRRL UBRR1L //!< UART baud rate register, low byte 62 | #define UBRRH UBRR1H //!< UART baud rate register, high byte 63 | 64 | // definitions for bits of UART control and status register A 65 | #define RXC RXC1 //!< UART receive-complete (bit 7, register A) 66 | #define TXC TXC1 //!< UART transmit-complete (bit 6, register A) 67 | #define UDRE UDRE1 //!< UART data-register-empty (bit 5, register A) 68 | #define FE FE1 //!< UART frame-error (bit 4, register A) 69 | #define DOR DOR1 //!< UART data-overrun (bit 3, register A) 70 | #define UPE UPE1 //!< UART parity-error (bit 2, register A) 71 | #define U2X U2X1 //!< UART double-speed (bit 1, register A) 72 | #define MPCM MPCM1 //!< UART multi-processor communication (bit 0, register A) 73 | 74 | // definitions for bits of UART control and status register B 75 | #define RXCIE RXCIE1 //!< UART rx complete interrupt enable (bit 7, register B) 76 | #define TXCIE TXCIE1 //!< UART tx complete interrupt enable (bit 6, register B) 77 | #define UDRIE UDRIE1 //!< UART data register empty interrupt enable (bit 5, register B) 78 | #define RXEN RXEN1 //!< UART enable-receiver (bit 4, register B) 79 | #define TXEN TXEN1 //!< UART enable-transmitter (bit 3, register B) 80 | #define UCSZ_2 UCSZ12 //!< UART msb of number of data bits (bit 2, register B) 81 | #define RXB8 RXB81 //!< UART receive ninth data bit (bit 1, register B) 82 | #define TXB8 TXB81 //!< UART send ninth data bit (bit 0, register B) 83 | 84 | // The ATSHA204 interface module does not use UART control and status register C. 85 | 86 | /** @} */ 87 | 88 | #endif 89 | 90 | -------------------------------------------------------------------------------- /src/common-atmel/bitbang_config.h: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Definitions for Hardware Dependent Part of ATSHA204 Physical Layer 3 | * Using GPIO for Communication 4 | * \author Atmel Crypto Products 5 | * \date January 14, 2013 6 | * 7 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 8 | * 9 | * \atsha204_library_license_start 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 17 | * 2. Redistributions in binary form must reproduce the above copyright notice, 18 | * this list of conditions and the following disclaimer in the documentation 19 | * and/or other materials provided with the distribution. 20 | * 21 | * 3. The name of Atmel may not be used to endorse or promote products derived 22 | * from this software without specific prior written permission. 23 | * 24 | * 4. This software may only be redistributed and used in connection with an 25 | * Atmel integrated circuit. 26 | * 27 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 28 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 29 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 30 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 31 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 35 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 36 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | * POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | * \atsha204_library_license_stop 40 | */ 41 | #ifndef BITBANG_CONFIG_H 42 | # define BITBANG_CONFIG_H 43 | 44 | #include // GPIO definitions 45 | #include // interrupt definitions 46 | 47 | 48 | /** \defgroup atsha204_swi_gpio_config Module 17: SWI Configuration - GPIO 49 | * 50 | * Two definition blocks are supplied: 51 | * - port definitions for various Atmel evaluation kits 52 | * - loop definitions that result in correct pulse widths for an AVR CPU 53 | * running at 16 MHz 54 | */ 55 | 56 | #define swi_enable_interrupts sei //!< enable interrupts 57 | #define swi_disable_interrupts cli //!< disable interrupts 58 | 59 | //#define AT88CK_DEBUG 60 | // 61 | // first socket 62 | #ifdef AT88CK109STK3 // Javan daughter board 63 | # define SIG2_BIT (7) //!< bit position of port register for second device 64 | # define CLIENT_ID (0) //!< identifier for client 65 | # define PORT_DDR (DDRB) //!< direction register for device id 0 66 | # define PORT_OUT (PORTB) //!< output port register for device id 0 67 | # define PORT_IN (PINB) //!< input port register for device id 0 68 | #elif defined(AT88CK101STK3) // Javan Jr. daughter board, 3-pin device 69 | # define SIG2_BIT (7) //!< bit position of port register for second device 70 | # define CLIENT_ID (0) //!< identifier for client 71 | # define PORT_DDR (DDRB) //!< direction register for device id 0 72 | # define PORT_OUT (PORTB) //!< output port register for device id 0 73 | # define PORT_IN (PINB) //!< input port register for device id 0 74 | #elif defined(AT88CK101STK8) // Javan Jr. daughter board, 8-pin device 75 | # define SIG2_BIT (2) //!< bit position of port register for second device 76 | # define CLIENT_ID (0) //!< identifier for client 77 | # define PORT_DDR (DDRB) //!< direction register for device id 0 78 | # define PORT_OUT (PORTB) //!< output port register for device id 0 79 | # define PORT_IN (PINB) //!< input port register for device id 0 80 | #elif defined(AT88CK454) || defined(RHINO_RED) // Rhino Black or Red 81 | # define SIG2_BIT (2) //!< bit position of port register for second device 82 | # define CLIENT_ID (0) //!< identifier for client 83 | # define PORT_DDR (DDRD) //!< direction register for device id 0 84 | # define PORT_OUT (PORTD) //!< output port register for device id 0 85 | # define PORT_IN (PIND) //!< input port register for device id 0 86 | #elif defined(AT88CK101STK3_TWO) // two Javan Jr. daughter boards 87 | # define SIG2_BIT (6) //!< bit position of port register for second device 88 | # define CLIENT_ID (0) //!< identifier for client 89 | # define PORT_DDR (DDRB) //!< direction register for device id 0 90 | # define PORT_OUT (PORTB) //!< output port register for device id 0 91 | # define PORT_IN (PINB) //!< input port register for device id 0 92 | #elif defined(AT88CK_DEBUG) 93 | # define SIG2_BIT (1) //!< bit position of port register for second device 94 | # define CLIENT_ID (0) //!< identifier for client 95 | # define PORT_DDR (DDRD) //!< direction register for device id 0 96 | # define PORT_OUT (PORTD) //!< output port register for device id 0 97 | # define PORT_IN (PIND) //!< input port register for device id 0 98 | #else 99 | # define SIG2_BIT (2) //!< bit position of port register for second device 100 | # define CLIENT_ID (0) //!< identifier for client 101 | # define PORT_DDR (DDRD) //!< direction register for device id 0 102 | # define PORT_OUT (PORTD) //!< output port register for device id 0 103 | # define PORT_IN (PIND) //!< input port register for device id 0 104 | #endif 105 | 106 | // second socket 107 | #ifdef AT88CK101STK3_TWO 108 | # define SIG1_BIT (7) //!< bit position of port register for first device 109 | #else 110 | # define SIG1_BIT (6) //!< bit position of port register for first device 111 | #endif 112 | #define HOST_ID (1) //!< identifier for host 113 | 114 | /** \brief Debug pin that indicates pulse edge detection. This is only enabled if compilation switch DEBUG_BITBANG is used. 115 | To debug timing, disable host power (H1 and H2 on AT88CK109BK8 daughter board) and connect logic analyzer 116 | or storage oscilloscope to the H2 pin that is closer to the H1 header. 117 | The logic analyzer from Saleae (www.saleae.com) comes with a protocol analyzer for this Atmel SWI protocol. 118 | */ 119 | //#define DEBUG_BITBANG 120 | #ifdef DEBUG_BITBANG 121 | # ifdef AT88CK101STK3_TWO 122 | # define DEBUG_PORT_DDR (DDRD) //!< direction register for debug pin 123 | # define DEBUG_PORT_OUT (PORTD) //!< output port register for debug pin 124 | # define DEBUG_BIT (0) //!< what pin to use for debugging 125 | # else 126 | # define DEBUG_PORT_DDR (DDRB) //!< direction register for debug pin 127 | # define DEBUG_PORT_OUT (PORTB) //!< output port register for debug pin 128 | # define DEBUG_BIT (6) //!< what pin to use for debugging 129 | # endif 130 | # define DEBUG_LOW DEBUG_PORT_OUT &= ~_BV(DEBUG_BIT) //!< set debug pin low 131 | # define DEBUG_HIGH DEBUG_PORT_OUT |= _BV(DEBUG_BIT) //!< set debug pin high 132 | #else 133 | # define DEBUG_LOW 134 | # define DEBUG_HIGH 135 | #endif 136 | 137 | /** \name Macros for Bit-Banged SWI Timing 138 | 139 | Times to drive bits at 230.4 kbps. 140 | For a CPU clock of 16 MHz on an 8-bit AVR, the delay loops used 141 | take about 580 ns per iteration. Another 800 ns are needed to 142 | access the port. 143 | @{ */ 144 | 145 | //! delay macro for width of one pulse (start pulse or zero pulse, in ns) 146 | // should be 4.34 us, is 4.33 us 147 | #define BIT_DELAY_1 {volatile uint8_t delay = 6; while (delay--);} 148 | 149 | //! time to keep pin high for five pulses plus stop bit (used to bit-bang CryptoAuth 'zero' bit, in ns) 150 | // should be 26.04 us, is 26.38 us 151 | #define BIT_DELAY_5 {volatile uint8_t delay = 44; while (delay--);} 152 | 153 | //! time to keep pin high for seven bits plus stop bit (used to bit-bang CryptoAuth 'one' bit) 154 | // should be 34.72 us, is 35.00 us 155 | #define BIT_DELAY_7 {volatile uint8_t delay = 59; while (delay--);} 156 | 157 | //! turn around time when switching from receive to transmit 158 | // should be 15 us, is 15 us 159 | #define RX_TX_DELAY {volatile uint8_t delay = 25; while (delay--);} 160 | 161 | // One loop iteration for edge detection takes about 0.6 us on this hardware. 162 | // Lets set the timeout value for start pulse detection to the uint8_t maximum. 163 | //! This value is decremented while waiting for the falling edge of a start pulse. 164 | #define START_PULSE_TIME_OUT (255) 165 | 166 | // We measured a loop count of 8 for the start pulse. That means it takes about 167 | // 0.6 us per loop iteration. Maximum time between rising edge of start pulse 168 | // and falling edge of zero pulse is 8.6 us. Therefore, a value of 26 (around 15 us) 169 | // gives ample time to detect a zero pulse and also leaves enough time to detect 170 | // the following start pulse. 171 | // The values above were established using the WinAVR 2010 compiler. 172 | // The code runs faster when compiled with the compiler version of Atmel Studio 6. 173 | // In this case a timeout value of 26 leads to a timeout of 10 us which is still 174 | // greater than 8.6 us. 175 | //! This value is decremented while waiting for the falling edge of a zero pulse. 176 | #define ZERO_PULSE_TIME_OUT (26) 177 | 178 | /** @} */ 179 | 180 | #endif 181 | -------------------------------------------------------------------------------- /src/common-atmel/bitbang_phys.c: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Functions of Hardware Dependent Part of ATSHA204 Physical Layer 3 | * Using GPIO For Communication 4 | * \author Atmel Crypto Products 5 | * \date January 14, 2013 6 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 7 | * 8 | * \atsha204_library_license_start 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 20 | * 3. The name of Atmel may not be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * 4. This software may only be redistributed and used in connection with an 24 | * Atmel integrated circuit. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 27 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 28 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 29 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 30 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 34 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 35 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 | * POSSIBILITY OF SUCH DAMAGE. 37 | * 38 | * \atsha204_library_license_stop 39 | */ 40 | 41 | #include // data type definitions 42 | 43 | #include "swi_phys.h" // hardware dependent declarations for SWI 44 | #include "bitbang_config.h" // non-portable macro definitions 45 | 46 | 47 | //! declaration of the variable indicating which pin the selected device is connected to 48 | static uint8_t device_pin; 49 | 50 | /** \defgroup atsha204_swi_gpio Module 16: GPIO Interface 51 | * 52 | * This module implements functions defined in swi_phys.h. 53 | * This implementation targets an eight-bit AVR CPU. 54 | */ 55 | 56 | 57 | /** \brief This GPIO function sets the signal pin. 58 | * Communication functions will use this signal pin. 59 | * 60 | * \param[in] id client if zero, otherwise host 61 | * \return status of the operation 62 | **************************************************************** 63 | */ 64 | void swi_set_device_id(uint8_t id) { 65 | device_pin = (id == 0 ? _BV(SIG2_BIT) : _BV(SIG1_BIT)); 66 | } 67 | 68 | 69 | /** \brief This GPIO function sets the bit position of the 70 | * signal pin to its default. 71 | */ 72 | void swi_enable(void) 73 | { 74 | // Enable pull-up for first device. 75 | device_pin = _BV(SIG1_BIT); 76 | PORT_DDR &= ~device_pin; 77 | PORT_OUT |= device_pin; 78 | 79 | // Enable pull-up for second device. 80 | device_pin = _BV(SIG2_BIT); 81 | PORT_DDR &= ~device_pin; 82 | PORT_OUT |= device_pin; 83 | 84 | #ifdef DEBUG_BITBANG 85 | DEBUG_PORT_DDR |= _BV(DEBUG_BIT); 86 | DEBUG_LOW; 87 | #endif 88 | } 89 | 90 | 91 | /** \brief This GPIO function sets the signal pin low or high. 92 | * \param[in] is_high 0: set signal low, otherwise high. 93 | */ 94 | void swi_set_signal_pin(uint8_t is_high) 95 | { 96 | PORT_DDR |= device_pin; 97 | 98 | if (is_high) 99 | PORT_OUT |= device_pin; 100 | else 101 | PORT_OUT &= ~device_pin; 102 | } 103 | 104 | 105 | /** \brief This GPIO function sends bytes to an SWI device. 106 | * \param[in] count number of bytes to send 107 | * \param[in] buffer pointer to tx buffer 108 | * \return status of the operation 109 | */ 110 | uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer) 111 | { 112 | uint8_t i, bit_mask; 113 | 114 | // Disable interrupts while sending. 115 | swi_disable_interrupts(); 116 | 117 | // Set signal pin as output. 118 | PORT_OUT |= device_pin; 119 | PORT_DDR |= device_pin; 120 | 121 | // Wait turn around time. 122 | RX_TX_DELAY; 123 | 124 | for (i = 0; i < count; i++) { 125 | for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) { 126 | if (bit_mask & buffer[i]) { 127 | PORT_OUT &= ~device_pin; 128 | BIT_DELAY_1; 129 | PORT_OUT |= device_pin; 130 | BIT_DELAY_7; 131 | } 132 | else { 133 | // Send a zero bit. 134 | PORT_OUT &= ~device_pin; 135 | BIT_DELAY_1; 136 | PORT_OUT |= device_pin; 137 | BIT_DELAY_1; 138 | PORT_OUT &= ~device_pin; 139 | BIT_DELAY_1; 140 | PORT_OUT |= device_pin; 141 | BIT_DELAY_5; 142 | } 143 | } 144 | } 145 | swi_enable_interrupts(); 146 | return SWI_FUNCTION_RETCODE_SUCCESS; 147 | } 148 | 149 | 150 | /** \brief This GPIO function sends one byte to an SWI device. 151 | * \param[in] value byte to send 152 | * \return status of the operation 153 | */ 154 | uint8_t swi_send_byte(uint8_t value) 155 | { 156 | return swi_send_bytes(1, &value); 157 | } 158 | 159 | 160 | /** \brief This GPIO function receives bytes from an SWI device. 161 | * \param[in] count number of bytes to receive 162 | * \param[out] buffer pointer to rx buffer 163 | * \return status of the operation 164 | */ 165 | uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer) { 166 | uint8_t status = SWI_FUNCTION_RETCODE_SUCCESS; 167 | uint8_t i; 168 | uint8_t bit_mask; 169 | uint8_t pulse_count; 170 | uint8_t timeout_count; 171 | 172 | // Disable interrupts while receiving. 173 | swi_disable_interrupts(); 174 | 175 | // Configure signal pin as input. 176 | PORT_DDR &= ~device_pin; 177 | 178 | #ifndef DEBUG_BITBANG 179 | 180 | // Receive bits and store in buffer. 181 | for (i = 0; i < count; i++) { 182 | for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) { 183 | pulse_count = 0; 184 | 185 | // Make sure that the variable below is big enough. 186 | // Change it to uint16_t if 255 is too small, but be aware that 187 | // the loop resolution decreases on an 8-bit controller in that case. 188 | timeout_count = START_PULSE_TIME_OUT; 189 | 190 | // Detect start bit. 191 | while (--timeout_count > 0) { 192 | // Wait for falling edge. 193 | if ((PORT_IN & device_pin) == 0) 194 | break; 195 | } 196 | 197 | if (timeout_count == 0) { 198 | status = SWI_FUNCTION_RETCODE_TIMEOUT; 199 | break; 200 | } 201 | 202 | do { 203 | // Wait for rising edge. 204 | if ((PORT_IN & device_pin) != 0) { 205 | // For an Atmel microcontroller this might be faster than "pulse_count++". 206 | pulse_count = 1; 207 | break; 208 | } 209 | } while (--timeout_count > 0); 210 | 211 | if (pulse_count == 0) { 212 | status = SWI_FUNCTION_RETCODE_TIMEOUT; 213 | break; 214 | } 215 | 216 | // Trying to measure the time of start bit and calculating the timeout 217 | // for zero bit detection is not accurate enough for an 8 MHz 8-bit CPU. 218 | // So let's just wait the maximum time for the falling edge of a zero bit 219 | // to arrive after we have detected the rising edge of the start bit. 220 | timeout_count = ZERO_PULSE_TIME_OUT; 221 | 222 | // Detect possible edge indicating zero bit. 223 | do { 224 | if ((PORT_IN & device_pin) == 0) { 225 | // For an Atmel microcontroller this might be faster than "pulse_count++". 226 | pulse_count = 2; 227 | break; 228 | } 229 | } while (--timeout_count > 0); 230 | 231 | // Wait for rising edge of zero pulse before returning. Otherwise we might interpret 232 | // its rising edge as the next start pulse. 233 | if (pulse_count == 2) { 234 | timeout_count = ZERO_PULSE_TIME_OUT; 235 | do { 236 | if ((PORT_IN & device_pin) != 0) 237 | break; 238 | } while (timeout_count-- > 0); 239 | 240 | // This check is taken out, because it makes the bit 241 | // sampling loop too slow on an AT90USB1287 running at 16 MHz. 242 | // if (timeout_count == 0) { 243 | // status = SHA204_TIMEOUT; 244 | // break; 245 | // } 246 | } 247 | 248 | // Update byte at current buffer index. 249 | else 250 | // received "one" bit 251 | buffer[i] |= bit_mask; 252 | } 253 | 254 | if (status != SWI_FUNCTION_RETCODE_SUCCESS) 255 | break; 256 | } 257 | swi_enable_interrupts(); 258 | 259 | if (status == SWI_FUNCTION_RETCODE_TIMEOUT) { 260 | if (i > 0) 261 | // Indicate that we timed out after having received at least one byte. 262 | status = SWI_FUNCTION_RETCODE_RX_FAIL; 263 | } 264 | return status; 265 | 266 | /***********************************************************************************/ 267 | /***** debug version that toggles a pin when an edge has been detected ************/ 268 | /***********************************************************************************/ 269 | #else 270 | DEBUG_LOW; 271 | 272 | #ifdef DEBUG_BITBANG_MEASURE 273 | // Use this variable to measure the number of loop counts per pulse 274 | // to establish a value for the zero bit detection timeout. 275 | // For the AT88CK109STK3 (AT90USB1287 at 16 MHz) it is 8 for the start pulse. 276 | volatile uint8_t start_pulse_width = 0; 277 | #endif 278 | 279 | for (i = 0; i < count; i++) { 280 | buffer[i] = 0; 281 | for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) { 282 | pulse_count = 0; 283 | 284 | // Make sure that the variable below is big enough. 285 | // Change it to uint16_t if 255 is too small, but be aware that 286 | // the loop resolution decreases on an 8-bit controller in that case. 287 | timeout_count = START_PULSE_TIME_OUT; 288 | 289 | #ifdef DEBUG_BITBANG_MEASURE 290 | // Use this variable to measure the number of loop counts per pulse 291 | // to establish a value for the zero bit detection timeout. 292 | // For the AT88CK109STK3 (AT90USB1287 at 16 MHz) it was 8 for the start pulse. 293 | start_pulse_width = 0; 294 | #endif 295 | // Detect start bit. 296 | DEBUG_HIGH; 297 | while (--timeout_count > 0) { 298 | // Wait for falling edge. 299 | if ((PORT_IN & device_pin) == 0) 300 | break; 301 | } 302 | DEBUG_LOW; 303 | 304 | if (timeout_count == 0) { 305 | // Allows to put a break point. 306 | //asm volatile("nop"::); 307 | status = SWI_FUNCTION_RETCODE_TIMEOUT; 308 | break; 309 | } 310 | DEBUG_HIGH; 311 | 312 | do { 313 | // Wait for rising edge. 314 | if ((PORT_IN & device_pin) != 0) { 315 | // For an Atmel microcontroller this might be faster than "edgeCount++". 316 | pulse_count = 1; 317 | break; 318 | } 319 | #ifdef DEBUG_BITBANG_MEASURE 320 | start_pulse_width++; 321 | #endif 322 | } while (--timeout_count > 0); 323 | DEBUG_LOW; 324 | 325 | #ifdef DEBUG_BITBANG_MEASURE 326 | if (pulse_count == 0 || start_pulse_width == 0) 327 | #else 328 | if (pulse_count == 0) 329 | #endif 330 | { 331 | // Allows to put a break point. 332 | //asm volatile("nop"::); 333 | status = SWI_FUNCTION_RETCODE_TIMEOUT; 334 | break; 335 | } 336 | 337 | // Trying to measure the time of start bit and calculating the timeout 338 | // for zero bit detection is not accurate enough for an 8 MHz 8-bit CPU. 339 | // So let's just wait the maximum time for the falling edge of a zero bit 340 | // to arrive after we have detected the rising edge of the start bit. 341 | timeout_count = ZERO_PULSE_TIME_OUT; 342 | 343 | // Detect possible edge indicating zero bit. 344 | DEBUG_HIGH; 345 | do { 346 | if ((PORT_IN & device_pin) == 0) { 347 | // For an Atmel microcontroller this might be faster than "edgeCount++". 348 | pulse_count = 2; 349 | break; 350 | } 351 | } while (--timeout_count > 0); 352 | DEBUG_LOW; 353 | 354 | // Wait for rising edge of zero pulse before returning. Otherwise we might interpret 355 | // its rising edge as the next start pulse. 356 | if (pulse_count == 2) { 357 | DEBUG_HIGH; 358 | do { 359 | if ((PORT_IN & device_pin) != 0) 360 | break; 361 | } while (timeout_count-- > 0); 362 | } 363 | 364 | // Update byte at current buffer index. 365 | else 366 | // received "one" bit 367 | buffer[i] |= bit_mask; 368 | 369 | DEBUG_LOW; 370 | } 371 | } 372 | swi_enable_interrupts(); 373 | 374 | return status; 375 | 376 | #endif // DEBUG_BITBANG 377 | } 378 | 379 | /** @} */ 380 | -------------------------------------------------------------------------------- /src/common-atmel/i2c_phys.c: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Functions of Hardware Dependent Part of ATSHA204 Physical Layer 3 | * Using I2C For Communication 4 | * \author Atmel Crypto Products 5 | * \date January 11, 2013 6 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 7 | * 8 | * \atsha204_library_license_start 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 20 | * 3. The name of Atmel may not be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * 4. This software may only be redistributed and used in connection with an 24 | * Atmel integrated circuit. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 27 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 28 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 29 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 30 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 34 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 35 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 | * POSSIBILITY OF SUCH DAMAGE. 37 | * 38 | * \atsha204_library_license_stop 39 | */ 40 | 41 | 42 | #include // GPIO definitions 43 | #include // I2C definitions 44 | #include // definitions for power saving register 45 | #include "i2c_phys.h" // definitions and declarations for the hardware dependent I2C module 46 | #include "Arduino.h" 47 | 48 | /** \brief This function initializes and enables the I2C peripheral. 49 | * */ 50 | void i2c_enable(void) 51 | { 52 | #ifdef HAVE_PRR 53 | PRR &= ~_BV(PRTWI); // Disable power saving. 54 | #endif 55 | 56 | #ifdef I2C_PULLUP 57 | digitalWrite(SDA, 1); 58 | digitalWrite(SCL, 1); 59 | #endif 60 | 61 | TWBR = ((uint8_t) (((double) F_CPU / I2C_CLOCK - 16.0) / 2.0 + 0.5)); // Set the baud rate 62 | } 63 | 64 | 65 | /** \brief This function disables the I2C peripheral. */ 66 | void i2c_disable(void) 67 | { 68 | TWCR = 0; // Disable TWI. 69 | #ifdef HAVE_PRR 70 | PRR |= _BV(PRTWI); // Enable power saving. 71 | #endif 72 | } 73 | 74 | 75 | /** \brief This function creates a Start condition (SDA low, then SCL low). 76 | * \return status of the operation 77 | * */ 78 | uint8_t i2c_send_start(void) 79 | { 80 | uint8_t timeout_counter = I2C_START_TIMEOUT; 81 | uint8_t i2c_status; 82 | 83 | TWCR = (_BV(TWEN) | _BV(TWSTA) | _BV(TWINT)); 84 | do { 85 | if (timeout_counter-- == 0) 86 | return I2C_FUNCTION_RETCODE_TIMEOUT; 87 | } while ((TWCR & (_BV(TWINT))) == 0); 88 | 89 | i2c_status = TW_STATUS; 90 | if ((i2c_status != TW_START) && (i2c_status != TW_REP_START)) 91 | return I2C_FUNCTION_RETCODE_COMM_FAIL; 92 | 93 | return I2C_FUNCTION_RETCODE_SUCCESS; 94 | } 95 | 96 | 97 | /** \brief This function creates a Stop condition (SCL high, then SDA high). 98 | * \return status of the operation 99 | * */ 100 | uint8_t i2c_send_stop(void) 101 | { 102 | uint8_t timeout_counter = I2C_STOP_TIMEOUT; 103 | 104 | TWCR = (_BV(TWEN) | _BV(TWSTO) | _BV(TWINT)); 105 | do { 106 | if (timeout_counter-- == 0) 107 | return I2C_FUNCTION_RETCODE_TIMEOUT; 108 | } while ((TWCR & _BV(TWSTO)) > 0); 109 | 110 | if (TW_STATUS == TW_BUS_ERROR) 111 | return I2C_FUNCTION_RETCODE_COMM_FAIL; 112 | 113 | return I2C_FUNCTION_RETCODE_SUCCESS; 114 | } 115 | 116 | 117 | /** \brief This function sends bytes to an I2C device. 118 | * \param[in] count number of bytes to send 119 | * \param[in] data pointer to tx buffer 120 | * \return status of the operation 121 | */ 122 | uint8_t i2c_send_bytes(uint8_t count, uint8_t *data) 123 | { 124 | uint8_t timeout_counter; 125 | uint8_t twi_status; 126 | uint8_t i; 127 | 128 | for (i = 0; i < count; i++) { 129 | TWDR = *data++; 130 | TWCR = _BV(TWEN) | _BV(TWINT); 131 | 132 | timeout_counter = I2C_BYTE_TIMEOUT; 133 | do { 134 | if (timeout_counter-- == 0) 135 | return I2C_FUNCTION_RETCODE_TIMEOUT; 136 | } while ((TWCR & (_BV(TWINT))) == 0); 137 | 138 | twi_status = TW_STATUS; 139 | if ((twi_status != TW_MT_SLA_ACK) 140 | && (twi_status != TW_MT_DATA_ACK) 141 | && (twi_status != TW_MR_SLA_ACK)) 142 | // Return error if byte got nacked. 143 | return I2C_FUNCTION_RETCODE_NACK; 144 | } 145 | 146 | return I2C_FUNCTION_RETCODE_SUCCESS; 147 | } 148 | 149 | 150 | /** \brief This function receives one byte from an I2C device. 151 | * 152 | * \param[out] data pointer to received byte 153 | * \return status of the operation 154 | */ 155 | uint8_t i2c_receive_byte(uint8_t *data) 156 | { 157 | uint8_t timeout_counter = I2C_BYTE_TIMEOUT; 158 | 159 | // Enable acknowledging data. 160 | TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA)); 161 | do { 162 | if (timeout_counter-- == 0) 163 | return I2C_FUNCTION_RETCODE_TIMEOUT; 164 | } while ((TWCR & (_BV(TWINT))) == 0); 165 | 166 | if (TW_STATUS != TW_MR_DATA_ACK) { 167 | // Do not override original error. 168 | (void) i2c_send_stop(); 169 | return I2C_FUNCTION_RETCODE_COMM_FAIL; 170 | } 171 | *data = TWDR; 172 | 173 | return I2C_FUNCTION_RETCODE_SUCCESS; 174 | } 175 | 176 | 177 | /** \brief This function receives bytes from an I2C device 178 | * and sends a Stop. 179 | * 180 | * \param[in] count number of bytes to receive 181 | * \param[out] data pointer to rx buffer 182 | * \return status of the operation 183 | */ 184 | uint8_t i2c_receive_bytes(uint8_t count, uint8_t *data) 185 | { 186 | uint8_t i; 187 | uint8_t timeout_counter; 188 | 189 | // Acknowledge all bytes except the last one. 190 | for (i = 0; i < count - 1; i++) { 191 | // Enable acknowledging data. 192 | TWCR = (_BV(TWEN) | _BV(TWINT) | _BV(TWEA)); 193 | timeout_counter = I2C_BYTE_TIMEOUT; 194 | do { 195 | if (timeout_counter-- == 0) 196 | return I2C_FUNCTION_RETCODE_TIMEOUT; 197 | } while ((TWCR & (_BV(TWINT))) == 0); 198 | 199 | if (TW_STATUS != TW_MR_DATA_ACK) { 200 | // Do not override original error. 201 | (void) i2c_send_stop(); 202 | return I2C_FUNCTION_RETCODE_COMM_FAIL; 203 | } 204 | *data++ = TWDR; 205 | } 206 | 207 | // Disable acknowledging data for the last byte. 208 | TWCR = (_BV(TWEN) | _BV(TWINT)); 209 | timeout_counter = I2C_BYTE_TIMEOUT; 210 | do { 211 | if (timeout_counter-- == 0) 212 | return I2C_FUNCTION_RETCODE_TIMEOUT; 213 | } while ((TWCR & (_BV(TWINT))) == 0); 214 | 215 | if (TW_STATUS != TW_MR_DATA_NACK) { 216 | // Do not override original error. 217 | (void) i2c_send_stop(); 218 | return I2C_FUNCTION_RETCODE_COMM_FAIL; 219 | } 220 | *data = TWDR; 221 | 222 | return i2c_send_stop(); 223 | } 224 | -------------------------------------------------------------------------------- /src/common-atmel/i2c_phys.h: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Definitions for Hardware Dependent Part of ATSHA204 Physical Layer 3 | * Using I2C for Communication 4 | * \author Atmel Crypto Products 5 | * \date January 14, 2013 6 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 7 | * 8 | * \atsha204_library_license_start 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions are met: 12 | * 13 | * 1. Redistributions of source code must retain the above copyright notice, 14 | * this list of conditions and the following disclaimer. 15 | * 16 | * 2. Redistributions in binary form must reproduce the above copyright notice, 17 | * this list of conditions and the following disclaimer in the documentation 18 | * and/or other materials provided with the distribution. 19 | * 20 | * 3. The name of Atmel may not be used to endorse or promote products derived 21 | * from this software without specific prior written permission. 22 | * 23 | * 4. This software may only be redistributed and used in connection with an 24 | * Atmel integrated circuit. 25 | * 26 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 27 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 28 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 29 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 30 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 34 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 35 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 | * POSSIBILITY OF SUCH DAMAGE. 37 | * 38 | * \atsha204_library_license_stop 39 | */ 40 | 41 | #ifndef I2C_PHYS_H_ 42 | # define I2C_PHYS_H_ 43 | 44 | #include // data type definitions 45 | 46 | /** \defgroup atsha204_i2c_hardware Module 18: I2C Interface 47 | * Definitions are supplied for various I2C configuration values 48 | * such as clock, timeouts, and error codes. 49 | */ 50 | 51 | //! I2C clock 52 | #define I2C_CLOCK (400000.0) 53 | 54 | //! Use pull-up resistors. 55 | #define I2C_PULLUP 56 | 57 | /** \brief number of polling iterations for TWINT bit in TWSR after 58 | * creating a Start condition in #i2c_send_start() 59 | * 60 | * Adjust this value considering how long it takes to check a status bit 61 | * in the TWI status register, decrement the timeout counter, 62 | * compare its value with 0, and branch. 63 | */ 64 | #define I2C_START_TIMEOUT ((uint8_t) 250) 65 | 66 | /** \brief number of polling iterations for TWINT bit in TWSR after sending 67 | * or receiving a byte. 68 | * 69 | * Adjust this value considering how long it takes to check a status bit 70 | * in the TWI status register, decrement the timeout counter, 71 | * compare its value with 0, branch, and to send or receive one byte. 72 | */ 73 | #define I2C_BYTE_TIMEOUT ((uint8_t) 200) 74 | 75 | /** \brief number of polling iterations for TWSTO bit in TWSR after 76 | * creating a Stop condition in #i2c_send_stop(). 77 | * 78 | * Adjust this value considering how long it takes to check a status bit 79 | * in the TWI control register, decrement the timeout counter, 80 | * compare its value with 0, and branch. 81 | */ 82 | #define I2C_STOP_TIMEOUT ((uint8_t) 250) 83 | 84 | 85 | // error codes for physical hardware dependent module 86 | // Codes in the range 0x00 to 0xF7 are shared between physical interfaces (SWI, TWI, SPI). 87 | // Codes in the range 0xF8 to 0xFF are special for the particular interface. 88 | #define I2C_FUNCTION_RETCODE_SUCCESS ((uint8_t) 0x00) //!< Communication with device succeeded. 89 | #define I2C_FUNCTION_RETCODE_COMM_FAIL ((uint8_t) 0xF0) //!< Communication with device failed. 90 | #define I2C_FUNCTION_RETCODE_TIMEOUT ((uint8_t) 0xF1) //!< Communication timed out. 91 | #define I2C_FUNCTION_RETCODE_NACK ((uint8_t) 0xF8) //!< TWI nack 92 | 93 | 94 | void i2c_enable(void); 95 | void i2c_disable(void); 96 | uint8_t i2c_send_start(void); 97 | uint8_t i2c_send_stop(void); 98 | uint8_t i2c_send_bytes(uint8_t count, uint8_t *data); 99 | uint8_t i2c_receive_byte(uint8_t *data); 100 | uint8_t i2c_receive_bytes(uint8_t count, uint8_t *data); 101 | 102 | 103 | /** @} */ 104 | 105 | #endif 106 | -------------------------------------------------------------------------------- /src/common-atmel/swi_phys.h: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Definitions and Prototypes for SWI Hardware Dependent Physical Layer of CryptoAuth Library 3 | * \author Atmel Crypto Products 4 | * \date January 11, 2013 5 | * \todo Move interface header files from "Hardware\AVR_AT" to "Hardware\Includes" 6 | * so that they can be shared by other hardware implementations. 7 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 8 | * 9 | * \atsha204_library_license_start 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 17 | * 2. Redistributions in binary form must reproduce the above copyright notice, 18 | * this list of conditions and the following disclaimer in the documentation 19 | * and/or other materials provided with the distribution. 20 | * 21 | * 3. The name of Atmel may not be used to endorse or promote products derived 22 | * from this software without specific prior written permission. 23 | * 24 | * 4. This software may only be redistributed and used in connection with an 25 | * Atmel integrated circuit. 26 | * 27 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 28 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 29 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 30 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 31 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 35 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 36 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | * POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | * \atsha204_library_license_stop 40 | */ 41 | #ifndef SWI_PHYS_H 42 | # define SWI_PHYS_H 43 | 44 | #include // data type definitions 45 | 46 | /** \ingroup sha204_swi 47 | * 48 | error codes for hardware dependent module 49 | Codes in the range 0x00 to 0xF7 are shared between physical interfaces (SWI, I2). 50 | Codes in the range 0xF8 to 0xFF are special for the particular interface. 51 | @{ */ 52 | 53 | #define SWI_FUNCTION_RETCODE_SUCCESS ((uint8_t) 0x00) //!< Communication with device succeeded. 54 | #define SWI_FUNCTION_RETCODE_TIMEOUT ((uint8_t) 0xF1) //!< Communication timed out. 55 | #define SWI_FUNCTION_RETCODE_RX_FAIL ((uint8_t) 0xF9) //!< Communication failed after at least one byte was received. 56 | 57 | /** @} */ 58 | 59 | // Function Prototypes 60 | void swi_enable(void); 61 | void swi_set_device_id(uint8_t id); 62 | void swi_set_signal_pin(uint8_t end); 63 | uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer); 64 | uint8_t swi_send_byte(uint8_t value); 65 | uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer); 66 | 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/common-atmel/timer_utilities.c: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Timer Utility Functions 3 | * \author Atmel Crypto Products 4 | * \date January 11, 2013 5 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 6 | * 7 | * \atsha204_library_license_start 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. The name of Atmel may not be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * 4. This software may only be redistributed and used in connection with an 23 | * Atmel integrated circuit. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 26 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 28 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 29 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | * POSSIBILITY OF SUCH DAMAGE. 36 | * 37 | * \atsha204_library_license_stop 38 | */ 39 | 40 | #include // data type definitions 41 | 42 | /** \defgroup timer_utilities Module 09: Timers 43 | * 44 | * This module implements timers used during communication. 45 | * They are implemented using loop counters. But if you have hardware 46 | * timers available, you can implement the functions using them. 47 | @{ */ 48 | 49 | // The values below are valid for an AVR 8-bit processor running at 16 MHz. 50 | // Code is compiled with optimization set to -O1. 51 | 52 | #if F_CPU == 16000000UL 53 | //! Fill the inner loop of delay_10us() with these CPU instructions to achieve 10 us per iteration. 54 | # define TIME_UTILS_US_CALIBRATION //__asm__ volatile ("\n\tnop\n\tnop\n\tnop\n") 55 | 56 | /** Decrement the inner loop of delay_10us() this many times to achieve 10 us per 57 | * iteration of the outer loop. 58 | */ 59 | # define TIME_UTILS_LOOP_COUNT ((uint8_t) 14) 60 | 61 | //! The delay_ms function calls delay_10us with this parameter. 62 | # define TIME_UTILS_MS_CALIBRATION ((uint8_t) 104) 63 | 64 | #elif F_CPU == 8000000UL 65 | //! Fill the inner loop of delay_10us() with these CPU instructions to achieve 10 us per iteration. 66 | # define TIME_UTILS_US_CALIBRATION __asm__ volatile ("\n\tnop\n\tnop\n\tnop\n\tnop\n") 67 | 68 | /** \brief Decrement the inner loop of delay_10us() this many times to achieve 10 us per 69 | * iteration of the outer loop. 70 | */ 71 | # define TIME_UTILS_LOOP_COUNT ((uint8_t) 0) 72 | 73 | //! The delay_ms function calls delay_10us with this parameter. 74 | # define TIME_UTILS_MS_CALIBRATION ((uint8_t) 100) 75 | 76 | #elif F_CPU == 2000000UL 77 | //! Fill the inner loop of delay_10us() with these CPU instructions to achieve 10 us per iteration. 78 | # define TIME_UTILS_US_CALIBRATION __asm__ volatile ("\n\tnop\n") 79 | 80 | /** \brief Decrement the inner loop of delay_10us() this many times to achieve 10 us per 81 | * iteration of the outer loop. 82 | */ 83 | # define TIME_UTILS_LOOP_COUNT ((uint8_t) 1) 84 | 85 | //! The delay_ms function calls delay_10us with this parameter. 86 | # define TIME_UTILS_MS_CALIBRATION ((uint8_t) 91) 87 | 88 | #elif CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC32MHZ 89 | // Xmega 90 | //! Fill the inner loop of delay_10us() with these CPU instructions to achieve 10 us per iteration. 91 | # define TIME_UTILS_US_CALIBRATION //__asm__ volatile ("\n\tnop\n\tnop\n\tnop\n") 92 | 93 | /** \brief Decrement the inner loop of delay_10us() this many times to achieve 10 us per 94 | * iteration of the outer loop. 95 | */ 96 | # define TIME_UTILS_LOOP_COUNT ((uint8_t) 28) 97 | 98 | //! The delay_ms function calls delay_10us with this parameter. 99 | # define TIME_UTILS_MS_CALIBRATION ((uint8_t) 104) 100 | 101 | #else 102 | # error Time macros are not defined. 103 | #endif 104 | 105 | 106 | /** \brief This function delays for a number of tens of microseconds. 107 | * 108 | * This function will not time correctly, if one loop iteration 109 | * plus the time it takes to enter this function takes more than 10 us. 110 | * \param[in] delay number of 0.01 milliseconds to delay 111 | */ 112 | void delay_10us(uint8_t delay) 113 | { 114 | volatile uint8_t delay_10us; 115 | 116 | for (; delay > 0; delay--) { 117 | for (delay_10us = TIME_UTILS_LOOP_COUNT; delay_10us > 0; delay_10us--); 118 | TIME_UTILS_US_CALIBRATION; 119 | } 120 | } 121 | 122 | 123 | /** \brief This function delays for a number of milliseconds. 124 | * 125 | * You can override this function if you like to do 126 | * something else in your system while delaying. 127 | * \param[in] delay number of milliseconds to delay 128 | */ 129 | void delay_ms(uint8_t delay) 130 | { 131 | uint8_t i; 132 | for (i = delay; i > 0; i--) 133 | delay_10us(TIME_UTILS_MS_CALIBRATION); 134 | } 135 | 136 | /** @} */ 137 | -------------------------------------------------------------------------------- /src/common-atmel/timer_utilities.h: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Timer Utility Declarations 3 | * \author Atmel Crypto Products 4 | * \date January 11, 2013 5 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 6 | * 7 | * \atsha204_library_license_start 8 | * 9 | * Redistribution and use in source and binary forms, with or without 10 | * modification, are permitted provided that the following conditions are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright notice, 13 | * this list of conditions and the following disclaimer. 14 | * 15 | * 2. Redistributions in binary form must reproduce the above copyright notice, 16 | * this list of conditions and the following disclaimer in the documentation 17 | * and/or other materials provided with the distribution. 18 | * 19 | * 3. The name of Atmel may not be used to endorse or promote products derived 20 | * from this software without specific prior written permission. 21 | * 22 | * 4. This software may only be redistributed and used in connection with an 23 | * Atmel integrated circuit. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 26 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 28 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 29 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 34 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 | * POSSIBILITY OF SUCH DAMAGE. 36 | * 37 | * \atsha204_library_license_stop 38 | */ 39 | 40 | #ifndef TIMER_UTILITIES_H 41 | #define TIMER_UTILITIES_H 42 | 43 | #include // data type definitions 44 | 45 | void delay_10us(uint8_t delay); 46 | void delay_ms(uint8_t delay); 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /src/common-atmel/uart_config.h: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Definitions for Hardware Dependent Part of the Physical Layer 3 | * of the ATSHA204 Library Using a UART 4 | * \author Atmel Crypto Products 5 | * \date January 15, 2013 6 | * 7 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 8 | * 9 | * \atsha204_library_license_start 10 | * 11 | * Redistribution and use in source and binary forms, with or without 12 | * modification, are permitted provided that the following conditions are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright notice, 15 | * this list of conditions and the following disclaimer. 16 | * 17 | * 2. Redistributions in binary form must reproduce the above copyright notice, 18 | * this list of conditions and the following disclaimer in the documentation 19 | * and/or other materials provided with the distribution. 20 | * 21 | * 3. The name of Atmel may not be used to endorse or promote products derived 22 | * from this software without specific prior written permission. 23 | * 24 | * 4. This software may only be redistributed and used in connection with an 25 | * Atmel integrated circuit. 26 | * 27 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 28 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 29 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 30 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 31 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 35 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 36 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 | * POSSIBILITY OF SUCH DAMAGE. 38 | * 39 | * \atsha204_library_license_stop 40 | */ 41 | #ifndef UART_CONFIG_H 42 | # define UART_CONFIG_H 43 | 44 | #include // GPIO definitions 45 | 46 | 47 | /** \defgroup atsha204_swi_uart_config Module 14: SWI Configuration - UART 48 | * 49 | * This module contains hardware configuration values for the UART 50 | * implementation of the single-wire interface. It uses macro definitions 51 | * from avr/io.h for an AT90USB1287 micro-controller. 52 | */ 53 | 54 | 55 | //! baud rate for SHA204 device in single-wire mode 56 | #define BAUD_RATE (230400UL) 57 | 58 | //! time in us it takes for decrementing a uint8_t and branching 59 | #define TIME_PER_LOOP_ITERATION (0.8) 60 | 61 | /** \brief number of polling iterations over UART register before timing out 62 | * 63 | * The polling iteration takes about 0.8 us. 64 | * For tx, we would need to wait bit time = 39 us. 65 | * For rx, we need at least wait for 66 | * tx / rx turn-around time + bit time = 95 us + 39 us = 134 us. 67 | * Let's make the timeout larger to be safe. 68 | */ 69 | #define BIT_TIMEOUT ((uint8_t) (250.0 / TIME_PER_LOOP_ITERATION)) 70 | 71 | //! Delay for this many loop iterations before sending. 72 | #define RX_TX_DELAY ((uint8_t) (15.0 / TIME_PER_LOOP_ITERATION)) 73 | 74 | //! direction register when using UART pin for Wake-up 75 | #define UART_GPIO_DDR DDRD 76 | 77 | //! output register when using UART pin for Wake-up 78 | #define UART_GPIO_OUT PORTD 79 | 80 | //! bit position when using UART rx pin for Wake-up 81 | #define UART_GPIO_PIN_RX _BV(PD2) 82 | 83 | //! bit position when using UART tx pin for Wake-up 84 | #define UART_GPIO_PIN_TX _BV(PD3) 85 | 86 | #ifdef DEBUG_UART 87 | # define DEBUG_PORT_DDR (DDRB) //!< direction register for debug pin 88 | # define DEBUG_PORT_OUT (PORTB) //!< output port register for debug pin 89 | # define DEBUG_BIT (PB6) //!< pin used for debugging 90 | # define DEBUG_LOW DEBUG_PORT_OUT &= ~_BV(DEBUG_BIT) //!< set debug pin low 91 | # define DEBUG_HIGH DEBUG_PORT_OUT |= _BV(DEBUG_BIT) //!< set debug pin high 92 | #else 93 | # define DEBUG_LOW //!< undefine debugging macro 94 | # define DEBUG_HIGH //!< undefine debugging macro 95 | 96 | #endif 97 | 98 | 99 | /** @} */ 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /src/common-atmel/uart_phys.c: -------------------------------------------------------------------------------- 1 | /** \file 2 | * \brief Physical Layer Functions of ATSHA204 Library When Using UART 3 | * 4 | * This module supports most of ATmega and all ATXmega AVR microcontrollers. 5 | * http://www.atmel.com/dyn/products/param_table.asp?family_id=607&OrderBy=part_no&Direction=ASC 6 | * 7 | * \author Atmel Crypto Products 8 | * \date January 14, 2013 9 | * \copyright Copyright (c) 2013 Atmel Corporation. All rights reserved. 10 | * 11 | * \atsha204_library_license_start 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions are met: 15 | * 16 | * 1. Redistributions of source code must retain the above copyright notice, 17 | * this list of conditions and the following disclaimer. 18 | * 19 | * 2. Redistributions in binary form must reproduce the above copyright notice, 20 | * this list of conditions and the following disclaimer in the documentation 21 | * and/or other materials provided with the distribution. 22 | * 23 | * 3. The name of Atmel may not be used to endorse or promote products derived 24 | * from this software without specific prior written permission. 25 | * 26 | * 4. This software may only be redistributed and used in connection with an 27 | * Atmel integrated circuit. 28 | * 29 | * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 30 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 31 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 32 | * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 33 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 38 | * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 39 | * POSSIBILITY OF SUCH DAMAGE. 40 | * 41 | * \atsha204_library_license_stop 42 | */ 43 | 44 | #include "swi_phys.h" // hardware dependent declarations for SWI 45 | #include "uart_config.h" // UART definitions 46 | #include "avr_compatible.h" // translates generic AVR UART macros into specific ones 47 | 48 | #ifdef SHA204_SWI_UART 49 | /** \defgroup atsha204_swi_uart Module 13: UART Interface 50 | * 51 | * This module implements the single-wire interface using a UART 52 | * micro-controller peripheral. 53 | */ 54 | 55 | /** \brief This UART function is a dummy to satisfy the SWI module interface. 56 | * 57 | * \param[in] id not used in this UART module, only used in SWI bit-banging module 58 | * To be able to talk to two devices (client or host) sending a 59 | * Pause flag is required. Please refer to the data sheet. 60 | */ 61 | void swi_set_device_id(uint8_t id) { 62 | } 63 | 64 | 65 | /** \brief This UART function initializes the hardware. 66 | */ 67 | void swi_enable(void) { 68 | UCSRA = _BV(U2X); 69 | 70 | // According to the data sheet, the formula should be the one below 71 | // that is commented out. But what is missing in the data sheet is 72 | // rounding the result. 73 | // In this implementation for an F_CPU = 16 MHz we get UBRRL = 7.68. 74 | // But according to the data sheet, we need to load 8, not 7, to achieve 75 | // a baudrate of 230400 with an error of -3.5%. Therefore, we have to 76 | // add 1 to the result before type casting. 77 | // UBRRL = (uint8_t) (F_CPU / (8UL * BAUD_RATE) - 1UL); 78 | UBRRL = (uint8_t) (F_CPU / (8UL * BAUD_RATE)); 79 | 80 | // When using a UART for the SWI, we configure 81 | // the UART with one start bit, seven character 82 | // bits, and one stop bit, a total of nine bits. 83 | // This leads to a bit width of 84 | // t(bit) = 9 / 230400 = 39.0625 us. 85 | UCSRC = _BV(UCSZ11); 86 | 87 | // Disable rx and tx interrupt. 88 | UCSRB &= ~(_BV(TXCIE) | _BV(RXCIE)); 89 | 90 | #ifdef DEBUG_UART 91 | DEBUG_PORT_DDR |= _BV(DEBUG_BIT); 92 | DEBUG_LOW; 93 | #endif 94 | } 95 | 96 | 97 | /** \brief This UART function sets the signal pin using GPIO. 98 | * 99 | It is used to generate a Wake-up pulse.
100 | Another way to generate a Wake-up pulse is using the UART 101 | at half the communication baud rate and sending a 0. 102 | Keeping the baud rate at 230400 would only produce 103 | the signal wire going low for 34.7 us 104 | when sending a data byte of 0 that causes the signal wire 105 | being low for eight bits (start bit and seven data bits). 106 | Configuring the UART for half the baud rate and sending 107 | a 0 produces a long enough Wake-up pulse of 69.4 us.
108 | The fact that a hardware independent Physical layer above 109 | this hardware dependent layer delays for Wake-pulse width 110 | after calling this function would only add this delay to the 111 | much longer delay of 3 ms after the Wake-up pulse. 112 | With other words, by not using GPIO for the generation of 113 | a Wake-up pulse, we add only 69.4 us to the delay of 114 | 3000 us after the Wake-up pulse.
115 | Implementing a Wake-up pulse generation using the UART 116 | would introduce a slight design flaw though since this module 117 | would now "know" something about the width of the Wake-up pulse. 118 | We could add a function that sets the baud rate and 119 | sends a 0, but that would add at least 150 bytes of code. 120 | * \param[in] is_high 0: set signal low, otherwise set signal high 121 | */ 122 | void swi_set_signal_pin(uint8_t is_high) 123 | { 124 | // Turn off transmit and receive. 125 | UCSRB &= ~(_BV(RXEN) | _BV(TXEN)); 126 | 127 | UART_GPIO_DDR |= UART_GPIO_PIN_TX; 128 | 129 | if (is_high > 0) 130 | UART_GPIO_OUT |= UART_GPIO_PIN_TX; 131 | else 132 | UART_GPIO_OUT &= ~UART_GPIO_PIN_TX; 133 | } 134 | 135 | 136 | /** \brief This UART function sends bytes to an SWI device. 137 | * \param[in] count number of bytes to send 138 | * \param[in] buffer pointer to transmit buffer 139 | * \return status of the operation 140 | */ 141 | uint8_t swi_send_bytes(uint8_t count, uint8_t *buffer) 142 | { 143 | uint8_t i, bit_mask, timeout, rx_tx_delay = RX_TX_DELAY; 144 | 145 | UCSRB &= ~_BV(RXEN); // Turn off receive. 146 | UCSRB |= _BV(TXEN); // Turn on transmit. 147 | 148 | while (rx_tx_delay--); 149 | 150 | for (i = 0; i < count; i++) { 151 | DEBUG_HIGH; 152 | for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) { 153 | timeout = BIT_TIMEOUT; 154 | while ((UCSRA & _BV(UDRE)) == 0) { 155 | if (timeout-- == 0) { 156 | UCSRA |= _BV(TXC); 157 | return SWI_FUNCTION_RETCODE_TIMEOUT; 158 | } 159 | } 160 | 161 | // Create a start pulse only ("zero" bit) 162 | // or a start pulse and a zero pulse ("one" bit). 163 | // The zero pulse is placed at UDR bit 2 (lsb first). 164 | UDR = (bit_mask & buffer[i]) ? 0x7F : 0x7D; 165 | } 166 | DEBUG_LOW; 167 | } 168 | // Wait until last byte is sent. 169 | // This should not take longer than bit time (39 us). 170 | // The polling loop takes around 1 us on an 8-bit AVR clocking at 16 MHz. 171 | timeout = BIT_TIMEOUT; 172 | while ((UCSRA & _BV(TXC)) == 0) { 173 | if (timeout-- == 0) 174 | return SWI_FUNCTION_RETCODE_TIMEOUT; 175 | } 176 | 177 | // We must manually clear transmit complete flag if not using interrupts 178 | // by writing a logic one to it! 179 | UCSRA |= _BV(TXC); 180 | 181 | return SWI_FUNCTION_RETCODE_SUCCESS; 182 | } 183 | 184 | 185 | /** \brief This UART function sends one byte to an SWI device. 186 | * \param[in] value byte to send 187 | * \return status of the operation 188 | */ 189 | uint8_t swi_send_byte(uint8_t value) 190 | { 191 | return swi_send_bytes(1, &value); 192 | } 193 | 194 | 195 | /** \brief This UART function receives bytes from an SWI device. 196 | * \param[in] count number of bytes to receive 197 | * \param[out] buffer pointer to receive buffer 198 | * \return status of the operation 199 | */ 200 | uint8_t swi_receive_bytes(uint8_t count, uint8_t *buffer) { 201 | uint8_t i, bit_mask, bit_data, timeout; 202 | 203 | // Turn off transmit. The transmitter will not turn off until transmit is complete. 204 | UCSRB &= ~_BV(TXEN); 205 | 206 | // Disable pull-up resistor. 207 | UART_GPIO_DDR &= ~(UART_GPIO_PIN_TX | UART_GPIO_PIN_TX); 208 | UART_GPIO_OUT &= ~(UART_GPIO_PIN_TX | UART_GPIO_PIN_TX); 209 | 210 | // Turn on receive. 211 | UCSRB |= _BV(RXEN); 212 | 213 | DEBUG_HIGH; 214 | 215 | for (i = 0; i < count; i++) { 216 | buffer[i] = 0; 217 | for (bit_mask = 1; bit_mask > 0; bit_mask <<= 1) { 218 | timeout = BIT_TIMEOUT; 219 | while (bit_is_clear(UCSRA, RXC)) { 220 | if (timeout-- == 0) 221 | return (i == 0 ? SWI_FUNCTION_RETCODE_TIMEOUT : SWI_FUNCTION_RETCODE_RX_FAIL); 222 | } 223 | bit_data = UDR; 224 | // If the device sends a "one" bit, UDR bits 1 to 6 are set (0x7E). 225 | // LSB comes first. Reversing 0x7E results in 0x7E. 226 | if ((bit_data & 0x7E) == 0x7E) 227 | // Received "one" bit. 228 | buffer[i] |= bit_mask; 229 | } 230 | } 231 | DEBUG_LOW; 232 | 233 | return SWI_FUNCTION_RETCODE_SUCCESS; 234 | } 235 | #endif 236 | /** @} */ 237 | -------------------------------------------------------------------------------- /src/cryptoauth.h: -------------------------------------------------------------------------------- 1 | #include "api/CryptoBuffer.h" 2 | #include "api/AtSha204.h" 3 | #include "api/AtEccX08.h" 4 | #include "softcrypto/sha256.h" 5 | #include "softcrypto/sha_256.h" 6 | -------------------------------------------------------------------------------- /src/keywords.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thiseldo/cryptoauth-arduino/0e49f59105f5758c347347ea0125e7fc61eca551/src/keywords.txt -------------------------------------------------------------------------------- /src/softcrypto/sha256.h: -------------------------------------------------------------------------------- 1 | /* sha256.h */ 2 | /* 3 | This file is part of the AVR-Crypto-Lib. 4 | Copyright (C) 2008 Daniel Otte (daniel.otte@rub.de) 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | /** 20 | * \file sha256.h 21 | * \author Daniel Otte 22 | * \date 2006-05-16 23 | * \license GPLv3 or later 24 | * 25 | */ 26 | 27 | #ifndef SHA256_H_ 28 | #define SHA256_H_ 29 | 30 | #define __LITTLE_ENDIAN__ 31 | 32 | 33 | #include 34 | 35 | /** \def SHA256_HASH_BITS 36 | * defines the size of a SHA-256 hash value in bits 37 | */ 38 | 39 | /** \def SHA256_HASH_BYTES 40 | * defines the size of a SHA-256 hash value in bytes 41 | */ 42 | 43 | /** \def SHA256_BLOCK_BITS 44 | * defines the size of a SHA-256 input block in bits 45 | */ 46 | 47 | /** \def SHA256_BLOCK_BYTES 48 | * defines the size of a SHA-256 input block in bytes 49 | */ 50 | 51 | #ifdef __cplusplus 52 | extern "C"{ 53 | #endif 54 | 55 | #define SHA256_HASH_BITS 256 56 | #define SHA256_HASH_BYTES (SHA256_HASH_BITS/8) 57 | #define SHA256_BLOCK_BITS 512 58 | #define SHA256_BLOCK_BYTES (SHA256_BLOCK_BITS/8) 59 | 60 | /** \typedef sha256_ctx_t 61 | * \brief SHA-256 context type 62 | * 63 | * A variable of this type may hold the state of a SHA-256 hashing process 64 | */ 65 | typedef struct { 66 | uint32_t h[8]; 67 | uint64_t length; 68 | } sha256_ctx_t; 69 | 70 | /** \typedef sha256_hash_t 71 | * \brief SHA-256 hash value type 72 | * 73 | * A variable of this type may hold the hash value produced by the 74 | * sha256_ctx2hash(sha256_hash_t *dest, const sha256_ctx_t *state) function. 75 | */ 76 | typedef uint8_t sha256_hash_t[SHA256_HASH_BYTES]; 77 | 78 | /** \fn void sha256_init(sha256_ctx_t *state) 79 | * \brief initialise a SHA-256 context 80 | * 81 | * This function sets a ::sha256_ctx_t to the initial values for hashing. 82 | * \param state pointer to the SHA-256 hashing context 83 | */ 84 | void sha256_init(sha256_ctx_t *state); 85 | 86 | /** \fn void sha256_nextBlock (sha256_ctx_t *state, const void *block) 87 | * \brief update the context with a given block 88 | * 89 | * This function updates the SHA-256 hash context by processing the given block 90 | * of fixed length. 91 | * \param state pointer to the SHA-256 hash context 92 | * \param block pointer to the block of fixed length (512 bit = 64 byte) 93 | */ 94 | void sha256_nextBlock (sha256_ctx_t *state, const void *block); 95 | 96 | /** \fn void sha256_lastBlock(sha256_ctx_t *state, const void *block, uint16_t length_b) 97 | * \brief finalize the context with the given block 98 | * 99 | * This function finalizes the SHA-256 hash context by processing the given block 100 | * of variable length. 101 | * \param state pointer to the SHA-256 hash context 102 | * \param block pointer to the block of fixed length (512 bit = 64 byte) 103 | * \param length_b the length of the block in bits 104 | */ 105 | void sha256_lastBlock(sha256_ctx_t *state, const void *block, uint16_t length_b); 106 | 107 | /** \fn void sha256_ctx2hash(sha256_hash_t *dest, const sha256_ctx_t *state) 108 | * \brief convert the hash state into the hash value 109 | * This function reads the context and writes the hash value to the destination 110 | * \param dest pointer to the location where the hash value should be written 111 | * \param state pointer to the SHA-256 hash context 112 | */ 113 | void sha256_ctx2hash(sha256_hash_t *dest, const sha256_ctx_t *state); 114 | 115 | /** \fn void sha256(sha256_hash_t *dest, const void *msg, uint32_t length_b) 116 | * \brief simple SHA-256 hashing function for direct hashing 117 | * 118 | * This function automaticaly hashes a given message of arbitary length with 119 | * the SHA-256 hashing algorithm. 120 | * \param dest pointer to the location where the hash value is going to be written to 121 | * \param msg pointer to the message thats going to be hashed 122 | * \param length_b length of the message in bits 123 | */ 124 | void sha256(sha256_hash_t *dest, const void *msg, uint32_t length_b); 125 | 126 | #ifdef __cplusplus 127 | } // extern "C" 128 | #endif 129 | #endif /*SHA256_H_*/ 130 | -------------------------------------------------------------------------------- /src/softcrypto/sha_256.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "sha_256.h" 5 | 6 | const uint32_t sha256K[] PROGMEM = { 7 | 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5, 8 | 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174, 9 | 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da, 10 | 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967, 11 | 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85, 12 | 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070, 13 | 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3, 14 | 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 15 | }; 16 | 17 | #define BUFFER_SIZE 64 18 | 19 | const uint8_t sha256InitState[] PROGMEM = { 20 | 0x67,0xe6,0x09,0x6a, // H0 21 | 0x85,0xae,0x67,0xbb, // H1 22 | 0x72,0xf3,0x6e,0x3c, // H2 23 | 0x3a,0xf5,0x4f,0xa5, // H3 24 | 0x7f,0x52,0x0e,0x51, // H4 25 | 0x8c,0x68,0x05,0x9b, // H5 26 | 0xab,0xd9,0x83,0x1f, // H6 27 | 0x19,0xcd,0xe0,0x5b // H7 28 | }; 29 | 30 | void Sha256Class::init(void) { 31 | memcpy_P(state.b,sha256InitState,32); 32 | byteCount = 0; 33 | bufferOffset = 0; 34 | } 35 | 36 | uint32_t Sha256Class::ror32(uint32_t number, uint8_t bits) { 37 | return ((number << (32-bits)) | (number >> bits)); 38 | } 39 | 40 | void Sha256Class::hashBlock() { 41 | uint8_t i; 42 | uint32_t a,b,c,d,e,f,g,h,t1,t2; 43 | 44 | a=state.w[0]; 45 | b=state.w[1]; 46 | c=state.w[2]; 47 | d=state.w[3]; 48 | e=state.w[4]; 49 | f=state.w[5]; 50 | g=state.w[6]; 51 | h=state.w[7]; 52 | 53 | for (i=0; i<64; i++) { 54 | if (i>=16) { 55 | t1 = buffer.w[i&15] + buffer.w[(i-7)&15]; 56 | t2 = buffer.w[(i-2)&15]; 57 | t1 += ror32(t2,17) ^ ror32(t2,19) ^ (t2>>10); 58 | t2 = buffer.w[(i-15)&15]; 59 | t1 += ror32(t2,7) ^ ror32(t2,18) ^ (t2>>3); 60 | buffer.w[i&15] = t1; 61 | } 62 | t1 = h; 63 | t1 += ror32(e,6) ^ ror32(e,11) ^ ror32(e,25); // ∑1(e) 64 | t1 += g ^ (e & (g ^ f)); // Ch(e,f,g) 65 | t1 += pgm_read_dword(sha256K+i); // Ki 66 | t1 += buffer.w[i&15]; // Wi 67 | t2 = ror32(a,2) ^ ror32(a,13) ^ ror32(a,22); // ∑0(a) 68 | t2 += ((b & c) | (a & (b | c))); // Maj(a,b,c) 69 | h=g; g=f; f=e; e=d+t1; d=c; c=b; b=a; a=t1+t2; 70 | } 71 | state.w[0] += a; 72 | state.w[1] += b; 73 | state.w[2] += c; 74 | state.w[3] += d; 75 | state.w[4] += e; 76 | state.w[5] += f; 77 | state.w[6] += g; 78 | state.w[7] += h; 79 | } 80 | 81 | void Sha256Class::addUncounted(uint8_t data) { 82 | buffer.b[bufferOffset ^ 3] = data; 83 | bufferOffset++; 84 | if (bufferOffset == BUFFER_SIZE) { 85 | hashBlock(); 86 | bufferOffset = 0; 87 | } 88 | } 89 | 90 | size_t Sha256Class::write(uint8_t data) { 91 | ++byteCount; 92 | addUncounted(data); 93 | return byteCount; 94 | } 95 | 96 | void Sha256Class::pad() { 97 | // Implement SHA-256 padding (fips180-2 §5.1.1) 98 | 99 | // Pad with 0x80 followed by 0x00 until the end of the block 100 | addUncounted(0x80); 101 | while (bufferOffset != 56) addUncounted(0x00); 102 | 103 | // Append length in the last 8 bytes 104 | addUncounted(0); // We're only using 32 bit lengths 105 | addUncounted(0); // But SHA-1 supports 64 bit lengths 106 | addUncounted(0); // So zero pad the top bits 107 | addUncounted(byteCount >> 29); // Shifting to multiply by 8 108 | addUncounted(byteCount >> 21); // as SHA-1 supports bitstreams as well as 109 | addUncounted(byteCount >> 13); // byte. 110 | addUncounted(byteCount >> 5); 111 | addUncounted(byteCount << 3); 112 | } 113 | 114 | 115 | uint8_t* Sha256Class::result(void) { 116 | // Pad to complete the last block 117 | pad(); 118 | 119 | // Swap byte order back 120 | for (int i=0; i<8; i++) { 121 | uint32_t a,b; 122 | a=state.w[i]; 123 | b=a<<24; 124 | b|=(a<<8) & 0x00ff0000; 125 | b|=(a>>8) & 0x0000ff00; 126 | b|=a>>24; 127 | state.w[i]=b; 128 | } 129 | 130 | // Return pointer to hash (20 characters) 131 | return state.b; 132 | } 133 | 134 | #define HMAC_IPAD 0x36 135 | #define HMAC_OPAD 0x5c 136 | 137 | uint8_t keyBuffer[BLOCK_LENGTH]; // K0 in FIPS-198a 138 | uint8_t innerHash[HASH_LENGTH]; 139 | 140 | void Sha256Class::initHmac(const uint8_t* key, int keyLength) { 141 | uint8_t i; 142 | memset(keyBuffer,0,BLOCK_LENGTH); 143 | if (keyLength > BLOCK_LENGTH) { 144 | // Hash long keys 145 | init(); 146 | for (;keyLength--;) write(*key++); 147 | memcpy(keyBuffer,result(),HASH_LENGTH); 148 | } else { 149 | // Block length keys are used as is 150 | memcpy(keyBuffer,key,keyLength); 151 | } 152 | // Start inner hash 153 | init(); 154 | for (i=0; i 5 | #include "Print.h" 6 | 7 | #define HASH_LENGTH 32 8 | #define BLOCK_LENGTH 64 9 | 10 | union _buffer { 11 | uint8_t b[BLOCK_LENGTH]; 12 | uint32_t w[BLOCK_LENGTH/4]; 13 | }; 14 | union _state { 15 | uint8_t b[HASH_LENGTH]; 16 | uint32_t w[HASH_LENGTH/4]; 17 | }; 18 | 19 | class Sha256Class : public Print 20 | { 21 | public: 22 | void init(void); 23 | void initHmac(const uint8_t* secret, int secretLength); 24 | uint8_t* result(void); 25 | uint8_t* resultHmac(void); 26 | virtual size_t write(uint8_t); 27 | using Print::write; 28 | private: 29 | void pad(); 30 | void addUncounted(uint8_t data); 31 | void hashBlock(); 32 | uint32_t ror32(uint32_t number, uint8_t bits); 33 | _buffer buffer; 34 | uint8_t bufferOffset; 35 | _state state; 36 | uint32_t byteCount; 37 | uint8_t keyBuffer[BLOCK_LENGTH]; 38 | uint8_t innerHash[HASH_LENGTH]; 39 | }; 40 | extern Sha256Class Sha256; 41 | 42 | #endif 43 | --------------------------------------------------------------------------------