├── .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 | -
115 | Try to re-synchronize without sending a Wake token.
116 | This step is implemented in the Physical layer.
117 |
118 | -
119 | If the first step did not succeed send a Wake token.
120 |
121 | -
122 | Try to read the Wake response.
123 |
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 | -
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 |
317 | -
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 |
324 | -
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 |
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 | -
134 | Try to re-synchronize without sending a Wake token.
135 | This step is implemented in the Physical layer.
136 |
137 | -
138 | If the first step did not succeed send a Wake token.
139 |
140 | -
141 | Try to read the Wake response.
142 |
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 | -
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 |
323 | -
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 |
330 | -
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 |
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 | - Wait t_timeout.
197 | - Send the transmit flag.
198 | -
199 | If the chip responds within t_turnaround,
200 | then the system may proceed with more commands.
201 |
202 | - Send a Wake token, wait t_whi, and send the transmit flag.
203 | -
204 | The chip should respond with a 0x11 return status within
205 | t_turnaround, after which the system may proceed with more commands.
206 |
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 |
--------------------------------------------------------------------------------