├── README.md
├── binary
└── ctf.hex
├── license.txt
├── solutions
├── Riscure solution
│ ├── Solution path diagram.png
│ └── writeup.txt
└── winners solutions
│ ├── Riscure's comments to the winners solutions.txt
│ ├── STARE @ Cisco SPVSS
│ └── writeup.md
│ └── Team R@bbit
│ ├── hack.py
│ ├── setup.jpg
│ └── writeup.txt
└── source
├── aes
├── README
├── aes.h
├── aes128_dec.c
├── aes128_dec.h
├── aes128_enc.c
├── aes128_enc.h
├── aes_dec.c
├── aes_dec.h
├── aes_enc.c
├── aes_enc.h
├── aes_invsbox.c
├── aes_invsbox.h
├── aes_keyschedule.c
├── aes_keyschedule.h
├── aes_sbox.c
├── aes_sbox.h
├── aes_types.h
├── build.sh
├── gf256mul.S
└── gf256mul.h
├── auth
├── auth.c
├── auth.h
└── build.sh
├── build.sh
├── check_board.py
├── eeprom_rw
├── build.sh
├── eeprom_rw.c
└── eeprom_rw.h
├── license.txt
├── main
├── avr5.x
├── build.sh
├── ldscript
└── main.c
├── menu
├── build.sh
├── menu.c
└── menu.h
├── overflow_readflash
├── build.sh
├── overflow_readflash.c
└── overflow_readflash.h
├── overflow_rop
├── build.sh
├── examine_stack.c
├── examine_stack.h
├── overflow_rop.c
└── overflow_rop.h
├── random
├── README
├── build.sh
├── random.c
├── random.h
└── random_test.c
├── serial
├── README
├── build.sh
├── dbg_putchar.c
├── dbg_putchar.h
├── serial_io.c
├── serial_io.h
├── serial_test.c
├── usart.c
├── usart.h
├── usartx.c
└── usartx.h
├── upload.sh
└── variables
├── build.sh
├── variables.c
└── variables.h
/README.md:
--------------------------------------------------------------------------------
1 | # RHme+ 2015
2 |
3 | ## License
4 | This challenge has been published under the terms of the Reciprocal Public License 1.5.
5 | The terms of the license can be checked here: [http://opensource.org/licenses/RPL-1.5](http://opensource.org/licenses/RPL-1.5)
6 |
7 | ## What is RHme+
8 |
9 | The RHme+ (Riscure Hack me ) is a low level hardware challenge that comes in the form of an Arduino board. It was launched during BlackHat Amsterdam in 2015. The winners of the first edition were announced on 18th of January 2016. The writeups together with the interview of the winners can be found from March 1 at the [official challenge website](http://www.riscure.com/challenge).
10 |
11 | Use your weapon of choice to extract the flags. We have no preference and we are curious to see where your creativity and skill will take you! Just be sure to have fun! ;-)
12 | We estimate the difficulty level to be moderate. If you like these challenges and you would like more, let us know. Get in touch with us via twitter (#riscure #rhme+) or send us an email at challenge. at. riscure.com
13 |
14 |
15 | ###### Choosing the target
16 | You need to install the RHme+ firmware into a target. The "official" target for the challenge is an [Arduino nano 3.0](https://www.arduino.cc/en/Main/ArduinoBoardNano). If you don't have one, you can buy a clone in ebay for few euros. Alternatively you can use any other development board based in the Atmel ATmega328. Many other Arduino and Arduino-based boards should work. The following is a list of Arduino targets:
17 |
18 | **Tested devices**
19 | - Arduino Nano 3.0
20 |
21 | **Untested devices that should work**
22 | - Arduino Uno
23 | - Arduino Pro
24 | - Arduino Pro Mini (5V and 16 MHz version)
25 | - Arduino Duemilanove (ATmega328P version)
26 | - Arduino Mini (Pro ATmega328P version)
27 |
28 | **Untested devices that might work**
29 | - LilyPad Arduino: It runs at 8MHz instead of 16MHz, so the timing-dependent attacks could be affected
30 |
31 | For other Arduino-based targets, you can check the [Wikipedia](http://en.wikipedia.org/wiki/List_of_Arduino_boards_and_compatible_systems). Any board based in ATmega328P is potentially able to run the firmware unless that the UARTs or analog inputs of the ATmega are connected to another chip (e.g. a Bluetooth or Zigbee module).
32 |
33 | ###### Burning the firmware into the target
34 | You need to burn the file binary\ctf.hex into the ATmega overwriting Arduino bootloader. For that you need an external AVR-ISP programmer. Is up to you to find a suitable programmer and the instructions to use it. You can even use another Arduino and use it as an AVR-ISP programmer. Follow [this instructions](http://www.arduino.cc/en/Tutorial/ArduinoISP) to prepare another Arduino as a ISP programmer and follow [this](http://learn.adafruit.com/arduino-tips-tricks-and-techniques/arduinoisp#bonus-using-with-avrdude) to burn the RHme+ firmware in your target.
35 |
36 | ###### Checking that your target is working
37 | Connect the target to your computer through the USB (or the UART0 is you are not using a target with USB). Open the serial port with any terminal tool and press the reset bottom in the target. Do you see garbage being send? Congrats! It is very likely that you programmed correctly the firmware. Unfortunately the first challenge you have to solve is to find how to properly communicate with the target so that garbage you see now becomes something meaningful.# RHme+ 2015
38 |
39 | ## Tips and tricks
40 |
41 | During the Blackhat Europe 2015, Riscure gave away more than 150 Arduino boards prepared with the RHme+ challenge. The original challenge was a "black box" evaluation, so the participants had no access to the source code, binary or such. Today we are releasing the source and binary of the challenge so everybody can play and try it at home. We recommend you to try to solve the challenge without reading the source or reversing the binary.
42 |
43 | The ultimate goal of the challenge is to recover the Admin Key stored in the hardware. In order to ease the challenge, we provide some information that could help you:
44 |
45 | * All hardware and software attacks are in the scope. There are many ways to solve the challenge, so if you get stuck at any point, just go back and try something different. Please, consider techniques like side-channel attacks, fault injection and other fancy hardware attacks as well as classic software explotation attacks like buffer overflows or unvalidated inputs.
46 | * If you have no experience with hardware attacks, don’t worry! You can solve the challenge using exclusively software exploitation techniques. However, you can also solve the challenge using only hardware attacks or a combination of both.
47 | * Read about the CPU architecture and learn about its limitations and try to figure out what the I/Os do;
48 | * There are three types of users that can login, the normal user, the privileged user and the admin. All of them have a 128 bit private key, the User, Prividleged and Admin Key respectively.
49 | * The login mechanism is a challenge-response protocol. The target generates a 32 bit random number called nonce using an external source of noise. The nonce is sent to the user and the target waits for the correct response.
50 | * The response is calculated as follows: the nonce is padded with zeros up to 128 bits to form the plaintext P, which is then encrypted using AES-128 with the Key. The output is AND-masked with a 32 bit mask M. The result of the masking is the 32 bit response R to the challenge.
51 | * The target calculates three possible responses using the User Key, Privileged and the Admin key with the masks 0x000FFFFF, 0x00FFFFFF and 0xFFFFFFFF respectively. If one response matches the input provided by the user, the access is allowed with the corresponding privilege level (normal user, privileged user or admin). Here is an example of a response calculation:
52 |
53 | ```
54 | Admin Key = 000102030405060708090A0B0C0D0E0F
55 |
56 | User Key = F0E0D0C0B0A090807060504030201000
57 |
58 | Madmin= FFFFFFFF
59 |
60 | Muser = 000FFFFF
61 |
62 | Nonce = 0AEEB964
63 |
64 | P = 0AEEB964000000000000000000000000
65 |
66 | Radmin = AES(P,Admin Key) & Madmin = 2496faad
67 |
68 | Ruser= AES(P,User Key) &Muser = 00033695
69 | ```
70 |
71 | * There are many secondary "assets" you can try to obtain: login as User, login as Admin, recovering the User key, dumping the binary, gaining runtime control, affecting the RNG, etc. You don't need to get all these assets in order to extract the Admin Key, but you will have fun doing it!
72 | * Write us to let us know your impressions about the challenge!!!
73 |
74 | ## Solutions ##
75 | The write-ups, scripts and setup photos of the challenge winners as well as the "official" solution proposed by the challenge designers are available in the solutions\ folder.
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | Reciprocal Public License (RPL-1.5)
2 |
3 | Version 1.5, July 15, 2007
4 |
5 | Copyright (C) 2001-2007
6 | Technical Pursuit Inc.,
7 | All Rights Reserved.
8 |
9 |
10 | PREAMBLE
11 |
12 | The Reciprocal Public License (RPL) is based on the concept of reciprocity or,
13 | if you prefer, fairness.
14 |
15 | In short, this license grew out of a desire to close loopholes in previous open
16 | source licenses, loopholes that allowed parties to acquire open source software
17 | and derive financial benefit from it without having to release their
18 | improvements or derivatives to the community which enabled them. This occurred
19 | any time an entity did not release their application to a "third party".
20 |
21 | While there is a certain freedom in this model of licensing, it struck the
22 | authors of the RPL as being unfair to the open source community at large and to
23 | the original authors of the works in particular. After all, bug fixes,
24 | extensions, and meaningful and valuable derivatives were not consistently
25 | finding their way back into the community where they could fuel further, and
26 | faster, growth and expansion of the overall open source software base.
27 |
28 | While you should clearly read and understand the entire license, the essence of
29 | the RPL is found in two definitions: "Deploy" and "Required Components".
30 |
31 | Regarding deployment, under the RPL your changes, bug fixes, extensions, etc.
32 | must be made available to the open source community at large when you Deploy in
33 | any form -- either internally or to an outside party. Once you start running
34 | the software you have to start sharing the software.
35 |
36 | Further, under the RPL all components you author including schemas, scripts,
37 | source code, etc. -- regardless of whether they're compiled into a single
38 | binary or used as two halves of client/server application -- must be shared.
39 | You have to share the whole pie, not an isolated slice of it.
40 |
41 | In addition to these goals, the RPL was authored to meet the requirements of
42 | the Open Source Definition as maintained by the Open Source Initiative (OSI).
43 |
44 | The specific terms and conditions of the license are defined in the remainder
45 | of this document.
46 |
47 |
48 | LICENSE TERMS
49 |
50 | 1.0 General; Applicability & Definitions. This Reciprocal Public License
51 | Version 1.5 ("License") applies to any programs or other works as well as any
52 | and all updates or maintenance releases of said programs or works ("Software")
53 | not already covered by this License which the Software copyright holder
54 | ("Licensor") makes available containing a License Notice (hereinafter defined)
55 | from the Licensor specifying or allowing use or distribution under the terms of
56 | this License. As used in this License:
57 |
58 | 1.1 "Contributor" means any person or entity who created or contributed to the
59 | creation of an Extension.
60 |
61 | 1.2 "Deploy" means to use, Serve, sublicense or distribute Licensed Software
62 | other than for Your internal Research and/or Personal Use, and includes
63 | without limitation, any and all internal use or distribution of Licensed
64 | Software within Your business or organization other than for Research and/or
65 | Personal Use, as well as direct or indirect sublicensing or distribution of
66 | Licensed Software by You to any third party in any form or manner.
67 |
68 | 1.3 "Derivative Works" as used in this License is defined under U.S. copyright
69 | law.
70 |
71 | 1.4 "Electronic Distribution Mechanism" means a mechanism generally accepted
72 | in the software development community for the electronic transfer of data such
73 | as download from an FTP server or web site, where such mechanism is publicly
74 | accessible.
75 |
76 | 1.5 "Extensions" means any Modifications, Derivative Works, or Required
77 | Components as those terms are defined in this License.
78 |
79 | 1.6 "License" means this Reciprocal Public License.
80 |
81 | 1.7 "License Notice" means any notice contained in EXHIBIT A.
82 |
83 | 1.8 "Licensed Software" means any Software licensed pursuant to this License.
84 | Licensed Software also includes all previous Extensions from any Contributor
85 | that You receive.
86 |
87 | 1.9 "Licensor" means the copyright holder of any Software previously not
88 | covered by this License who releases the Software under the terms of this
89 | License.
90 |
91 | 1.10 "Modifications" means any additions to or deletions from the substance or
92 | structure of (i) a file or other storage containing Licensed Software, or (ii)
93 | any new file or storage that contains any part of Licensed Software, or (iii)
94 | any file or storage which replaces or otherwise alters the original
95 | functionality of Licensed Software at runtime.
96 |
97 | 1.11 "Personal Use" means use of Licensed Software by an individual solely for
98 | his or her personal, private and non-commercial purposes. An individual's use
99 | of Licensed Software in his or her capacity as an officer, employee, member,
100 | independent contractor or agent of a corporation, business or organization
101 | (commercial or non-commercial) does not qualify as Personal Use.
102 |
103 | 1.12 "Required Components" means any text, programs, scripts, schema,
104 | interface definitions, control files, or other works created by You which are
105 | required by a third party of average skill to successfully install and run
106 | Licensed Software containing Your Modifications, or to install and run Your
107 | Derivative Works.
108 |
109 | 1.13 "Research" means investigation or experimentation for the purpose of
110 | understanding the nature and limits of the Licensed Software and its potential
111 | uses.
112 |
113 | 1.14 "Serve" means to deliver Licensed Software and/or Your Extensions by
114 | means of a computer network to one or more computers for purposes of execution
115 | of Licensed Software and/or Your Extensions.
116 |
117 | 1.15 "Software" means any computer programs or other works as well as any
118 | updates or maintenance releases of those programs or works which are
119 | distributed publicly by Licensor.
120 |
121 | 1.16 "Source Code" means the preferred form for making modifications to the
122 | Licensed Software and/or Your Extensions, including all modules contained
123 | therein, plus any associated text, interface definition files, scripts used to
124 | control compilation and installation of an executable program or other
125 | components required by a third party of average skill to build a running
126 | version of the Licensed Software or Your Extensions.
127 |
128 | 1.17 "User-Visible Attribution Notice" means any notice contained in EXHIBIT B.
129 |
130 | 1.18 "You" or "Your" means an individual or a legal entity exercising rights
131 | under this License. For legal entities, "You" or "Your" includes any entity
132 | which controls, is controlled by, or is under common control with, You, where
133 | "control" means (a) the power, direct or indirect, to cause the direction or
134 | management of such entity, whether by contract or otherwise, or (b) ownership
135 | of fifty percent (50%) or more of the outstanding shares or beneficial
136 | ownership of such entity.
137 |
138 | 2.0 Acceptance Of License. You are not required to accept this License since
139 | you have not signed it, however nothing else grants you permission to use,
140 | copy, distribute, modify, or create derivatives of either the Software or any
141 | Extensions created by a Contributor. These actions are prohibited by law if
142 | you do not accept this License. Therefore, by performing any of these actions
143 | You indicate Your acceptance of this License and Your agreement to be bound by
144 | all its terms and conditions. IF YOU DO NOT AGREE WITH ALL THE TERMS AND
145 | CONDITIONS OF THIS LICENSE DO NOT USE, MODIFY, CREATE DERIVATIVES, OR
146 | DISTRIBUTE THE SOFTWARE. IF IT IS IMPOSSIBLE FOR YOU TO COMPLY WITH ALL THE
147 | TERMS AND CONDITIONS OF THIS LICENSE THEN YOU CAN NOT USE, MODIFY, CREATE
148 | DERIVATIVES, OR DISTRIBUTE THE SOFTWARE.
149 |
150 | 3.0 Grant of License From Licensor. Subject to the terms and conditions of
151 | this License, Licensor hereby grants You a world-wide, royalty-free, non-
152 | exclusive license, subject to Licensor's intellectual property rights, and any
153 | third party intellectual property claims derived from the Licensed Software
154 | under this License, to do the following:
155 |
156 | 3.1 Use, reproduce, modify, display, perform, sublicense and distribute
157 | Licensed Software and Your Extensions in both Source Code form or as an
158 | executable program.
159 |
160 | 3.2 Create Derivative Works (as that term is defined under U.S. copyright law)
161 | of Licensed Software by adding to or deleting from the substance or structure
162 | of said Licensed Software.
163 |
164 | 3.3 Under claims of patents now or hereafter owned or controlled by Licensor,
165 | to make, use, have made, and/or otherwise dispose of Licensed Software or
166 | portions thereof, but solely to the extent that any such claim is necessary to
167 | enable You to make, use, have made, and/or otherwise dispose of Licensed
168 | Software or portions thereof.
169 |
170 | 3.4 Licensor reserves the right to release new versions of the Software with
171 | different features, specifications, capabilities, functions, licensing terms,
172 | general availability or other characteristics. Title, ownership rights, and
173 | intellectual property rights in and to the Licensed Software shall remain in
174 | Licensor and/or its Contributors.
175 |
176 | 4.0 Grant of License From Contributor. By application of the provisions in
177 | Section 6 below, each Contributor hereby grants You a world-wide, royalty-
178 | free, non-exclusive license, subject to said Contributor's intellectual
179 | property rights, and any third party intellectual property claims derived from
180 | the Licensed Software under this License, to do the following:
181 |
182 | 4.1 Use, reproduce, modify, display, perform, sublicense and distribute any
183 | Extensions Deployed by such Contributor or portions thereof, in both Source
184 | Code form or as an executable program, either on an unmodified basis or as
185 | part of Derivative Works.
186 |
187 | 4.2 Under claims of patents now or hereafter owned or controlled by
188 | Contributor, to make, use, have made, and/or otherwise dispose of Extensions
189 | or portions thereof, but solely to the extent that any such claim is necessary
190 | to enable You to make, use, have made, and/or otherwise dispose of
191 | Licensed Software or portions thereof.
192 |
193 | 5.0 Exclusions From License Grant. Nothing in this License shall be deemed to
194 | grant any rights to trademarks, copyrights, patents, trade secrets or any
195 | other intellectual property of Licensor or any Contributor except as expressly
196 | stated herein. Except as expressly stated in Sections 3 and 4, no other patent
197 | rights, express or implied, are granted herein. Your Extensions may require
198 | additional patent licenses from Licensor or Contributors which each may grant
199 | in its sole discretion. No right is granted to the trademarks of Licensor or
200 | any Contributor even if such marks are included in the Licensed Software.
201 | Nothing in this License shall be interpreted to prohibit Licensor from
202 | licensing under different terms from this License any code that Licensor
203 | otherwise would have a right to license.
204 |
205 | 5.1 You expressly acknowledge and agree that although Licensor and each
206 | Contributor grants the licenses to their respective portions of the Licensed
207 | Software set forth herein, no assurances are provided by Licensor or any
208 | Contributor that the Licensed Software does not infringe the patent or other
209 | intellectual property rights of any other entity. Licensor and each
210 | Contributor disclaim any liability to You for claims brought by any other
211 | entity based on infringement of intellectual property rights or otherwise. As
212 | a condition to exercising the rights and licenses granted hereunder, You
213 | hereby assume sole responsibility to secure any other intellectual property
214 | rights needed, if any. For example, if a third party patent license is
215 | required to allow You to distribute the Licensed Software, it is Your
216 | responsibility to acquire that license before distributing the Licensed
217 | Software.
218 |
219 | 6.0 Your Obligations And Grants. In consideration of, and as an express
220 | condition to, the licenses granted to You under this License You hereby agree
221 | that any Modifications, Derivative Works, or Required Components (collectively
222 | Extensions) that You create or to which You contribute are governed by the
223 | terms of this License including, without limitation, Section 4. Any Extensions
224 | that You create or to which You contribute must be Deployed under the terms of
225 | this License or a future version of this License released under Section 7. You
226 | hereby grant to Licensor and all third parties a world-wide, non-exclusive,
227 | royalty-free license under those intellectual property rights You own or
228 | control to use, reproduce, display, perform, modify, create derivatives,
229 | sublicense, and distribute Licensed Software, in any form. Any Extensions You
230 | make and Deploy must have a distinct title so as to readily tell any
231 | subsequent user or Contributor that the Extensions are by You. You must
232 | include a copy of this License or directions on how to obtain a copy with
233 | every copy of the Extensions You distribute. You agree not to offer or impose
234 | any terms on any Source Code or executable version of the Licensed Software,
235 | or its Extensions that alter or restrict the applicable version of this
236 | License or the recipients' rights hereunder.
237 |
238 | 6.1 Availability of Source Code. You must make available, under the terms of
239 | this License, the Source Code of any Extensions that You Deploy, via an
240 | Electronic Distribution Mechanism. The Source Code for any version that You
241 | Deploy must be made available within one (1) month of when you Deploy and must
242 | remain available for no less than twelve (12) months after the date You cease
243 | to Deploy. You are responsible for ensuring that the Source Code to each
244 | version You Deploy remains available even if the Electronic Distribution
245 | Mechanism is maintained by a third party. You may not charge a fee for any
246 | copy of the Source Code distributed under this Section in excess of Your
247 | actual cost of duplication and distribution of said copy.
248 |
249 | 6.2 Description of Modifications. You must cause any Modifications that You
250 | create or to which You contribute to be documented in the Source Code, clearly
251 | describing the additions, changes or deletions You made. You must include a
252 | prominent statement that the Modifications are derived, directly or indirectly,
253 | from the Licensed Software and include the names of the Licensor and any
254 | Contributor to the Licensed Software in (i) the Source Code and (ii) in any
255 | notice displayed by the Licensed Software You distribute or in related
256 | documentation in which You describe the origin or ownership of the Licensed
257 | Software. You may not modify or delete any pre-existing copyright notices,
258 | change notices or License text in the Licensed Software without written
259 | permission of the respective Licensor or Contributor.
260 |
261 | 6.3 Intellectual Property Matters.
262 |
263 | a. Third Party Claims. If You have knowledge that a license to a third party's
264 | intellectual property right is required to exercise the rights granted by this
265 | License, You must include a human-readable file with Your distribution that
266 | describes the claim and the party making the claim in sufficient detail that a
267 | recipient will know whom to contact.
268 |
269 | b. Contributor APIs. If Your Extensions include an application programming
270 | interface ("API") and You have knowledge of patent licenses that are
271 | reasonably necessary to implement that API, You must also include this
272 | information in a human-readable file supplied with Your distribution.
273 |
274 | c. Representations. You represent that, except as disclosed pursuant to 6.3(a)
275 | above, You believe that any Extensions You distribute are Your original
276 | creations and that You have sufficient rights to grant the rights conveyed by
277 | this License.
278 |
279 | 6.4 Required Notices.
280 |
281 | a. License Text. You must duplicate this License or instructions on how to
282 | acquire a copy in any documentation You provide along with the Source Code of
283 | any Extensions You create or to which You contribute, wherever You describe
284 | recipients' rights relating to Licensed Software.
285 |
286 | b. License Notice. You must duplicate any notice contained in EXHIBIT A (the
287 | "License Notice") in each file of the Source Code of any copy You distribute
288 | of the Licensed Software and Your Extensions. If You create an Extension, You
289 | may add Your name as a Contributor to the Source Code and accompanying
290 | documentation along with a description of the contribution. If it is not
291 | possible to put the License Notice in a particular Source Code file due to its
292 | structure, then You must include such License Notice in a location where a
293 | user would be likely to look for such a notice.
294 |
295 | c. Source Code Availability. You must notify the software community of the
296 | availability of Source Code to Your Extensions within one (1) month of the date
297 | You initially Deploy and include in such notification a description of the
298 | Extensions, and instructions on how to acquire the Source Code. Should such
299 | instructions change you must notify the software community of revised
300 | instructions within one (1) month of the date of change. You must provide
301 | notification by posting to appropriate news groups, mailing lists, weblogs, or
302 | other sites where a publicly accessible search engine would reasonably be
303 | expected to index your post in relationship to queries regarding the Licensed
304 | Software and/or Your Extensions.
305 |
306 | d. User-Visible Attribution. You must duplicate any notice contained in
307 | EXHIBIT B (the "User-Visible Attribution Notice") in each user-visible display
308 | of the Licensed Software and Your Extensions which delineates copyright,
309 | ownership, or similar attribution information. If You create an Extension,
310 | You may add Your name as a Contributor, and add Your attribution notice, as an
311 | equally visible and functional element of any User-Visible Attribution Notice
312 | content. To ensure proper attribution, You must also include such User-Visible
313 | Attribution Notice in at least one location in the Software documentation
314 | where a user would be likely to look for such notice.
315 |
316 | 6.5 Additional Terms. You may choose to offer, and charge a fee for, warranty,
317 | support, indemnity or liability obligations to one or more recipients of
318 | Licensed Software. However, You may do so only on Your own behalf, and not on
319 | behalf of the Licensor or any Contributor except as permitted under other
320 | agreements between you and Licensor or Contributor. You must make it clear that
321 | any such warranty, support, indemnity or liability obligation is offered by You
322 | alone, and You hereby agree to indemnify the Licensor and every Contributor for
323 | any liability plus attorney fees, costs, and related expenses due to any such
324 | action or claim incurred by the Licensor or such Contributor as a result of
325 | warranty, support, indemnity or liability terms You offer.
326 |
327 | 6.6 Conflicts With Other Licenses. Where any portion of Your Extensions, by
328 | virtue of being Derivative Works of another product or similar circumstance,
329 | fall under the terms of another license, the terms of that license should be
330 | honored however You must also make Your Extensions available under this
331 | License. If the terms of this License continue to conflict with the terms of
332 | the other license you may write the Licensor for permission to resolve the
333 | conflict in a fashion that remains consistent with the intent of this License.
334 | Such permission will be granted at the sole discretion of the Licensor.
335 |
336 | 7.0 Versions of This License. Licensor may publish from time to time revised
337 | versions of the License. Once Licensed Software has been published under a
338 | particular version of the License, You may always continue to use it under the
339 | terms of that version. You may also choose to use such Licensed Software under
340 | the terms of any subsequent version of the License published by Licensor. No
341 | one other than Licensor has the right to modify the terms applicable to
342 | Licensed Software created under this License.
343 |
344 | 7.1 If You create or use a modified version of this License, which You may do
345 | only in order to apply it to software that is not already Licensed Software
346 | under this License, You must rename Your license so that it is not confusingly
347 | similar to this License, and must make it clear that Your license contains
348 | terms that differ from this License. In so naming Your license, You may not
349 | use any trademark of Licensor or of any Contributor. Should Your modifications
350 | to this License be limited to alteration of a) Section 13.8 solely to modify
351 | the legal Jurisdiction or Venue for disputes, b) EXHIBIT A solely to define
352 | License Notice text, or c) to EXHIBIT B solely to define a User-Visible
353 | Attribution Notice, You may continue to refer to Your License as the
354 | Reciprocal Public License or simply the RPL.
355 |
356 | 8.0 Disclaimer of Warranty. LICENSED SOFTWARE IS PROVIDED UNDER THIS LICENSE
357 | ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
358 | INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE LICENSED SOFTWARE IS FREE
359 | OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
360 | FURTHER THERE IS NO WARRANTY MADE AND ALL IMPLIED WARRANTIES ARE DISCLAIMED
361 | THAT THE LICENSED SOFTWARE MEETS OR COMPLIES WITH ANY DESCRIPTION OF
362 | PERFORMANCE OR OPERATION, SAID COMPATIBILITY AND SUITABILITY BEING YOUR
363 | RESPONSIBILITY. LICENSOR DISCLAIMS ANY WARRANTY, IMPLIED OR EXPRESSED, THAT
364 | ANY CONTRIBUTOR'S EXTENSIONS MEET ANY STANDARD OF COMPATIBILITY OR DESCRIPTION
365 | OF PERFORMANCE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
366 | LICENSED SOFTWARE IS WITH YOU. SHOULD LICENSED SOFTWARE PROVE DEFECTIVE IN ANY
367 | RESPECT, YOU (AND NOT THE LICENSOR OR ANY OTHER CONTRIBUTOR) ASSUME THE COST
368 | OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. UNDER THE TERMS OF THIS
369 | LICENSOR WILL NOT SUPPORT THIS SOFTWARE AND IS UNDER NO OBLIGATION TO ISSUE
370 | UPDATES TO THIS SOFTWARE. LICENSOR HAS NO KNOWLEDGE OF ERRANT CODE OR VIRUS IN
371 | THIS SOFTWARE, BUT DOES NOT WARRANT THAT THE SOFTWARE IS FREE FROM SUCH ERRORS
372 | OR VIRUSES. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
373 | LICENSE. NO USE OF LICENSED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
374 | DISCLAIMER.
375 |
376 | 9.0 Limitation of Liability. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY,
377 | WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE
378 | LICENSOR, ANY CONTRIBUTOR, OR ANY DISTRIBUTOR OF LICENSED SOFTWARE, OR ANY
379 | SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT,
380 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING,
381 | WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER
382 | FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES,
383 | EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH
384 | DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH
385 | OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT
386 | APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
387 | EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS
388 | EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
389 |
390 | 10.0 High Risk Activities. THE LICENSED SOFTWARE IS NOT FAULT-TOLERANT AND IS
391 | NOT DESIGNED, MANUFACTURED, OR INTENDED FOR USE OR DISTRIBUTION AS ON-LINE
392 | CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE PERFORMANCE,
393 | SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT NAVIGATION OR
394 | COMMUNICATIONS SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE SUPPORT MACHINES, OR
395 | WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE LICENSED SOFTWARE COULD LEAD
396 | DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE
397 | ("HIGH RISK ACTIVITIES"). LICENSOR AND CONTRIBUTORS SPECIFICALLY DISCLAIM ANY
398 | EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
399 |
400 | 11.0 Responsibility for Claims. As between Licensor and Contributors, each
401 | party is responsible for claims and damages arising, directly or indirectly,
402 | out of its utilization of rights under this License which specifically
403 | disclaims warranties and limits any liability of the Licensor. This paragraph
404 | is to be used in conjunction with and controlled by the Disclaimer Of
405 | Warranties of Section 8, the Limitation Of Damages in Section 9, and the
406 | disclaimer against use for High Risk Activities in Section 10. The Licensor
407 | has thereby disclaimed all warranties and limited any damages that it is or
408 | may be liable for. You agree to work with Licensor and Contributors to
409 | distribute such responsibility on an equitable basis consistent with the terms
410 | of this License including Sections 8, 9, and 10. Nothing herein is intended or
411 | shall be deemed to constitute any admission of liability.
412 |
413 | 12.0 Termination. This License and all rights granted hereunder will terminate
414 | immediately in the event of the circumstances described in Section 13.6 or if
415 | applicable law prohibits or restricts You from fully and or specifically
416 | complying with Sections 3, 4 and/or 6, or prevents the enforceability of any
417 | of those Sections, and You must immediately discontinue any use of Licensed
418 | Software.
419 |
420 | 12.1 Automatic Termination Upon Breach. This License and the rights granted
421 | hereunder will terminate automatically if You fail to comply with the terms
422 | herein and fail to cure such breach within thirty (30) days of becoming aware
423 | of the breach. All sublicenses to the Licensed Software that are properly
424 | granted shall survive any termination of this License. Provisions that, by
425 | their nature, must remain in effect beyond the termination of this License,
426 | shall survive.
427 |
428 | 12.2 Termination Upon Assertion of Patent Infringement. If You initiate
429 | litigation by asserting a patent infringement claim (excluding declaratory
430 | judgment actions) against Licensor or a Contributor (Licensor or Contributor
431 | against whom You file such an action is referred to herein as "Respondent")
432 | alleging that Licensed Software directly or indirectly infringes any patent,
433 | then any and all rights granted by such Respondent to You under Sections 3 or
434 | 4 of this License shall terminate prospectively upon sixty (60) days notice
435 | from Respondent (the "Notice Period") unless within that Notice Period You
436 | either agree in writing (i) to pay Respondent a mutually agreeable reasonably
437 | royalty for Your past or future use of Licensed Software made by such
438 | Respondent, or (ii) withdraw Your litigation claim with respect to Licensed
439 | Software against such Respondent. If within said Notice Period a reasonable
440 | royalty and payment arrangement are not mutually agreed upon in writing by the
441 | parties or the litigation claim is not withdrawn, the rights granted by
442 | Licensor to You under Sections 3 and 4 automatically terminate at the
443 | expiration of said Notice Period.
444 |
445 | 12.3 Reasonable Value of This License. If You assert a patent infringement
446 | claim against Respondent alleging that Licensed Software directly or
447 | indirectly infringes any patent where such claim is resolved (such as by
448 | license or settlement) prior to the initiation of patent infringement
449 | litigation, then the reasonable value of the licenses granted by said
450 | Respondent under Sections 3 and 4 shall be taken into account in determining
451 | the amount or value of any payment or license.
452 |
453 | 12.4 No Retroactive Effect of Termination. In the event of termination under
454 | this Section all end user license agreements (excluding licenses to
455 | distributors and resellers) that have been validly granted by You or any
456 | distributor hereunder prior to termination shall survive termination.
457 |
458 | 13.0 Miscellaneous.
459 |
460 | 13.1 U.S. Government End Users. The Licensed Software is a "commercial item,"
461 | as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of
462 | "commercial computer software" and "commercial computer software
463 | documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995).
464 | Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4
465 | (June 1995), all U.S. Government End Users acquire Licensed Software with only
466 | those rights set forth herein.
467 |
468 | 13.2 Relationship of Parties. This License will not be construed as creating
469 | an agency, partnership, joint venture, or any other form of legal association
470 | between or among You, Licensor, or any Contributor, and You will not represent
471 | to the contrary, whether expressly, by implication, appearance, or otherwise.
472 |
473 | 13.3 Independent Development. Nothing in this License will impair Licensor's
474 | right to acquire, license, develop, subcontract, market, or distribute
475 | technology or products that perform the same or similar functions as, or
476 | otherwise compete with, Extensions that You may develop, produce, market, or
477 | distribute.
478 |
479 | 13.4 Consent To Breach Not Waiver. Failure by Licensor or Contributor to
480 | enforce any provision of this License will not be deemed a waiver of future enforcement
481 | of that or any other provision.
482 |
483 | 13.5 Severability. This License represents the complete agreement concerning
484 | the subject matter hereof. If any provision of this License is held to be
485 | unenforceable, such provision shall be reformed only to the extent necessary
486 | to make it enforceable.
487 |
488 | 13.6 Inability to Comply Due to Statute or Regulation. If it is impossible for
489 | You to comply with any of the terms of this License with respect to some or
490 | all of the Licensed Software due to statute, judicial order, or regulation,
491 | then You cannot use, modify, or distribute the software.
492 |
493 | 13.7 Export Restrictions. You may be restricted with respect to downloading or
494 | otherwise acquiring, exporting, or reexporting the Licensed Software or any
495 | underlying information or technology by United States and other applicable
496 | laws and regulations. By downloading or by otherwise obtaining the Licensed
497 | Software, You are agreeing to be responsible for compliance with all
498 | applicable laws and regulations.
499 |
500 | 13.8 Arbitration, Jurisdiction & Venue. This License shall be governed by
501 | Colorado law provisions (except to the extent applicable law, if any, provides
502 | otherwise), excluding its conflict-of-law provisions. You expressly agree that
503 | any dispute relating to this License shall be submitted to binding arbitration
504 | under the rules then prevailing of the American Arbitration Association. You
505 | further agree that Adams County, Colorado USA is proper venue and grant such
506 | arbitration proceeding jurisdiction as may be appropriate for purposes of
507 | resolving any dispute under this License. Judgement upon any award made in
508 | arbitration may be entered and enforced in any court of competent
509 | jurisdiction. The arbitrator shall award attorney's fees and costs of
510 | arbitration to the prevailing party. Should either party find it necessary to
511 | enforce its arbitration award or seek specific performance of such award in a
512 | civil court of competent jurisdiction, the prevailing party shall be entitled
513 | to reasonable attorney's fees and costs. The application of the United Nations
514 | Convention on Contracts for the International Sale of Goods is expressly
515 | excluded. You and Licensor expressly waive any rights to a jury trial in any
516 | litigation concerning Licensed Software or this License. Any law or regulation
517 | that provides that the language of a contract shall be construed against the
518 | drafter shall not apply to this License.
519 |
520 | 13.9 Entire Agreement. This License constitutes the entire agreement between
521 | the parties with respect to the subject matter hereof.
522 |
523 | EXHIBIT A
524 |
525 | The License Notice below must appear in each file of the Source Code of any
526 | copy You distribute of the Licensed Software or any Extensions thereto:
527 |
528 | Unless explicitly acquired and licensed from Licensor under another
529 | license, the contents of this file are subject to the Reciprocal Public
530 | License ("RPL") Version 1.5, or subsequent versions as allowed by the RPL,
531 | and You may not copy or use this file in either source code or executable
532 | form, except in compliance with the terms and conditions of the RPL.
533 |
534 | All software distributed under the RPL is provided strictly on an "AS
535 | IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND
536 | LICENSOR HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
537 | LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
538 | PURPOSE, QUIET ENJOYMENT, OR NON-INFRINGEMENT. See the RPL for specific
539 | language governing rights and limitations under the RPL.
540 |
541 |
542 |
543 | EXHIBIT B
544 |
545 | The User-Visible Attribution Notice below, when provided, must appear in each
546 | user-visible display as defined in Section 6.4 (d):
547 |
--------------------------------------------------------------------------------
/solutions/Riscure solution/Solution path diagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Keysight/RHme-2015/2c9da0207683170bfaf78cdb9827c5712c0b36ae/solutions/Riscure solution/Solution path diagram.png
--------------------------------------------------------------------------------
/solutions/Riscure solution/writeup.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Keysight/RHme-2015/2c9da0207683170bfaf78cdb9827c5712c0b36ae/solutions/Riscure solution/writeup.txt
--------------------------------------------------------------------------------
/solutions/winners solutions/Riscure's comments to the winners solutions.txt:
--------------------------------------------------------------------------------
1 | ================================ TEAM R@BBIT ================================
2 |
3 |
4 | This is a perfect example of how difficult can be to properly protect your embedded system. Team Rabbit found a bug not introduced on purpose in the firmware. Exploiting this bug allowed them to find the encryption keys in a much easier and faster way that what we originally planned. Bravo for Team Rabbit! You really hacked us!
5 |
6 | All their write-up describes the expected attacks on the hardware but the following was completely unexpected:
7 |
8 | "After some experimentation, it was found that the memory dump contains the user key if the serial connection is closed immediately after login in as administrator.Next step was to find a delay for closing the connection that would deliver the administrator key. Just testing by hand (about 5 minutes) gave a delay of 0.01 seconds."
9 |
10 | During the login process, the three keys are being loaded to verify the different users. What Team Rabbit found is that if you reset the board in the correct moment, the RAM will contain one of the keys and you can use the vulnerability that dumps part of the memory content to get the key. By playing with the timing and resetting the chip in the correct moment, you can get the three keys.
11 |
12 | We already considered the possibility that somebody could dump the RAM and get the encryption key, so in order to prevent it the keys are stored in flash and only loaded into RAM when needed. Once the encryption is done, the key is cleared from RAM to prevent a leak:
13 |
14 | // Read key from flash
15 | for (i = 0; i < 16; i++)
16 | ram_aes_key[i] = pgm_read_byte(key + i);
17 |
18 | // Encrypt
19 | aes128_init(ram_aes_key, &aes_ctx);
20 | aes128_enc(aes_data, &aes_ctx, countermeasures);
21 |
22 | // Clear the key in RAM
23 | for (i = 0; i < 16; i++)
24 | ram_aes_key[i] = 0;
25 |
26 | However, we did not realize that the open source crypto library we used was making its own copy of the key in the RAM and that copy was not being cleared after using it:
27 |
28 | void aes_init(const void *key, uint16_t keysize_b, aes_genctx_t *ctx)
29 | {
30 | ...
31 | memcpy(ctx, key, keysize_b / 8);
32 | ...
33 | }
34 |
35 | Even if that copy of the key is cleared after using it, there is still a small windows of time between loading the key and clearing it were the attacker can reset the chip. The key would still be in RAM and the attacker could dump it.
36 |
37 | The lesson learned is clear: always initialize/clear all your variables and buffers immediately after a reset.
38 |
39 |
40 |
41 |
42 |
43 |
44 | ========================= STARE TEAM @ CISCO SPVSS ==========================
45 |
46 | The write-up sent by the STARE team is the complete solution for the challenge. They found and exploited all the vulnerabilities we introduced (on purpose) in the code. They even succeeded in using an EM glitch to dump the keys. There is not too much to add to their write up except "GOOD JOB TEAM STARE!".
47 |
48 | Team STARE enjoyed so much the RHme challenge that they talked about it in the BSides Knoxville 2016:
49 |
50 | http://bsidesknoxville2016.sched.org/event/6tCk/how-we-pwned-riscures-rhme-challenge-in-two-days
51 |
52 | Thanks STARE team! We are glad you enjoyed the challenge and we will see you in the RHme 2016.
--------------------------------------------------------------------------------
/solutions/winners solutions/STARE @ Cisco SPVSS/writeup.md:
--------------------------------------------------------------------------------
1 | Riscure RHme+ Challenge Writeup
2 | ===============================
3 |
4 |
5 |
6 | About Us
7 | --------
8 |
9 | We are a team within Cisco that routinely deals with reverse engineering
10 | tasks, mainly of embedded systems. The team itself deals mostly with
11 | software, but we are "embedded" in a group that does the same for
12 | hardware, and the two teams (HW and SW) often work jointly on various
13 | projects. When time off of "real" projects permits, we try to particpate
14 | in various challenges, CTFs, etc., in order to further our training. So
15 | when the opportunity arose to particpate in this challenge, we were
16 | happy to be able to spare the time for it.
17 |
18 | The bulk of the work on this challenge was done in a two-day period last
19 | week, by 6 members of the software team, and with support from 2 members
20 | of the hardware team. A few individuals started working on certain
21 | aspects of the challenge prior to this two-day period -- one, because he
22 | was not able to attend during the joint effort; another, the team
23 | leader, in order to evaluate how to divide up the team efforts during
24 | the 2-day sprint; and one who spent a few hours getting acquainted with
25 | the AVR instruction set and IDA's handling of it. All of the inputs from
26 | those efforts were fed into the main efforts during the 2-day sprint.
27 |
28 | We thank Riscure for setting up this challenge, and for providing us
29 | with the necessary boards. We enjoyed the challenge a lot, and are happy
30 | to present our results.
31 |
32 | Communicating with the board
33 | ----------------------------
34 |
35 | We connected the mini USB connector to the PC and noticed that the baud
36 | rate for the UART is not any of the standard options. In order to
37 | determine the correct baud rate, we connected a scope to the TX pin of
38 | the Arduino and measured the time for a single bit to be transmitted.
39 | The measured time was 1 microsecond, which implies a baud rate of
40 | 1000000. Indeed, setting that baud rate enabled us to communicate with
41 | the board.
42 |
43 | Disabling Random
44 | ----------------
45 |
46 | The first problem we are presented with is a randomly changing nonce. We
47 | looked at the hardware datasheet for the CPU, and noticed that it does
48 | not have any hardware RNG. Thus, we assumed that its random source must
49 | be one of the analog pins. We connected each of the analog pins to GND,
50 | and found that A1 was the random source -- once A1 and GND were
51 | connected, we were consistently presented with the constant nonce
52 | `0xe7212f7d`.
53 |
54 | Logging In as User
55 | ------------------
56 |
57 | Exploring the menus available on the terminal, the 'V' command
58 | ("retrieve variables"), which is available even before logging in,
59 | seemed interesting. Since it asked for a number between 0--5, we
60 | naturally tried some out-of-range numbers. Inserting -1 gave a dump of
61 | the RAM.
62 |
63 | The dump did not prove that useful as long as no authentication attempt
64 | had been made. However, a dump produced ''after'' an authentication
65 | attempt proved, upon inspection, to contain (immediately after the
66 | regular variables) the expected authentication response. This response
67 | can then be used for logging in as the normal user. (The correct
68 | response for the non-random nonce `0xe7212f7d` is `063b4c`.)
69 |
70 | Timing Attack
71 | -------------
72 |
73 | We assumed the verification of the challenge response would be
74 | susceptible to a timing attack, since the CPU is only 8-bit and a
75 | typical check will check each byte one-at-a-time. We wrote a short
76 | python script to time the responses we got from the device while trying
77 | all possible byte values. For the constant nonce obtained by disabling
78 | the random, we found 3 valid responses:
79 |
80 | 1. User: `063b4c`
81 | 2. Privileged User: `798068`
82 | 3. Administrator: `498451d5`
83 |
84 | Dumping the Flash
85 | -----------------
86 |
87 | By sending random inputs to the "read flash config" menu option, we
88 | managed to produce what appeared to be dumps of portions of the flash.
89 | Further exploration showed us that the values at positions 21 and 22 in
90 | the input control the offset in the flash at which the dump begins. The
91 | dump ends when a 0x00 byte is encountered. Using this information, we
92 | implemented a simple script which dumps the entire contents of the flash
93 | using this functionality.
94 |
95 | However, the dump proved useful only up to address 0x3500 in the flash.
96 | Beyond that, it was clear from the responses that our read attempts were
97 | somehow failing. Thus, we realized that we were still missing part of
98 | the flash.
99 |
100 | Static Analysis of the Flash
101 | ----------------------------
102 |
103 | We used IDA Pro to statically analyze the binary obtained by dumping the
104 | flash.
105 |
106 | ### IDA Pro & AVR
107 |
108 | It appears that IDA's support for the AVR instruction set is not as
109 | developed as its support of more common architectures such as x86 and
110 | ARM. One of the more annoying issues is that although IDA automatically
111 | annotates the meaning of various values and memory xrefs, it does so
112 | only for immediate values that are directly used for accessing memory or
113 | I/O ports. However, indirect accesses (e.g., loading values into
114 | registers, then accessing memory using those registers) are not
115 | annotated. So we wrote an IDA Python script that identifies consecutive
116 | loads of two bytes into paired registers (AVR registers are 8-bit
117 | registers, but addresses are 16-bits; so pairs of registers --r24:r25,
118 | for example -- are used in tandem for accessing memory locations) and
119 | adds a comment with a hyperlink to the relevant address (in both RAM and
120 | ROM, as the address spaces overlap, and it is not always possible to
121 | know upfront which is being accessed), as well as the text of the string
122 | beginning at that address, if that is the case.
123 |
124 | This greatly eased the subsequent analysis of the binary.
125 |
126 | ### Analyzing the Flash
127 |
128 | Once acquainted with the AVR instruction set and IDA's quirks in
129 | analyzing it, we were able to very quickly locate the main command loop,
130 | which led us to the authentication function. By reverse engineering this
131 | function we determined the keys of the normal and privileged users, and
132 | we learned that the admin key was stored at location 0x3500 in the
133 | flash. Unfortunately, as explained above, our dump ended at exactly that
134 | address.
135 |
136 | - Normal User Key:
137 |
138 | Riscure is cool!
139 |
140 | - Privileged User Key:
141 |
142 | Getting closer!!
143 |
144 | We reverse engineered the "read flash config" function, which had been
145 | used to dump the flash, and noted that there is a check to see if the
146 | upper byte of the area being dumped is 0x35. If so, the actual flash
147 | contents are not returned. We also learned that this check was gated by
148 | a value in the EEPROM: if the byte at offset 0x26 in the EEPROM is 1,
149 | the read is blocked; for any other value, the read would proceed as
150 | normal, enabling memory addresses beyond 0x3500 to be dumped as well.
151 |
152 | Debug UART
153 | ----------
154 |
155 | During the static analysis of the binary, we noted that strings were
156 | being passed to a function that looks similar to `printf`, and which
157 | outputs to the UART. This function does a `sprintf` to a buffer and then
158 | bit-bangs the results over a pin in PORTB. We attached an FTDI cable to
159 | the appropriate output pin (D8) in order to read this debug info.
160 |
161 | Stack Buffer Overflow Exploit
162 | -----------------------------
163 |
164 | While further exploring the menus, we noted what appeared to be a stack
165 | buffer overflow in the "Send command to backend ICS network" menu
166 | functionality. This functionality requests an "instruction length" from
167 | the user, then an "instruction opcode", and then prints "the inserted
168 | command was" followed by the actual input ("opcode") provided by the
169 | user. By interactively playing around with these inputs, as well as
170 | statically analyzing the related code, we learned that in fact there
171 | were two buffer overflows here:
172 |
173 | 1. A read overflow: the ultimate output ("the inserted command was") is
174 | of length "instruction length" provided by the user; thus, by
175 | providing a length longer than the actual "opcode", we get a glimpse
176 | of the memory beyond the command buffer -- presumably, the stack;
177 | 2. A write overflow: by inserting a command longer than the capacity of
178 | the stack buffer into which it is placed, we can overwrite portions
179 | of the stack.
180 |
181 | Combining these two overflows should allow us to construct a payload
182 | that will overwrite the return address stored on the stack, thus gaining
183 | control over the program counter.
184 |
185 | ### Stack Canary
186 |
187 | Confirmation that indeed a stack buffer overflow was occurring was
188 | provided by printouts to that effect made to the Debug UART discovered
189 | earlier. However, the fact that the overflows are being detected implies
190 | a detection method --which presumably could also prevent any code
191 | execution. And indeed, the static analysis showed that a stack canary is
192 | used in this function to detect buffer overflows. However, in this case
193 | the canary consists of single-byte constant value ('0xc8'), so it is not
194 | difficult to overcome.
195 |
196 | ### No Execution from RAM
197 |
198 | The AVR is not capable of running code from RAM, but only from flash.
199 | This means that we cannot provide our own code to be executed, but
200 | rather we must find existing code that will be useful to us to run.
201 | Luckily, such a function had already been found: Besides the
202 | `eeprom_set_memory_protected` function, which is called every time the
203 | board boots up, before entering the main command loop, we also found a
204 | function `eeprom_set_memory_unprotected`, which exists in the code, but
205 | it is never called. This function simply writes 0 to offset 0x26 in the
206 | EEPROM (which, recall, would allow flash beyond address 0x3500 to be
207 | dumped).
208 |
209 | ### Constructing the Exploit
210 |
211 | By combining all of the above information, we are able to craft our
212 | exploit payload:
213 |
214 | - we need to bypass the stack canary;
215 | - we need to replace the return address with the address of
216 | `eeprom_set_memory_unprotected` (0xbca);
217 | - after that function is executed, we need to continue running as
218 | normal, in order to enable us to dump the flash again; so we need to
219 | call the main command loop (at 0xd01).
220 |
221 | This leads to the following exploit payload:
222 |
223 | c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c80bca0d01
224 |
225 | Now that the memory is unprotected, dumping the flash beyond 0x3500
226 | becomes possible, using the "read flash config" functionality described
227 | above. We dumped the flash, and thus the admin key was retrieved:
228 |
229 | RHme+ C0n7ac7_u5
230 |
231 | Dumping the EEPROM (just for kicks)
232 | -----------------------------------
233 |
234 | Using the code execution described above, we decided to try to read the
235 | entire contents of the EEPROM. This requires a ROP chain, since, as
236 | explained above, we must make do with code already existing in flash, as
237 | we cannot execute from RAM, and cannot write to flash.
238 |
239 | The gadgets we used were:
240 |
241 | Address Gadget
242 | --------- -----------------------------
243 | 0x0434 r25:r24 = 0; pop Y
244 | 0x048d r24 = uart\_recv\_byte()
245 | 0x1573 r24 = eeprom\_read(r25:r24)
246 | 0x0474 uart\_send\_byte(r24)
247 | 0x1787 r25:r24 += 1
248 |
249 | This is the crafted payload:
250 |
251 | payload = 'c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8c8'
252 | payload += '0434' # r25:r24 = 0; pop Y
253 | payload += '0000' # -- dummy. ## This value will be popped in to Y
254 | payload += '048d' # r24 = uart_recv_byte() ## Read the low eeprom address from the serial port
255 | payload += '1573' # r24 = eeprom_read(r25:r24) ## Read an eeprom byte from the address that came in from the serial port
256 | payload += '0474' # uart_set_byte(r24) ## Send the eeprom byte read, to the serial port
257 |
258 | The above payload dumps a single value from the EEPROM, from the offset
259 | provided over the UART. This was used in a loop to dump offsets
260 | 0x00-0xFF.
261 |
262 | However, since only a single byte "offset" is read from the UART, we
263 | cannot access offsets beyond 0xFF. So in order to dump the 0x100 - 0x3FF
264 | range, we needed to set r25 to 1,2 or 3. This was achieved by inserting
265 | the following payload after zeroing r25:r24:
266 |
267 | payload += '1578' # r24 = uart_recv_byte() ## We will send FF. so r24 = 0xFF
268 | payload += '1787' # r25:r24 += 1 ## Now r25 = 0x01
269 |
270 | Inserting the above payload N times will set r25 = N
271 |
272 | As expected, we found that EEPROM offset 0x26 contained `0x01`. All
273 | other offsets had the value `0xFF`, except for offset 0x9e, where the
274 | value `0xa8` was observed. We do not know whether this is intentional,
275 | or perhaps was written somehow by accident during our experiments.
276 | However, we found no use being made of it (or any other offset other
277 | than 0x26) by the flashed binary.
278 |
279 | EM Glitch
280 | ---------
281 |
282 | Having obtained the key using software-only techniques, we decided to
283 | also attempt some hardware attacks.
284 |
285 | Since only the value 0x1 obtained from offset 0x26 in the EEPROM will
286 | block reads beyond 0x3500, and any other value will allow such reads, we
287 | surmised that another way of gaining access to the flash contents at
288 | 0x3500 would be to cause a glitch that would corrupt that value as it
289 | was read from the EEPROM. In order to determine the exact point in time
290 | at which to cause the glitch, we compared the power consumption of the
291 | device when asked to get address 0x3400 and address 0x3500. By noting
292 | the difference between the two traces, we were able to determine the
293 | exact time at which to effect the EM glitch. After a few attempts, we
294 | succeeded in reading the flash contents at 0x3500:
295 |
296 | 00000000: 52 48 6D 65 2B 20 43 30 6E 37 61 63 37 5F 75 35 RHme+ C0n7ac7_u5
297 | 00000010: 0D 0A 43 61 6C 63 75 6C 61 74 69 6E 67 20 69 6E ..Calculating in
298 | 00000020: 64 65 78 dex
299 |
300 | Differential Power Analysis
301 | ---------------------------
302 |
303 | Another thought was to use DPA to discover the AES key. However,
304 | standard DPA methods on the first/last round of AES can reveal only the
305 | first 4 bytes of the first/last round key. Therefore, we did not use
306 | such techniques.
307 |
308 | More sophisticated attacks on internal rounds where not considered due
309 | to timing limitations.
310 |
311 | Similarly, Differential Fault Attack on the 8th and 9th round were also
312 | not considered.
313 |
314 | Reading Flash / EEPROM with Atmel Programmer
315 | --------------------------------------------
316 |
317 | We connected the Atmel ISP programmer to the board. When we tried to
318 | read the flash we got all FF's. This is consistent with the reported
319 | state of the fuses -- namely, they were set to not allow the program to
320 | be read. We tried reading in High Voltage Mode, but did not succeed.
321 |
322 |
--------------------------------------------------------------------------------
/solutions/winners solutions/Team R@bbit/hack.py:
--------------------------------------------------------------------------------
1 | #This script contains the hacks to recover the riscure challenge
2 | #Usage:
3 | #Install pyserial and pycrypto
4 | #modify the serial initialisation line to connect to the challenge
5 | #>> execfile("hack.py")
6 | #>> hackAccounts()
7 | #>> findAEAkeys()
8 | #>> login(Nonce) -> gives the responses for user, admin and privileged user
9 |
10 | import serial
11 | import sys
12 | import time
13 | from Crypto.Cipher import AES
14 |
15 | ser = serial.Serial("COM31", 1000000, timeout=2) #Initialize serial at 1 MBaud
16 |
17 | output = ser.read(195) #Read initial response
18 |
19 | def hackAccounts(bytepos = 0x00, offset = 0x00):
20 | timeouts = [190, 240, 290, 340] #Set timeout values for different byte positions
21 | getNonce()
22 | for i in range(0xff):
23 | if (i%0xfd == 0): #Get new nonce after 0xfd tries
24 | getNonce()
25 | response = "R%0.8x\r\n"%((i<<(8*bytepos)) + offset) #Write response into string
26 | ser.write(response)
27 | output=ser.read(2) #Read cr+lf
28 | starttime = time.time()
29 | output = ser.read(1) #Read answer (is 'E' when response is invalid)
30 | endtime = time.time()
31 | totaltime = (endtime - starttime) *1000 #The time in millis that it took between cr+lf and the final answer from the module
32 | if (output != 'E'):
33 | output = output + ser.read(1000)
34 | #print response[:-2] + " %d"%totaltime
35 | print "Found valid response: " + response[:-2]
36 | print output
37 | ser.write("X\r\n") #Logout
38 | ser.read(1000) #Read response
39 | break
40 | if (totaltime > timeouts[bytepos]): #Found next byte
41 | #print response[:-2] + " %d"%totaltime
42 | hackAccounts(bytepos + 1, ((i<<(8*bytepos)) + offset)) #Recurse into guessing the next byte
43 |
44 | def findAESkeys():
45 | timings = [0, 0.01, 0.5] #at these timings we find the different keys
46 | for timing in timings:
47 | loginTimingAttack(timing)
48 |
49 | def loginTimingAttack(t = 1):
50 | ser.close()
51 | ser.open()
52 | ser.read(195)
53 | getNonce()
54 | ser.write("R498451d5\r\n")
55 | time.sleep(t) #wait t seconds
56 | ser.close() #reset the chip
57 | ser.open()
58 | ser.read(195)
59 | ser.write('V\r\n') #dump memory
60 | out = ser.read(49)
61 | ser.write("-1\r\n")
62 | dump = ser.read(1000000)
63 | ser.close()
64 | testdump(dump) #check for valid keys in the memory
65 |
66 | def testdump(dump):
67 | message = "\xe7\x21\x2f\x7d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
68 | dumplen = (len(dump)-16 + 1)
69 | for i in range(dumplen):
70 | key = dump[i:i + 16]
71 | if (encryptTest(message, key) == 1):
72 | print
73 | break
74 |
75 | def encryptTest(message, key):
76 | obj = AES.new(key, AES.MODE_ECB)
77 | ciphertext = obj.encrypt(message)
78 | if (ciphertext[-2:] == "\x3b\x4c"):
79 | print "User key: \"%s\""%key
80 | print "Hex user key: " + ''.join("{:02x}".format(ord(c)) for c in key)
81 | return 1
82 | if (ciphertext[-3:] == "\x79\x80\x68"):
83 | print "Privileged user key: \"%s\""%key
84 | print "Hex privileged key: " + ''.join("{:02x}".format(ord(c)) for c in key)
85 | return 1
86 | if (ciphertext[-4:] == "\x49\x84\x51\xd5"):
87 | print "Admin key: \"%s\""%key
88 | print "Hex admin key: " + ''.join("{:02x}".format(ord(c)) for c in key)
89 | return 1
90 | return 0
91 |
92 | def getNonce():
93 | ser.write("A\r\n")
94 | ser.read(92)
95 |
96 | def login(nonce):
97 | keys= ["Riscure is cool!", "RHme+ C0n7ac7_u5", "Getting closer!!"]
98 | nonce = nonce + "000000000000000000000000"
99 | message = nonce.decode('hex')
100 | for key in keys:
101 | obj = AES.new(key, AES.MODE_ECB)
102 | ciphertext = obj.encrypt(message)
103 | print key + " : " + ''.join("{:02x}".format(ord(c)) for c in ciphertext[-4:])
104 |
105 |
--------------------------------------------------------------------------------
/solutions/winners solutions/Team R@bbit/setup.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Keysight/RHme-2015/2c9da0207683170bfaf78cdb9827c5712c0b36ae/solutions/winners solutions/Team R@bbit/setup.jpg
--------------------------------------------------------------------------------
/solutions/winners solutions/Team R@bbit/writeup.txt:
--------------------------------------------------------------------------------
1 | ***** 1. Find the right baudrate *****
2 | Used a Saleae 8 logic analyser and measured the baudrate required
3 | Connection speed: 1M baud
4 |
5 | Build an arduino to connect to the riscure challenge. To convert between 1Mbaud. My OSX couldn't communicate at 1M baud with the challenge.
6 | Later I found out that the Windows driver supports 1M baud (after adding baudrate to CoolTerm), so I could communicate directly (using Windows).
7 |
8 | ***** 2. Hack random number generator *****
9 | Connect pin A1 to ground
10 | Nonce is always: e7212f7d
11 |
12 | ***** 3. Brute force user response *****
13 | Just tried every combination. Used another Arduino to do this, because I didn't have 1M baud yet.
14 | Found: R00063b4c for the user response
15 |
16 | ***** 4. Timing attack per byte *****
17 | Found out with logic analyser that a timing attack is possible by measuring the time between "\r\n" and "E". The time to respond to a response.
18 | If the least significant byte matches, the response time increases. After that we tried the second least significant byte, until we get a valid login response.
19 | Wrote a python script to find all the valid responses.
20 | Output:
21 | - Found valid response: R00063b4c
22 | Authentication successful as user
23 | - Found valid response: R00798068
24 | Authentication successful as privileged user
25 | - Found valid response: R498451d5
26 | Authentication successful as administrator
27 |
28 | ***** 5. Fuzzing input *****
29 | Invalid input, delivers some kind of memory dump
30 | From the main menu use V (show variables), number of variables "-1" gives some kind of dump.
31 | This dump also contains the user response: User authentication token 63b4c
32 |
33 | Also insert command "S" option delivers some kind of dump with invalid input, such as a very high number for the command length
34 |
35 | Also read flash config delivers some kind of dump when number of characters entered is 21
36 |
37 | ***** 6. Scan memory dump for keys *****
38 | Simply shifting a 16 byte window over the dump and using the 16 bytes as the key to encrypt the known nonce from the hacked RNG. If the encrypted nonce matches the responses found with the known responses we have found the key.
39 |
40 | After login in as administrator, the "V"-dump revealed the key for the privileged user: "Getting closer!!"
41 |
42 | After some experimentation, it was found that the memory dump contains the user key if the serial connection is closed immediately after login in as administrator.
43 |
44 | Next step was to find a delay for closing the connection that would deliver the administrator key. Just testing by hand (about 5 minutes) gave a delay of 0.01 seconds.
45 |
46 | Results and final flag:
47 | User key: "Riscure is cool!"
48 | Hex user key: 5269736375726520697320636f6f6c21
49 |
50 | Admin key: "RHme+ C0n7ac7_u5"
51 | Hex admin key: 52486d652b2043306e376163375f7535
52 |
53 | Privileged user key: "Getting closer!!"
54 | Hex privileged key: 47657474696e6720636c6f7365722121
55 |
56 | ***** 7. Failed attempts *****
57 | - Connecting the challenge to the ICSP header via JTAG ICE II. Tried reading the flash and eeprom.
58 | - Debugging via the ICSP header.
59 | - Measuring all the pins with logic analyser, to see if some data comes out on pins
60 | - Shuffling the bits in the 16 byte memory window to test for keys (reverse bytes, reverse bits, reverse nibbles and combinations)
61 | - Even more input fuzzing
62 |
--------------------------------------------------------------------------------
/source/aes/README:
--------------------------------------------------------------------------------
1 | This is an implementation from
2 | https://git.cryptolib.org/avr-crypto-lib.git
3 | with the exact required sources for each version of aes listed at
4 | http://avrcryptolib.das-labor.org/trac/wiki/AES
5 |
6 | The second link also includes a small tutorial :)
7 |
--------------------------------------------------------------------------------
/source/aes/aes.h:
--------------------------------------------------------------------------------
1 | /* aes.h */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 aes.h
21 | * \email bg@nerilex.org
22 | * \author Daniel Otte
23 | * \date 2008-12-30
24 | * \license GPLv3 or later
25 | *
26 | */
27 | #ifndef AES_H_
28 | #define AES_H_
29 |
30 | #include
31 |
32 | #include "aes_types.h"
33 | #include "aes128_enc.h"
34 | #include "aes128_dec.h"
35 | #include "aes_enc.h"
36 | #include "aes_dec.h"
37 | #include "aes_keyschedule.h"
38 |
39 | #endif
40 |
--------------------------------------------------------------------------------
/source/aes/aes128_dec.c:
--------------------------------------------------------------------------------
1 | /* aes128_dec.c */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 aes128_dec.c
21 | * \email bg@nerilex.org
22 | * \author Daniel Otte
23 | * \date 2008-12-30
24 | * \license GPLv3 or later
25 | *
26 | */
27 |
28 | #include "aes.h"
29 | #include "aes_dec.h"
30 |
31 | void aes128_dec(void *buffer, aes128_ctx_t *ctx){
32 | aes_decrypt_core(buffer, (aes_genctx_t*)ctx, 10);
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/source/aes/aes128_dec.h:
--------------------------------------------------------------------------------
1 | /* aes128_dec.h */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 aes128_dec.h
21 | * \email bg@nerilex.org
22 | * \author Daniel Otte
23 | * \date 2008-12-30
24 | * \license GPLv3 or later
25 | * \ingroup AES
26 | */
27 |
28 | #ifndef AES128_DEC_H_
29 | #define AES128_DEC_H_
30 |
31 | #include "aes_types.h"
32 | #include "aes_dec.h"
33 |
34 | /**
35 | * \brief decrypt with 128 bit key.
36 | *
37 | * This function decrypts one block with the AES algorithm under control of
38 | * a keyschedule produced from a 128 bit key.
39 | * \param buffer pointer to the block to decrypt
40 | * \param ctx pointer to the key schedule
41 | */
42 | void aes128_dec(void *buffer, aes128_ctx_t *ctx);
43 |
44 |
45 |
46 | #endif /* AES128_DEC_H_ */
47 |
--------------------------------------------------------------------------------
/source/aes/aes128_enc.c:
--------------------------------------------------------------------------------
1 | /* aes128_enc.c */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 aes128_enc.c
21 | * \email bg@nerilex.org
22 | * \author Daniel Otte
23 | * \date 2008-12-30
24 | * \license GPLv3 or later
25 | *
26 | */
27 |
28 | #include "aes.h"
29 | #include "aes_enc.h"
30 |
31 | void aes128_enc(void *buffer, aes128_ctx_t *ctx, uint8_t countermeasures)
32 | {
33 | aes_encrypt_core(buffer, (aes_genctx_t*) ctx, 10, countermeasures);
34 | }
35 |
36 |
--------------------------------------------------------------------------------
/source/aes/aes128_enc.h:
--------------------------------------------------------------------------------
1 | /* aes128_enc.h */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 aes128_enc.h
21 | * \email bg@nerilex.org
22 | * \author Daniel Otte
23 | * \date 2008-12-30
24 | * \license GPLv3 or later
25 | * \ingroup AES
26 | */
27 |
28 | #ifndef AES128_ENC_H_
29 | #define AES128_ENC_H_
30 |
31 | #include "aes_types.h"
32 | #include "aes_enc.h"
33 |
34 | /**
35 | * \brief encrypt with 128 bit key.
36 | *
37 | * This function encrypts one block with the AES algorithm under control of
38 | * a keyschedule produced from a 128 bit key.
39 | * \param buffer pointer to the block to encrypt
40 | * \param ctx pointer to the key schedule
41 | */
42 | void aes128_enc(void *buffer, aes128_ctx_t *ctx, uint8_t countermeasures);
43 |
44 | #endif /* AES128_ENC_H_ */
45 |
--------------------------------------------------------------------------------
/source/aes/aes_dec.c:
--------------------------------------------------------------------------------
1 | /* aes.c */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 | #include
21 | #include
22 | #include "gf256mul.h"
23 | #include "aes.h"
24 | #include "aes_invsbox.h"
25 | #include "aes_dec.h"
26 | #include
27 |
28 | void aes_invshiftrow(void *data, uint8_t shift){
29 | uint8_t tmp[4];
30 | tmp[0] = ((uint8_t*)data)[(4+0-shift)&3];
31 | tmp[1] = ((uint8_t*)data)[(4+1-shift)&3];
32 | tmp[2] = ((uint8_t*)data)[(4+2-shift)&3];
33 | tmp[3] = ((uint8_t*)data)[(4+3-shift)&3];
34 | memcpy(data, tmp, 4);
35 | }
36 |
37 | void aes_invshiftcol(void *data, uint8_t shift){
38 | uint8_t tmp[4];
39 | tmp[0] = ((uint8_t*)data)[ 0];
40 | tmp[1] = ((uint8_t*)data)[ 4];
41 | tmp[2] = ((uint8_t*)data)[ 8];
42 | tmp[3] = ((uint8_t*)data)[12];
43 | ((uint8_t*)data)[ 0] = tmp[(4-shift+0)&3];
44 | ((uint8_t*)data)[ 4] = tmp[(4-shift+1)&3];
45 | ((uint8_t*)data)[ 8] = tmp[(4-shift+2)&3];
46 | ((uint8_t*)data)[12] = tmp[(4-shift+3)&3];
47 | }
48 | static
49 | void aes_dec_round(aes_cipher_state_t *state, const aes_roundkey_t *k){
50 | uint8_t tmp[16];
51 | uint8_t i;
52 | uint8_t t,u,v,w;
53 | /* keyAdd */
54 | for(i=0; i<16; ++i){
55 | tmp[i] = state->s[i] ^ k->ks[i];
56 | }
57 | /* mixColums */
58 | for(i=0; i<4; ++i){
59 | t = tmp[4*i+3] ^ tmp[4*i+2];
60 | u = tmp[4*i+1] ^ tmp[4*i+0];
61 | v = t ^ u;
62 | v = gf256mul(0x09, v, 0x1b);
63 | w = v ^ gf256mul(0x04, tmp[4*i+2] ^ tmp[4*i+0], 0x1b);
64 | v = v ^ gf256mul(0x04, tmp[4*i+3] ^ tmp[4*i+1], 0x1b);
65 | state->s[4*i+3] = tmp[4*i+3] ^ v ^ gf256mul(0x02, tmp[4*i+0] ^ tmp[4*i+3], 0x1b);
66 | state->s[4*i+2] = tmp[4*i+2] ^ w ^ gf256mul(0x02, t, 0x1b);
67 | state->s[4*i+1] = tmp[4*i+1] ^ v ^ gf256mul(0x02, tmp[4*i+2] ^ tmp[4*i+1], 0x1b);
68 | state->s[4*i+0] = tmp[4*i+0] ^ w ^ gf256mul(0x02, u, 0x1b);
69 |
70 | /*
71 | state->s[4*i+0] =
72 | gf256mul(0xe, tmp[4*i+0], 0x1b)
73 | ^ gf256mul(0xb, tmp[4*i+1], 0x1b)
74 | ^ gf256mul(0xd, tmp[4*i+2], 0x1b)
75 | ^ gf256mul(0x9, tmp[4*i+3], 0x1b);
76 | state->s[4*i+1] =
77 | gf256mul(0x9, tmp[4*i+0], 0x1b)
78 | ^ gf256mul(0xe, tmp[4*i+1], 0x1b)
79 | ^ gf256mul(0xb, tmp[4*i+2], 0x1b)
80 | ^ gf256mul(0xd, tmp[4*i+3], 0x1b);
81 | state->s[4*i+2] =
82 | gf256mul(0xd, tmp[4*i+0], 0x1b)
83 | ^ gf256mul(0x9, tmp[4*i+1], 0x1b)
84 | ^ gf256mul(0xe, tmp[4*i+2], 0x1b)
85 | ^ gf256mul(0xb, tmp[4*i+3], 0x1b);
86 | state->s[4*i+3] =
87 | gf256mul(0xb, tmp[4*i+0], 0x1b)
88 | ^ gf256mul(0xd, tmp[4*i+1], 0x1b)
89 | ^ gf256mul(0x9, tmp[4*i+2], 0x1b)
90 | ^ gf256mul(0xe, tmp[4*i+3], 0x1b);
91 | */
92 | }
93 | /* shiftRows */
94 | aes_invshiftcol(state->s+1, 1);
95 | aes_invshiftcol(state->s+2, 2);
96 | aes_invshiftcol(state->s+3, 3);
97 | /* subBytes */
98 | for(i=0; i<16; ++i){
99 | state->s[i] = pgm_read_byte(aes_invsbox+state->s[i]);
100 | }
101 | }
102 |
103 |
104 | static
105 | void aes_dec_firstround(aes_cipher_state_t *state, const aes_roundkey_t *k){
106 | uint8_t i;
107 | /* keyAdd */
108 | for(i=0; i<16; ++i){
109 | state->s[i] ^= k->ks[i];
110 | }
111 | /* shiftRows */
112 | aes_invshiftcol(state->s+1, 1);
113 | aes_invshiftcol(state->s+2, 2);
114 | aes_invshiftcol(state->s+3, 3);
115 | /* subBytes */
116 | for(i=0; i<16; ++i){
117 | state->s[i] = pgm_read_byte(aes_invsbox+state->s[i]);
118 | }
119 | }
120 |
121 | void aes_decrypt_core(aes_cipher_state_t *state, const aes_genctx_t *ks, uint8_t rounds){
122 | uint8_t i;
123 | aes_dec_firstround(state, &(ks->key[i=rounds]));
124 | for(;rounds>1;--rounds){
125 | --i;
126 | aes_dec_round(state, &(ks->key[i]));
127 | }
128 | for(i=0; i<16; ++i){
129 | state->s[i] ^= ks->key[0].ks[i];
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/source/aes/aes_dec.h:
--------------------------------------------------------------------------------
1 | /* aes_dec.h */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 aes_dec.h
21 | * \email bg@nerilex.org
22 | * \author Daniel Otte
23 | * \date 2008-12-30
24 | * \license GPLv3 or later
25 | *
26 | */
27 | #ifndef AES_DEC_H_
28 | #define AES_DEC_H_
29 | #include "aes_types.h"
30 | #include
31 |
32 |
33 | void aes_decrypt_core(aes_cipher_state_t *state,const aes_genctx_t *ks, uint8_t rounds);
34 |
35 |
36 | #endif
37 |
--------------------------------------------------------------------------------
/source/aes/aes_enc.c:
--------------------------------------------------------------------------------
1 | /* aes_enc.c */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 aes_enc.c
21 | * \email bg@nerilex.org
22 | * \author Daniel Otte
23 | * \date 2008-12-30
24 | * \license GPLv3 or later
25 | *
26 | */
27 |
28 | #include
29 | #include
30 | #include
31 | #include "aes.h"
32 | #include "gf256mul.h"
33 | #include "aes_sbox.h"
34 | #include "aes_enc.h"
35 | #include
36 |
37 |
38 |
39 | void aes_shiftcol(void *data, uint8_t shift)
40 | {
41 | uint8_t tmp[4];
42 | tmp[0] = ((uint8_t*) data)[0];
43 | tmp[1] = ((uint8_t*) data)[4];
44 | tmp[2] = ((uint8_t*) data)[8];
45 | tmp[3] = ((uint8_t*) data)[12];
46 | ((uint8_t*) data)[0] = tmp[(shift + 0) & 3];
47 | ((uint8_t*) data)[4] = tmp[(shift + 1) & 3];
48 | ((uint8_t*) data)[8] = tmp[(shift + 2) & 3];
49 | ((uint8_t*) data)[12] = tmp[(shift + 3) & 3];
50 | }
51 |
52 | #define GF256MUL_1(a) (a)
53 | #define GF256MUL_2(a) (gf256mul(2, (a), 0x1b))
54 | #define GF256MUL_3(a) (gf256mul(3, (a), 0x1b))
55 |
56 | static
57 | void aes_enc_round(aes_cipher_state_t *state, const aes_roundkey_t *k, uint8_t countermeasures)
58 | {
59 | uint8_t tmp[16], t;
60 | uint8_t i;
61 |
62 | volatile uint16_t loop;
63 |
64 | /* subBytes */
65 | for (i = 0; i < 16; ++i) {
66 | tmp[i] = pgm_read_byte(aes_sbox + state->s[i]);
67 | }
68 | /* shiftRows */
69 | aes_shiftcol(tmp + 1, 1);
70 | aes_shiftcol(tmp + 2, 2);
71 | aes_shiftcol(tmp + 3, 3);
72 | /* mixColums */
73 | for (i = 0; i < 4; ++i) {
74 | t = tmp[4 * i + 0] ^ tmp[4 * i + 1] ^ tmp[4 * i + 2] ^ tmp[4 * i + 3];
75 |
76 |
77 | if (countermeasures == 1) {
78 | for (loop = random() & 0x00003FF; loop>0; loop--) {
79 |
80 | }
81 | }
82 |
83 | state->s[4 * i + 0] =
84 | GF256MUL_2(tmp[4*i+0]^tmp[4*i+1])
85 | ^ tmp[4 * i + 0]
86 | ^ t;
87 |
88 | state->s[4 * i + 1] =
89 | GF256MUL_2(tmp[4*i+1]^tmp[4*i+2])
90 | ^ tmp[4 * i + 1]
91 | ^ t;
92 |
93 | if (countermeasures == 1) {
94 | for (loop = random() & 0x00003FF; loop>0; loop--) {
95 |
96 | }
97 | }
98 |
99 | state->s[4 * i + 2] =
100 | GF256MUL_2(tmp[4*i+2]^tmp[4*i+3])
101 | ^ tmp[4 * i + 2]
102 | ^ t;
103 | state->s[4 * i + 3] =
104 | GF256MUL_2(tmp[4*i+3]^tmp[4*i+0])
105 | ^ tmp[4 * i + 3]
106 | ^ t;
107 | }
108 |
109 | /* addKey */
110 | for (i = 0; i < 16; ++i) {
111 | state->s[i] ^= k->ks[i];
112 | }
113 | }
114 |
115 | static
116 | void aes_enc_lastround(aes_cipher_state_t *state, const aes_roundkey_t *k)
117 | {
118 | uint8_t i;
119 | /* subBytes */
120 | for (i = 0; i < 16; ++i) {
121 | state->s[i] = pgm_read_byte(aes_sbox + state->s[i]);
122 | }
123 | /* shiftRows */
124 | aes_shiftcol(state->s + 1, 1);
125 | aes_shiftcol(state->s + 2, 2);
126 | aes_shiftcol(state->s + 3, 3);
127 | /* keyAdd */
128 | for (i = 0; i < 16; ++i) {
129 | state->s[i] ^= k->ks[i];
130 | }
131 | }
132 |
133 | void aes_encrypt_core(aes_cipher_state_t *state, const aes_genctx_t *ks,
134 | uint8_t rounds, uint8_t countermeasures)
135 | {
136 | uint8_t i;
137 | for (i = 0; i < 16; ++i) {
138 | state->s[i] ^= ks->key[0].ks[i];
139 | }
140 | i = 1;
141 | for (; rounds > 1; --rounds) {
142 | aes_enc_round(state, &(ks->key[i]), countermeasures);
143 | ++i;
144 | }
145 | aes_enc_lastround(state, &(ks->key[i]));
146 | }
147 |
--------------------------------------------------------------------------------
/source/aes/aes_enc.h:
--------------------------------------------------------------------------------
1 | /* aes_enc.h */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 aes_enc.h
21 | * \email bg@nerilex.org
22 | * \author Daniel Otte
23 | * \date 2008-12-30
24 | * \license GPLv3 or later
25 | *
26 | */
27 | #ifndef AES_ENC_H_
28 | #define AES_ENC_H_
29 | #include "aes_types.h"
30 | #include
31 |
32 | void aes_encrypt_core(aes_cipher_state_t *state, const aes_genctx_t *ks,
33 | uint8_t rounds, uint8_t countermeasures);
34 |
35 | #endif
36 |
--------------------------------------------------------------------------------
/source/aes/aes_invsbox.c:
--------------------------------------------------------------------------------
1 | /* aes inverted sbox */
2 |
3 | #include
4 | #include
5 | const uint8_t aes_invsbox[256] PROGMEM = {
6 | 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e,
7 | 0x81, 0xf3, 0xd7, 0xfb,
8 | 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44,
9 | 0xc4, 0xde, 0xe9, 0xcb,
10 | 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b,
11 | 0x42, 0xfa, 0xc3, 0x4e,
12 | 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49,
13 | 0x6d, 0x8b, 0xd1, 0x25,
14 | 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc,
15 | 0x5d, 0x65, 0xb6, 0x92,
16 | 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57,
17 | 0xa7, 0x8d, 0x9d, 0x84,
18 | 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05,
19 | 0xb8, 0xb3, 0x45, 0x06,
20 | 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03,
21 | 0x01, 0x13, 0x8a, 0x6b,
22 | 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce,
23 | 0xf0, 0xb4, 0xe6, 0x73,
24 | 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8,
25 | 0x1c, 0x75, 0xdf, 0x6e,
26 | 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e,
27 | 0xaa, 0x18, 0xbe, 0x1b,
28 | 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe,
29 | 0x78, 0xcd, 0x5a, 0xf4,
30 | 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59,
31 | 0x27, 0x80, 0xec, 0x5f,
32 | 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f,
33 | 0x93, 0xc9, 0x9c, 0xef,
34 | 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c,
35 | 0x83, 0x53, 0x99, 0x61,
36 | 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63,
37 | 0x55, 0x21, 0x0c, 0x7d
38 | };
39 |
--------------------------------------------------------------------------------
/source/aes/aes_invsbox.h:
--------------------------------------------------------------------------------
1 | /* aes_invsbox.h */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 aes_invsbox.h
21 | * \email bg@nerilex.org
22 | * \author Daniel Otte
23 | * \date 2008-12-30
24 | * \license GPLv3 or later
25 | *
26 | */
27 | #ifndef AES_INVSBOX_H_
28 | #define AES_INVSBOX_H_
29 | #include
30 |
31 | extern uint8_t aes_invsbox[];
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/source/aes/aes_keyschedule.c:
--------------------------------------------------------------------------------
1 | /* aes_keyschedule.c */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 aes_keyschedule.c
21 | * \email bg@nerilex.org
22 | * \author Daniel Otte
23 | * \date 2008-12-30
24 | * \license GPLv3 or later
25 | *
26 | */
27 |
28 | #include
29 | #include "aes.h"
30 | #include "aes_keyschedule.h"
31 | #include "aes_sbox.h"
32 | #include
33 | #include
34 |
35 | static
36 | void aes_rotword(void *a)
37 | {
38 | uint8_t t;
39 | t = ((uint8_t*) a)[0];
40 | ((uint8_t*) a)[0] = ((uint8_t*) a)[1];
41 | ((uint8_t*) a)[1] = ((uint8_t*) a)[2];
42 | ((uint8_t*) a)[2] = ((uint8_t*) a)[3];
43 | ((uint8_t*) a)[3] = t;
44 | }
45 |
46 | const uint8_t rc_tab[] PROGMEM = { 0x01, 0x02, 0x04, 0x08,
47 | 0x10, 0x20, 0x40, 0x80,
48 | 0x1b, 0x36 };
49 |
50 | void aes_init(const void *key, uint16_t keysize_b, aes_genctx_t *ctx)
51 | {
52 | uint8_t hi, i, nk, next_nk;
53 | uint8_t rc = 0;
54 | union {
55 | uint32_t v32;
56 | uint8_t v8[4];
57 | } tmp;
58 | nk = keysize_b >> 5; /* 4, 6, 8 */
59 | hi = 4 * (nk + 6 + 1);
60 | memcpy(ctx, key, keysize_b / 8);
61 | next_nk = nk;
62 | for (i = nk; i < hi; ++i) {
63 | tmp.v32 = ((uint32_t*) (ctx->key[0].ks))[i - 1];
64 | if (i != next_nk) {
65 | if (nk == 8 && i % 8 == 4) {
66 | tmp.v8[0] = pgm_read_byte(aes_sbox + tmp.v8[0]);
67 | tmp.v8[1] = pgm_read_byte(aes_sbox + tmp.v8[1]);
68 | tmp.v8[2] = pgm_read_byte(aes_sbox + tmp.v8[2]);
69 | tmp.v8[3] = pgm_read_byte(aes_sbox + tmp.v8[3]);
70 | }
71 | } else {
72 | next_nk += nk;
73 | aes_rotword(&(tmp.v32));
74 | tmp.v8[0] = pgm_read_byte(aes_sbox + tmp.v8[0]);
75 | tmp.v8[1] = pgm_read_byte(aes_sbox + tmp.v8[1]);
76 | tmp.v8[2] = pgm_read_byte(aes_sbox + tmp.v8[2]);
77 | tmp.v8[3] = pgm_read_byte(aes_sbox + tmp.v8[3]);
78 | tmp.v8[0] ^= pgm_read_byte(rc_tab + rc);
79 | rc++;
80 | }
81 | ((uint32_t*) (ctx->key[0].ks))[i] = ((uint32_t*) (ctx->key[0].ks))[i
82 | - nk]
83 | ^ tmp.v32;
84 | }
85 | }
86 |
87 | void aes128_init(const void *key, aes128_ctx_t *ctx)
88 | {
89 | aes_init(key, 128, (aes_genctx_t*) ctx);
90 | }
91 |
92 | void aes192_init(const void *key, aes192_ctx_t *ctx)
93 | {
94 | aes_init(key, 192, (aes_genctx_t*) ctx);
95 | }
96 |
97 | void aes256_init(const void *key, aes256_ctx_t *ctx)
98 | {
99 | aes_init(key, 256, (aes_genctx_t*) ctx);
100 | }
101 |
--------------------------------------------------------------------------------
/source/aes/aes_keyschedule.h:
--------------------------------------------------------------------------------
1 | /* aes_keyschedule.h */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 aes_keyschedule.h
21 | * \email bg@nerilex.org
22 | * \author Daniel Otte
23 | * \date 2008-12-30
24 | * \license GPLv3 or later
25 | * \ingroup AES
26 | */
27 |
28 | #ifndef AES_KEYSCHEDULE_H_
29 | #define AES_KEYSCHEDULE_H_
30 |
31 | #include "aes_types.h"
32 | /**
33 | * \brief initialize the keyschedule
34 | *
35 | * This function computes the keyschedule from a given key with a given length
36 | * and stores it in the context variable
37 | * \param key pointer to the key material
38 | * \param keysize_b length of the key in bits (valid are 128, 192 and 256)
39 | * \param ctx pointer to the context where the keyschedule should be stored
40 | */
41 | void aes_init(const void *key, uint16_t keysize_b, aes_genctx_t *ctx);
42 |
43 | /**
44 | * \brief initialize the keyschedule for 128 bit key
45 | *
46 | * This function computes the keyschedule from a given 128 bit key
47 | * and stores it in the context variable
48 | * \param key pointer to the key material
49 | * \param ctx pointer to the context where the keyschedule should be stored
50 | */
51 | void aes128_init(const void *key, aes128_ctx_t *ctx);
52 |
53 | /**
54 | * \brief initialize the keyschedule for 192 bit key
55 | *
56 | * This function computes the keyschedule from a given 192 bit key
57 | * and stores it in the context variable
58 | * \param key pointer to the key material
59 | * \param ctx pointer to the context where the keyschedule should be stored
60 | */
61 | void aes192_init(const void *key, aes192_ctx_t *ctx);
62 |
63 | /**
64 | * \brief initialize the keyschedule for 256 bit key
65 | *
66 | * This function computes the keyschedule from a given 256 bit key
67 | * and stores it in the context variable
68 | * \param key pointer to the key material
69 | * \param ctx pointer to the context where the keyschedule should be stored
70 | */
71 | void aes256_init(const void *key, aes256_ctx_t *ctx);
72 |
73 | #endif /* AES_KEYSCHEDULE_H_ */
74 |
75 |
--------------------------------------------------------------------------------
/source/aes/aes_sbox.c:
--------------------------------------------------------------------------------
1 | /* aes sbox */
2 |
3 | #include
4 | #include
5 | const uint8_t aes_sbox[256] PROGMEM = {
6 | 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
7 | 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
8 | 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
9 | 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
10 | 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
11 | 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
12 | 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
13 | 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
14 | 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
15 | 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
16 | 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
17 | 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
18 | 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
19 | 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
20 | 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
21 | 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
22 | };
23 |
24 |
--------------------------------------------------------------------------------
/source/aes/aes_sbox.h:
--------------------------------------------------------------------------------
1 | /* aes_sbox.h */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 aes_sbox.h
21 | * \email bg@nerilex.org
22 | * \author Daniel Otte
23 | * \date 2008-12-30
24 | * \license GPLv3 or later
25 | *
26 | */
27 | #ifndef AES_SBOX_H_
28 | #define AES_SBOX_H_
29 | #include
30 |
31 | extern uint8_t aes_sbox[];
32 |
33 | #endif
34 |
--------------------------------------------------------------------------------
/source/aes/aes_types.h:
--------------------------------------------------------------------------------
1 | /* aes.h */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 aes_types.h
21 | * \email bg@nerilex.org
22 | * \author Daniel Otte
23 | * \date 2008-12-30
24 | * \license GPLv3 or later
25 | *
26 | */
27 | #ifndef AES_TYPES_H_
28 | #define AES_TYPES_H_
29 |
30 | #include
31 |
32 | typedef struct{
33 | uint8_t ks[16];
34 | } aes_roundkey_t;
35 |
36 | typedef struct{
37 | aes_roundkey_t key[10+1];
38 | } aes128_ctx_t;
39 |
40 | typedef struct{
41 | aes_roundkey_t key[12+1];
42 | } aes192_ctx_t;
43 |
44 | typedef struct{
45 | aes_roundkey_t key[14+1];
46 | } aes256_ctx_t;
47 |
48 | typedef struct{
49 | aes_roundkey_t key[1]; /* just to avoid the warning */
50 | } aes_genctx_t;
51 |
52 | typedef struct{
53 | uint8_t s[16];
54 | } aes_cipher_state_t;
55 |
56 | #endif
57 |
--------------------------------------------------------------------------------
/source/aes/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | set -euo pipefail
4 |
5 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c aes128_dec.c
6 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c aes128_enc.c
7 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c aes_dec.c
8 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c aes_enc.c
9 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c aes_invsbox.c
10 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c aes_keyschedule.c
11 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c aes_sbox.c
12 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c gf256mul.S
13 |
14 | echo "$(pwd)/aes128_dec.o $(pwd)/aes128_enc.o $(pwd)/aes_dec.o $(pwd)/aes_enc.o $(pwd)/aes_invsbox.o $(pwd)/aes_keyschedule.o $(pwd)/aes_sbox.o $(pwd)/gf256mul.o"
15 |
--------------------------------------------------------------------------------
/source/aes/gf256mul.S:
--------------------------------------------------------------------------------
1 | /* gf256mul.S */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 | /*
21 | * File: gf256mul.S
22 | * Author: Daniel Otte
23 | * Date: 2008-12-19
24 | * License: GPLv3 or later
25 | * Description: peasant's algorithm for multiplication in GF(2^8)
26 | *
27 | */
28 |
29 | #include
30 | #define OPTIMIZE_SMALL_A
31 |
32 | /*
33 | * param a: r24
34 | * param b: r22
35 | * param reducer: r20
36 | */
37 | A = 23
38 | B = 22
39 | P = 24
40 | .global gf256mul
41 |
42 | #ifdef OPTIMIZE_SMALL_A
43 | gf256mul:
44 | mov A, r24
45 | clr r24
46 | 1:
47 | lsr A
48 | breq 4f
49 | brcc 2f
50 | eor P, B
51 | 2:
52 | lsl B
53 | brcc 3f
54 | eor B, r20
55 | 3:
56 | rjmp 1b
57 | 4:
58 | brcc 2f
59 | eor P, B
60 | 2:
61 | ret
62 |
63 | #else
64 |
65 | /*
66 |
67 | uint8_t gf256mul(uint8_t a, uint8_t b, uint8_t p) {
68 | uint8_t r = 0, c = 8;
69 | do {
70 | if (a & 1) {
71 | r ^= b;
72 | }
73 | a >>= 1;
74 | if (b & 0x80) {
75 | b ^= p;
76 | }
77 | b <<= 1;
78 | } while (--c);
79 | return r;
80 | }
81 |
82 | */
83 | gf256mul:
84 | mov A, r24
85 | clr r24
86 | ldi r25, 8
87 | 1:
88 | lsr A
89 | brcc 2f
90 | eor P, B
91 | 2:
92 | lsl B
93 | brcc 3f
94 | eor B, r20
95 | 3:
96 | dec r25
97 | brne 1b
98 | ret
99 |
100 | #endif
101 |
--------------------------------------------------------------------------------
/source/aes/gf256mul.h:
--------------------------------------------------------------------------------
1 | /* gf256mul.h */
2 | /*
3 | This file is part of the AVR-Crypto-Lib.
4 | Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
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 | #ifndef GF256MUL_H_
20 | #define GF256MUL_H_
21 |
22 | /**
23 | * \author Daniel Otte
24 | * \email bg@nerilex.org
25 | * \date 2008-12-19
26 | * \license GPLv3
27 | * \brief
28 | *
29 | *
30 | */
31 |
32 | #include
33 |
34 | uint8_t gf256mul(uint8_t a, uint8_t b, uint8_t reducer);
35 |
36 | #endif /* GF256MUL_H_ */
37 |
38 |
--------------------------------------------------------------------------------
/source/auth/auth.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "auth.h"
8 | #include "serial_io.h"
9 | #include "random.h"
10 | #include "aes.h"
11 |
12 | uint8_t is_authenticated;
13 | uint8_t is_privileged;
14 | uint8_t is_administrator;
15 | uint8_t is_auth_nonce_valid;
16 | uint8_t k_attempts;
17 | uint32_t auth_nonce;
18 | extern char user_auth_response[9];
19 |
20 | const uint8_t flash_aes_key_User[] PROGMEM =
21 | { 'R','i','s','c','u','r','e',' ','i','s',' ','c','o','o','l','!'};
22 |
23 | const uint8_t flash_aes_key_Privileged[] PROGMEM =
24 | { 'G','e','t','t','i','n','g',' ','c','l','o','s','e','r','!','!'};
25 |
26 | const uint8_t flash_aes_key_Admin[] __attribute__((section(".flagsection"))) =
27 | { 'R','H','m','e','+',' ','C','0','n','7','a','c','7','_','u','5'};
28 |
29 | extern char *inbuff; // declared and initialized in main.c
30 |
31 | static void uint32_to_uint8_array(uint32_t, uint8_t *);
32 | static void uint32_to_uint8_array_bigEndian(uint32_t, uint8_t *);
33 | static uint32_t uint8_array_to_uint32_bigEndian(uint8_t *);
34 | static uint8_t timing_vulnerable_verification(uint32_t, uint8_t);
35 | static void calculate_response(uint32_t, uint32_t *, uint8_t user, uint8_t calculate_response);
36 |
37 | void generate_challenge(void) {
38 | uint32_t responses[3];
39 |
40 | is_auth_nonce_valid = 1;
41 | k_attempts = 0;
42 |
43 | auth_nonce = get_random_uint32_t();
44 | calculate_response(auth_nonce, &responses[0], USER_USER,0);
45 | calculate_response(auth_nonce, &responses[1], USER_ADMIN,1);
46 | calculate_response(auth_nonce, &responses[2], USER_PRIVILEGED,0);
47 | snprintf(user_auth_response, 9, "%lx", responses[0]);
48 |
49 | serial_printf("Your nonce is %08lx\r\n", auth_nonce);
50 | serial_printf("%S", PSTR("Please submit your response to finish the authentication process\r\n"));
51 | DEBUG_PRINT("DEVDEBUG: valid responses are %08lx %08lx %08lx\r\n", responses[0], responses[1], responses[2]);
52 | DEBUG_PRINT("DEVDEBUG: auth priv adm %d %d %d\r\n", is_authenticated, is_privileged, is_administrator);
53 | }
54 |
55 | void verify_response(void) {
56 | uint32_t user_input;
57 | uint8_t i;
58 |
59 | if (is_auth_nonce_valid == 1) {
60 | user_input = strtoul(inbuff + 1, NULL, 16);
61 | DEBUG_PRINT("DEBUG: input was %lx\r\n", user_input);
62 |
63 | // commence glitch chaining
64 | for (i = 0; i < 3; i++) {
65 | if( timing_vulnerable_verification(user_input, i) == 1 ) { // glitch 1
66 | is_authenticated = 1;
67 | if (i == USER_USER) { // glitch 2
68 | serial_printf("%S", PSTR("Authentication successful as user\r\n"));
69 | } else if (i == USER_PRIVILEGED) { // glitch 2
70 | serial_printf("%S", PSTR("Authentication successful as privileged user\r\n"));
71 | is_privileged = 1;
72 | } else {
73 | serial_printf("%S", PSTR("Authentication successful as administrator\r\n"));
74 | is_administrator = 1;
75 | }
76 | }
77 | }
78 |
79 | if (is_authenticated == 0) { // another glitch here, maybe useful if no RNG manipulation and no glitching above
80 | k_attempts++;
81 | if ( k_attempts == 255) {
82 | is_auth_nonce_valid = 0;
83 | serial_printf("%S", PSTR("Your nonce is now invalid, please request a new one to perform authentication\r\n"));
84 | } else
85 | serial_printf("E");
86 | }
87 | } else {
88 | serial_printf("%S", PSTR("You have not requested an authentication nonce\r\n"));
89 | serial_printf("%S", PSTR("Please start the authentication process with that step\r\n"));
90 | }
91 | }
92 |
93 | static uint8_t timing_vulnerable_verification(uint32_t user_input, uint8_t idx_resp) {
94 | int i;
95 | uint32_t responses[3];
96 | uint8_t buff_resp[4], buff_input[4];
97 |
98 | i = 0;
99 | uint32_to_uint8_array(user_input, buff_input);
100 | do {
101 | calculate_response(auth_nonce, &responses[0], USER_USER, 0);
102 | calculate_response(auth_nonce, &responses[1], USER_ADMIN, 1);
103 | calculate_response(auth_nonce, &responses[2], USER_PRIVILEGED, 2);
104 | uint32_to_uint8_array( responses[idx_resp], buff_resp );
105 |
106 | if (buff_input[i] != buff_resp[i])
107 | return 0;
108 |
109 | i++;
110 | } while(i < 4);
111 |
112 | return 1;
113 | }
114 |
115 |
116 | static void calculate_response(uint32_t nonce, uint32_t *response, uint8_t user, uint8_t countermeasures) {
117 | uint8_t i;
118 | uint8_t aes_data[16], ram_aes_key[16];
119 | aes128_ctx_t aes_ctx;
120 | const uint8_t *key;
121 |
122 | if (user == USER_USER)
123 | key = flash_aes_key_User;
124 | else if (user == USER_PRIVILEGED)
125 | key = flash_aes_key_Privileged;
126 | else
127 | key = flash_aes_key_Admin;
128 |
129 | for (i = 0; i < 16; i++)
130 | ram_aes_key[i] = pgm_read_byte(key + i);
131 |
132 | uint32_to_uint8_array_bigEndian(nonce, aes_data);
133 | for (i = 4; i < 16; i++)
134 | aes_data[i] = 0;
135 |
136 | aes128_init(ram_aes_key, &aes_ctx);
137 | aes128_enc(aes_data, &aes_ctx, countermeasures);
138 |
139 | for (i = 0; i < 16; i++)
140 | ram_aes_key[i] = 0; // Cleaning the key.
141 |
142 | *response = uint8_array_to_uint32_bigEndian(&aes_data[12]);
143 |
144 | if (user == USER_USER)
145 | *response = *response & 0x000FFFFF;
146 | else if (user == USER_PRIVILEGED)
147 | *response = *response & 0x00FFFFFF;
148 | else
149 | *response = *response & 0xFFFFFFFF;
150 | }
151 |
152 | static void uint32_to_uint8_array(uint32_t n, uint8_t *buffer) {
153 | uint8_t *ptr;
154 | int i;
155 |
156 | ptr = (uint8_t *)&n;
157 | for (i = 3; i >= 0; i--)
158 | buffer[i] = ptr[i];
159 | }
160 |
161 | static void uint32_to_uint8_array_bigEndian(uint32_t n, uint8_t *buffer) {
162 | uint8_t *ptr;
163 | int i;
164 |
165 | ptr = (uint8_t *)&n;
166 | for (i = 3; i >= 0; i--)
167 | buffer[i] = *ptr++;
168 | }
169 |
170 | static uint32_t uint8_array_to_uint32_bigEndian(uint8_t *buffer) {
171 | uint32_t val;
172 | int8_t i;
173 |
174 | val = 0;
175 | for (i = 0; i <= 3; i++) {
176 | val <<= 8;
177 | val |= buffer[i];
178 | }
179 |
180 | return val;
181 | }
182 |
--------------------------------------------------------------------------------
/source/auth/auth.h:
--------------------------------------------------------------------------------
1 | #ifndef AUTH_H
2 | #define AUTH_H
3 |
4 | #define USER_ADMIN 1
5 | #define USER_USER 0
6 | #define USER_PRIVILEGED 2
7 |
8 | void generate_challenge(void);
9 | void verify_response(void);
10 |
11 | #endif
12 |
--------------------------------------------------------------------------------
/source/auth/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | set -euo pipefail
4 |
5 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c auth.c
6 |
7 | echo "$(pwd)/auth.o"
8 |
--------------------------------------------------------------------------------
/source/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | set -euo pipefail
4 |
5 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6 |
7 | #MMCU="atxmega64a3"
8 | #F_CPU="32000000UL"
9 | #export BOARD_FAMILY="ATX_MEGA"
10 |
11 | MMCU="atmega328p"
12 | F_CPU="16000000UL"
13 | EEPROM_CHECK_ADDR="38"
14 | export BOARD_FAMILY="AT_MEGA"
15 |
16 | PRBUFF_LEN=120
17 | INBUFF_LEN=20
18 | export GCC_OPTIMIZATION_FLAG="-Os"
19 | export GCC_COMPILE_FLAGS="-Wall -mmcu=$MMCU -DF_CPU=$F_CPU -D$BOARD_FAMILY -DPRBUFF_LEN=$PRBUFF_LEN -DINBUFF_LEN=$INBUFF_LEN -DEEPROM_CHECK_ADDR=$EEPROM_CHECK_ADDR -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -fno-exceptions -Wundef"
20 | export GCC_LINK_FLAGS="-Wl,--gc-sections"
21 | export OBJCOPY_IHEX_FLAGS="-j .text -j .data -O ihex"
22 | export OBJCOPY_BIN_FLAGS="-j .text -j .data -O binary"
23 | export DEPS=""
24 | export INC_PATH="-I $DIR"
25 |
26 | MODULES=(
27 | serial
28 | random
29 | aes
30 | variables
31 | auth
32 | obfuscated_asm
33 | overflow_rop
34 | eeprom_rw
35 | overflow_readflash
36 | menu
37 | main
38 | )
39 |
40 | for M in ${MODULES[@]}; do
41 | echo ""
42 | echo ">>> Building $M"
43 | MOD_DIR="$DIR/$M"
44 | cd $MOD_DIR
45 | export DEPS="$DEPS $(./build.sh)"
46 | export INC_PATH="$INC_PATH -I $MOD_DIR"
47 | done
48 |
49 | #cp $DIR/main/ctf.elf /vmshared
50 | #cp $DIR/main/ctf.hex /vmshared
51 |
--------------------------------------------------------------------------------
/source/check_board.py:
--------------------------------------------------------------------------------
1 | #! env python
2 |
3 | import sys
4 | import avr_serial
5 |
6 | ser = avr_serial.AVRSerial( sys.argv[1], verbose = False )
7 |
8 | ser.w('H')
9 | response = ser.r(100)
10 |
11 | if response:
12 | exit(0)
13 | else:
14 | exit(1)
15 |
--------------------------------------------------------------------------------
/source/eeprom_rw/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | set -euo pipefail
4 |
5 | GCC_OPTIMIZATION_FLAG="-O0"
6 |
7 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c eeprom_rw.c
8 |
9 | echo "$(pwd)/eeprom_rw.o"
10 |
--------------------------------------------------------------------------------
/source/eeprom_rw/eeprom_rw.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "serial_io.h"
6 |
7 | uint8_t eeprom_is_memory_protected(void) {
8 | return eeprom_read_byte((uint8_t *)EEPROM_CHECK_ADDR);
9 | }
10 |
11 | void eeprom_set_memory_protected(void) {
12 | serial_printf("%S", PSTR("Calling eeprom_set_memory_protected\r\n"));
13 | eeprom_write_byte((uint8_t *)EEPROM_CHECK_ADDR, 1);
14 | }
15 |
16 | void eeprom_set_memory_unprotected(void) {
17 | serial_printf("%S", PSTR("Calling eeprom_set_memory_unprotected\r\n"));
18 | eeprom_write_byte((uint8_t *)EEPROM_CHECK_ADDR, 0);
19 | }
20 |
--------------------------------------------------------------------------------
/source/eeprom_rw/eeprom_rw.h:
--------------------------------------------------------------------------------
1 | #ifndef EEPROM_RC_H
2 | #define EEPROM_RC_H
3 |
4 | uint8_t eeprom_is_memory_protected(void);
5 | void eeprom_set_memory_protected(void);
6 | void eeprom_set_memory_unprotected(void) __attribute__((section(".set_memory_unprotected")));
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/source/license.txt:
--------------------------------------------------------------------------------
1 | Reciprocal Public License (RPL-1.5)
2 |
3 | Version 1.5, July 15, 2007
4 |
5 | Copyright (C) 2001-2007
6 | Technical Pursuit Inc.,
7 | All Rights Reserved.
8 |
9 |
10 | PREAMBLE
11 |
12 | The Reciprocal Public License (RPL) is based on the concept of reciprocity or,
13 | if you prefer, fairness.
14 |
15 | In short, this license grew out of a desire to close loopholes in previous open
16 | source licenses, loopholes that allowed parties to acquire open source software
17 | and derive financial benefit from it without having to release their
18 | improvements or derivatives to the community which enabled them. This occurred
19 | any time an entity did not release their application to a "third party".
20 |
21 | While there is a certain freedom in this model of licensing, it struck the
22 | authors of the RPL as being unfair to the open source community at large and to
23 | the original authors of the works in particular. After all, bug fixes,
24 | extensions, and meaningful and valuable derivatives were not consistently
25 | finding their way back into the community where they could fuel further, and
26 | faster, growth and expansion of the overall open source software base.
27 |
28 | While you should clearly read and understand the entire license, the essence of
29 | the RPL is found in two definitions: "Deploy" and "Required Components".
30 |
31 | Regarding deployment, under the RPL your changes, bug fixes, extensions, etc.
32 | must be made available to the open source community at large when you Deploy in
33 | any form -- either internally or to an outside party. Once you start running
34 | the software you have to start sharing the software.
35 |
36 | Further, under the RPL all components you author including schemas, scripts,
37 | source code, etc. -- regardless of whether they're compiled into a single
38 | binary or used as two halves of client/server application -- must be shared.
39 | You have to share the whole pie, not an isolated slice of it.
40 |
41 | In addition to these goals, the RPL was authored to meet the requirements of
42 | the Open Source Definition as maintained by the Open Source Initiative (OSI).
43 |
44 | The specific terms and conditions of the license are defined in the remainder
45 | of this document.
46 |
47 |
48 | LICENSE TERMS
49 |
50 | 1.0 General; Applicability & Definitions. This Reciprocal Public License
51 | Version 1.5 ("License") applies to any programs or other works as well as any
52 | and all updates or maintenance releases of said programs or works ("Software")
53 | not already covered by this License which the Software copyright holder
54 | ("Licensor") makes available containing a License Notice (hereinafter defined)
55 | from the Licensor specifying or allowing use or distribution under the terms of
56 | this License. As used in this License:
57 |
58 | 1.1 "Contributor" means any person or entity who created or contributed to the
59 | creation of an Extension.
60 |
61 | 1.2 "Deploy" means to use, Serve, sublicense or distribute Licensed Software
62 | other than for Your internal Research and/or Personal Use, and includes
63 | without limitation, any and all internal use or distribution of Licensed
64 | Software within Your business or organization other than for Research and/or
65 | Personal Use, as well as direct or indirect sublicensing or distribution of
66 | Licensed Software by You to any third party in any form or manner.
67 |
68 | 1.3 "Derivative Works" as used in this License is defined under U.S. copyright
69 | law.
70 |
71 | 1.4 "Electronic Distribution Mechanism" means a mechanism generally accepted
72 | in the software development community for the electronic transfer of data such
73 | as download from an FTP server or web site, where such mechanism is publicly
74 | accessible.
75 |
76 | 1.5 "Extensions" means any Modifications, Derivative Works, or Required
77 | Components as those terms are defined in this License.
78 |
79 | 1.6 "License" means this Reciprocal Public License.
80 |
81 | 1.7 "License Notice" means any notice contained in EXHIBIT A.
82 |
83 | 1.8 "Licensed Software" means any Software licensed pursuant to this License.
84 | Licensed Software also includes all previous Extensions from any Contributor
85 | that You receive.
86 |
87 | 1.9 "Licensor" means the copyright holder of any Software previously not
88 | covered by this License who releases the Software under the terms of this
89 | License.
90 |
91 | 1.10 "Modifications" means any additions to or deletions from the substance or
92 | structure of (i) a file or other storage containing Licensed Software, or (ii)
93 | any new file or storage that contains any part of Licensed Software, or (iii)
94 | any file or storage which replaces or otherwise alters the original
95 | functionality of Licensed Software at runtime.
96 |
97 | 1.11 "Personal Use" means use of Licensed Software by an individual solely for
98 | his or her personal, private and non-commercial purposes. An individual's use
99 | of Licensed Software in his or her capacity as an officer, employee, member,
100 | independent contractor or agent of a corporation, business or organization
101 | (commercial or non-commercial) does not qualify as Personal Use.
102 |
103 | 1.12 "Required Components" means any text, programs, scripts, schema,
104 | interface definitions, control files, or other works created by You which are
105 | required by a third party of average skill to successfully install and run
106 | Licensed Software containing Your Modifications, or to install and run Your
107 | Derivative Works.
108 |
109 | 1.13 "Research" means investigation or experimentation for the purpose of
110 | understanding the nature and limits of the Licensed Software and its potential
111 | uses.
112 |
113 | 1.14 "Serve" means to deliver Licensed Software and/or Your Extensions by
114 | means of a computer network to one or more computers for purposes of execution
115 | of Licensed Software and/or Your Extensions.
116 |
117 | 1.15 "Software" means any computer programs or other works as well as any
118 | updates or maintenance releases of those programs or works which are
119 | distributed publicly by Licensor.
120 |
121 | 1.16 "Source Code" means the preferred form for making modifications to the
122 | Licensed Software and/or Your Extensions, including all modules contained
123 | therein, plus any associated text, interface definition files, scripts used to
124 | control compilation and installation of an executable program or other
125 | components required by a third party of average skill to build a running
126 | version of the Licensed Software or Your Extensions.
127 |
128 | 1.17 "User-Visible Attribution Notice" means any notice contained in EXHIBIT B.
129 |
130 | 1.18 "You" or "Your" means an individual or a legal entity exercising rights
131 | under this License. For legal entities, "You" or "Your" includes any entity
132 | which controls, is controlled by, or is under common control with, You, where
133 | "control" means (a) the power, direct or indirect, to cause the direction or
134 | management of such entity, whether by contract or otherwise, or (b) ownership
135 | of fifty percent (50%) or more of the outstanding shares or beneficial
136 | ownership of such entity.
137 |
138 | 2.0 Acceptance Of License. You are not required to accept this License since
139 | you have not signed it, however nothing else grants you permission to use,
140 | copy, distribute, modify, or create derivatives of either the Software or any
141 | Extensions created by a Contributor. These actions are prohibited by law if
142 | you do not accept this License. Therefore, by performing any of these actions
143 | You indicate Your acceptance of this License and Your agreement to be bound by
144 | all its terms and conditions. IF YOU DO NOT AGREE WITH ALL THE TERMS AND
145 | CONDITIONS OF THIS LICENSE DO NOT USE, MODIFY, CREATE DERIVATIVES, OR
146 | DISTRIBUTE THE SOFTWARE. IF IT IS IMPOSSIBLE FOR YOU TO COMPLY WITH ALL THE
147 | TERMS AND CONDITIONS OF THIS LICENSE THEN YOU CAN NOT USE, MODIFY, CREATE
148 | DERIVATIVES, OR DISTRIBUTE THE SOFTWARE.
149 |
150 | 3.0 Grant of License From Licensor. Subject to the terms and conditions of
151 | this License, Licensor hereby grants You a world-wide, royalty-free, non-
152 | exclusive license, subject to Licensor's intellectual property rights, and any
153 | third party intellectual property claims derived from the Licensed Software
154 | under this License, to do the following:
155 |
156 | 3.1 Use, reproduce, modify, display, perform, sublicense and distribute
157 | Licensed Software and Your Extensions in both Source Code form or as an
158 | executable program.
159 |
160 | 3.2 Create Derivative Works (as that term is defined under U.S. copyright law)
161 | of Licensed Software by adding to or deleting from the substance or structure
162 | of said Licensed Software.
163 |
164 | 3.3 Under claims of patents now or hereafter owned or controlled by Licensor,
165 | to make, use, have made, and/or otherwise dispose of Licensed Software or
166 | portions thereof, but solely to the extent that any such claim is necessary to
167 | enable You to make, use, have made, and/or otherwise dispose of Licensed
168 | Software or portions thereof.
169 |
170 | 3.4 Licensor reserves the right to release new versions of the Software with
171 | different features, specifications, capabilities, functions, licensing terms,
172 | general availability or other characteristics. Title, ownership rights, and
173 | intellectual property rights in and to the Licensed Software shall remain in
174 | Licensor and/or its Contributors.
175 |
176 | 4.0 Grant of License From Contributor. By application of the provisions in
177 | Section 6 below, each Contributor hereby grants You a world-wide, royalty-
178 | free, non-exclusive license, subject to said Contributor's intellectual
179 | property rights, and any third party intellectual property claims derived from
180 | the Licensed Software under this License, to do the following:
181 |
182 | 4.1 Use, reproduce, modify, display, perform, sublicense and distribute any
183 | Extensions Deployed by such Contributor or portions thereof, in both Source
184 | Code form or as an executable program, either on an unmodified basis or as
185 | part of Derivative Works.
186 |
187 | 4.2 Under claims of patents now or hereafter owned or controlled by
188 | Contributor, to make, use, have made, and/or otherwise dispose of Extensions
189 | or portions thereof, but solely to the extent that any such claim is necessary
190 | to enable You to make, use, have made, and/or otherwise dispose of
191 | Licensed Software or portions thereof.
192 |
193 | 5.0 Exclusions From License Grant. Nothing in this License shall be deemed to
194 | grant any rights to trademarks, copyrights, patents, trade secrets or any
195 | other intellectual property of Licensor or any Contributor except as expressly
196 | stated herein. Except as expressly stated in Sections 3 and 4, no other patent
197 | rights, express or implied, are granted herein. Your Extensions may require
198 | additional patent licenses from Licensor or Contributors which each may grant
199 | in its sole discretion. No right is granted to the trademarks of Licensor or
200 | any Contributor even if such marks are included in the Licensed Software.
201 | Nothing in this License shall be interpreted to prohibit Licensor from
202 | licensing under different terms from this License any code that Licensor
203 | otherwise would have a right to license.
204 |
205 | 5.1 You expressly acknowledge and agree that although Licensor and each
206 | Contributor grants the licenses to their respective portions of the Licensed
207 | Software set forth herein, no assurances are provided by Licensor or any
208 | Contributor that the Licensed Software does not infringe the patent or other
209 | intellectual property rights of any other entity. Licensor and each
210 | Contributor disclaim any liability to You for claims brought by any other
211 | entity based on infringement of intellectual property rights or otherwise. As
212 | a condition to exercising the rights and licenses granted hereunder, You
213 | hereby assume sole responsibility to secure any other intellectual property
214 | rights needed, if any. For example, if a third party patent license is
215 | required to allow You to distribute the Licensed Software, it is Your
216 | responsibility to acquire that license before distributing the Licensed
217 | Software.
218 |
219 | 6.0 Your Obligations And Grants. In consideration of, and as an express
220 | condition to, the licenses granted to You under this License You hereby agree
221 | that any Modifications, Derivative Works, or Required Components (collectively
222 | Extensions) that You create or to which You contribute are governed by the
223 | terms of this License including, without limitation, Section 4. Any Extensions
224 | that You create or to which You contribute must be Deployed under the terms of
225 | this License or a future version of this License released under Section 7. You
226 | hereby grant to Licensor and all third parties a world-wide, non-exclusive,
227 | royalty-free license under those intellectual property rights You own or
228 | control to use, reproduce, display, perform, modify, create derivatives,
229 | sublicense, and distribute Licensed Software, in any form. Any Extensions You
230 | make and Deploy must have a distinct title so as to readily tell any
231 | subsequent user or Contributor that the Extensions are by You. You must
232 | include a copy of this License or directions on how to obtain a copy with
233 | every copy of the Extensions You distribute. You agree not to offer or impose
234 | any terms on any Source Code or executable version of the Licensed Software,
235 | or its Extensions that alter or restrict the applicable version of this
236 | License or the recipients' rights hereunder.
237 |
238 | 6.1 Availability of Source Code. You must make available, under the terms of
239 | this License, the Source Code of any Extensions that You Deploy, via an
240 | Electronic Distribution Mechanism. The Source Code for any version that You
241 | Deploy must be made available within one (1) month of when you Deploy and must
242 | remain available for no less than twelve (12) months after the date You cease
243 | to Deploy. You are responsible for ensuring that the Source Code to each
244 | version You Deploy remains available even if the Electronic Distribution
245 | Mechanism is maintained by a third party. You may not charge a fee for any
246 | copy of the Source Code distributed under this Section in excess of Your
247 | actual cost of duplication and distribution of said copy.
248 |
249 | 6.2 Description of Modifications. You must cause any Modifications that You
250 | create or to which You contribute to be documented in the Source Code, clearly
251 | describing the additions, changes or deletions You made. You must include a
252 | prominent statement that the Modifications are derived, directly or indirectly,
253 | from the Licensed Software and include the names of the Licensor and any
254 | Contributor to the Licensed Software in (i) the Source Code and (ii) in any
255 | notice displayed by the Licensed Software You distribute or in related
256 | documentation in which You describe the origin or ownership of the Licensed
257 | Software. You may not modify or delete any pre-existing copyright notices,
258 | change notices or License text in the Licensed Software without written
259 | permission of the respective Licensor or Contributor.
260 |
261 | 6.3 Intellectual Property Matters.
262 |
263 | a. Third Party Claims. If You have knowledge that a license to a third party's
264 | intellectual property right is required to exercise the rights granted by this
265 | License, You must include a human-readable file with Your distribution that
266 | describes the claim and the party making the claim in sufficient detail that a
267 | recipient will know whom to contact.
268 |
269 | b. Contributor APIs. If Your Extensions include an application programming
270 | interface ("API") and You have knowledge of patent licenses that are
271 | reasonably necessary to implement that API, You must also include this
272 | information in a human-readable file supplied with Your distribution.
273 |
274 | c. Representations. You represent that, except as disclosed pursuant to 6.3(a)
275 | above, You believe that any Extensions You distribute are Your original
276 | creations and that You have sufficient rights to grant the rights conveyed by
277 | this License.
278 |
279 | 6.4 Required Notices.
280 |
281 | a. License Text. You must duplicate this License or instructions on how to
282 | acquire a copy in any documentation You provide along with the Source Code of
283 | any Extensions You create or to which You contribute, wherever You describe
284 | recipients' rights relating to Licensed Software.
285 |
286 | b. License Notice. You must duplicate any notice contained in EXHIBIT A (the
287 | "License Notice") in each file of the Source Code of any copy You distribute
288 | of the Licensed Software and Your Extensions. If You create an Extension, You
289 | may add Your name as a Contributor to the Source Code and accompanying
290 | documentation along with a description of the contribution. If it is not
291 | possible to put the License Notice in a particular Source Code file due to its
292 | structure, then You must include such License Notice in a location where a
293 | user would be likely to look for such a notice.
294 |
295 | c. Source Code Availability. You must notify the software community of the
296 | availability of Source Code to Your Extensions within one (1) month of the date
297 | You initially Deploy and include in such notification a description of the
298 | Extensions, and instructions on how to acquire the Source Code. Should such
299 | instructions change you must notify the software community of revised
300 | instructions within one (1) month of the date of change. You must provide
301 | notification by posting to appropriate news groups, mailing lists, weblogs, or
302 | other sites where a publicly accessible search engine would reasonably be
303 | expected to index your post in relationship to queries regarding the Licensed
304 | Software and/or Your Extensions.
305 |
306 | d. User-Visible Attribution. You must duplicate any notice contained in
307 | EXHIBIT B (the "User-Visible Attribution Notice") in each user-visible display
308 | of the Licensed Software and Your Extensions which delineates copyright,
309 | ownership, or similar attribution information. If You create an Extension,
310 | You may add Your name as a Contributor, and add Your attribution notice, as an
311 | equally visible and functional element of any User-Visible Attribution Notice
312 | content. To ensure proper attribution, You must also include such User-Visible
313 | Attribution Notice in at least one location in the Software documentation
314 | where a user would be likely to look for such notice.
315 |
316 | 6.5 Additional Terms. You may choose to offer, and charge a fee for, warranty,
317 | support, indemnity or liability obligations to one or more recipients of
318 | Licensed Software. However, You may do so only on Your own behalf, and not on
319 | behalf of the Licensor or any Contributor except as permitted under other
320 | agreements between you and Licensor or Contributor. You must make it clear that
321 | any such warranty, support, indemnity or liability obligation is offered by You
322 | alone, and You hereby agree to indemnify the Licensor and every Contributor for
323 | any liability plus attorney fees, costs, and related expenses due to any such
324 | action or claim incurred by the Licensor or such Contributor as a result of
325 | warranty, support, indemnity or liability terms You offer.
326 |
327 | 6.6 Conflicts With Other Licenses. Where any portion of Your Extensions, by
328 | virtue of being Derivative Works of another product or similar circumstance,
329 | fall under the terms of another license, the terms of that license should be
330 | honored however You must also make Your Extensions available under this
331 | License. If the terms of this License continue to conflict with the terms of
332 | the other license you may write the Licensor for permission to resolve the
333 | conflict in a fashion that remains consistent with the intent of this License.
334 | Such permission will be granted at the sole discretion of the Licensor.
335 |
336 | 7.0 Versions of This License. Licensor may publish from time to time revised
337 | versions of the License. Once Licensed Software has been published under a
338 | particular version of the License, You may always continue to use it under the
339 | terms of that version. You may also choose to use such Licensed Software under
340 | the terms of any subsequent version of the License published by Licensor. No
341 | one other than Licensor has the right to modify the terms applicable to
342 | Licensed Software created under this License.
343 |
344 | 7.1 If You create or use a modified version of this License, which You may do
345 | only in order to apply it to software that is not already Licensed Software
346 | under this License, You must rename Your license so that it is not confusingly
347 | similar to this License, and must make it clear that Your license contains
348 | terms that differ from this License. In so naming Your license, You may not
349 | use any trademark of Licensor or of any Contributor. Should Your modifications
350 | to this License be limited to alteration of a) Section 13.8 solely to modify
351 | the legal Jurisdiction or Venue for disputes, b) EXHIBIT A solely to define
352 | License Notice text, or c) to EXHIBIT B solely to define a User-Visible
353 | Attribution Notice, You may continue to refer to Your License as the
354 | Reciprocal Public License or simply the RPL.
355 |
356 | 8.0 Disclaimer of Warranty. LICENSED SOFTWARE IS PROVIDED UNDER THIS LICENSE
357 | ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
358 | INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE LICENSED SOFTWARE IS FREE
359 | OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
360 | FURTHER THERE IS NO WARRANTY MADE AND ALL IMPLIED WARRANTIES ARE DISCLAIMED
361 | THAT THE LICENSED SOFTWARE MEETS OR COMPLIES WITH ANY DESCRIPTION OF
362 | PERFORMANCE OR OPERATION, SAID COMPATIBILITY AND SUITABILITY BEING YOUR
363 | RESPONSIBILITY. LICENSOR DISCLAIMS ANY WARRANTY, IMPLIED OR EXPRESSED, THAT
364 | ANY CONTRIBUTOR'S EXTENSIONS MEET ANY STANDARD OF COMPATIBILITY OR DESCRIPTION
365 | OF PERFORMANCE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
366 | LICENSED SOFTWARE IS WITH YOU. SHOULD LICENSED SOFTWARE PROVE DEFECTIVE IN ANY
367 | RESPECT, YOU (AND NOT THE LICENSOR OR ANY OTHER CONTRIBUTOR) ASSUME THE COST
368 | OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. UNDER THE TERMS OF THIS
369 | LICENSOR WILL NOT SUPPORT THIS SOFTWARE AND IS UNDER NO OBLIGATION TO ISSUE
370 | UPDATES TO THIS SOFTWARE. LICENSOR HAS NO KNOWLEDGE OF ERRANT CODE OR VIRUS IN
371 | THIS SOFTWARE, BUT DOES NOT WARRANT THAT THE SOFTWARE IS FREE FROM SUCH ERRORS
372 | OR VIRUSES. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
373 | LICENSE. NO USE OF LICENSED SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS
374 | DISCLAIMER.
375 |
376 | 9.0 Limitation of Liability. UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY,
377 | WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE
378 | LICENSOR, ANY CONTRIBUTOR, OR ANY DISTRIBUTOR OF LICENSED SOFTWARE, OR ANY
379 | SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR ANY INDIRECT,
380 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING,
381 | WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER
382 | FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES,
383 | EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH
384 | DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH
385 | OR PERSONAL INJURY RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT
386 | APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
387 | EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THIS
388 | EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
389 |
390 | 10.0 High Risk Activities. THE LICENSED SOFTWARE IS NOT FAULT-TOLERANT AND IS
391 | NOT DESIGNED, MANUFACTURED, OR INTENDED FOR USE OR DISTRIBUTION AS ON-LINE
392 | CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE PERFORMANCE,
393 | SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT NAVIGATION OR
394 | COMMUNICATIONS SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE SUPPORT MACHINES, OR
395 | WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE LICENSED SOFTWARE COULD LEAD
396 | DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE
397 | ("HIGH RISK ACTIVITIES"). LICENSOR AND CONTRIBUTORS SPECIFICALLY DISCLAIM ANY
398 | EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
399 |
400 | 11.0 Responsibility for Claims. As between Licensor and Contributors, each
401 | party is responsible for claims and damages arising, directly or indirectly,
402 | out of its utilization of rights under this License which specifically
403 | disclaims warranties and limits any liability of the Licensor. This paragraph
404 | is to be used in conjunction with and controlled by the Disclaimer Of
405 | Warranties of Section 8, the Limitation Of Damages in Section 9, and the
406 | disclaimer against use for High Risk Activities in Section 10. The Licensor
407 | has thereby disclaimed all warranties and limited any damages that it is or
408 | may be liable for. You agree to work with Licensor and Contributors to
409 | distribute such responsibility on an equitable basis consistent with the terms
410 | of this License including Sections 8, 9, and 10. Nothing herein is intended or
411 | shall be deemed to constitute any admission of liability.
412 |
413 | 12.0 Termination. This License and all rights granted hereunder will terminate
414 | immediately in the event of the circumstances described in Section 13.6 or if
415 | applicable law prohibits or restricts You from fully and or specifically
416 | complying with Sections 3, 4 and/or 6, or prevents the enforceability of any
417 | of those Sections, and You must immediately discontinue any use of Licensed
418 | Software.
419 |
420 | 12.1 Automatic Termination Upon Breach. This License and the rights granted
421 | hereunder will terminate automatically if You fail to comply with the terms
422 | herein and fail to cure such breach within thirty (30) days of becoming aware
423 | of the breach. All sublicenses to the Licensed Software that are properly
424 | granted shall survive any termination of this License. Provisions that, by
425 | their nature, must remain in effect beyond the termination of this License,
426 | shall survive.
427 |
428 | 12.2 Termination Upon Assertion of Patent Infringement. If You initiate
429 | litigation by asserting a patent infringement claim (excluding declaratory
430 | judgment actions) against Licensor or a Contributor (Licensor or Contributor
431 | against whom You file such an action is referred to herein as "Respondent")
432 | alleging that Licensed Software directly or indirectly infringes any patent,
433 | then any and all rights granted by such Respondent to You under Sections 3 or
434 | 4 of this License shall terminate prospectively upon sixty (60) days notice
435 | from Respondent (the "Notice Period") unless within that Notice Period You
436 | either agree in writing (i) to pay Respondent a mutually agreeable reasonably
437 | royalty for Your past or future use of Licensed Software made by such
438 | Respondent, or (ii) withdraw Your litigation claim with respect to Licensed
439 | Software against such Respondent. If within said Notice Period a reasonable
440 | royalty and payment arrangement are not mutually agreed upon in writing by the
441 | parties or the litigation claim is not withdrawn, the rights granted by
442 | Licensor to You under Sections 3 and 4 automatically terminate at the
443 | expiration of said Notice Period.
444 |
445 | 12.3 Reasonable Value of This License. If You assert a patent infringement
446 | claim against Respondent alleging that Licensed Software directly or
447 | indirectly infringes any patent where such claim is resolved (such as by
448 | license or settlement) prior to the initiation of patent infringement
449 | litigation, then the reasonable value of the licenses granted by said
450 | Respondent under Sections 3 and 4 shall be taken into account in determining
451 | the amount or value of any payment or license.
452 |
453 | 12.4 No Retroactive Effect of Termination. In the event of termination under
454 | this Section all end user license agreements (excluding licenses to
455 | distributors and resellers) that have been validly granted by You or any
456 | distributor hereunder prior to termination shall survive termination.
457 |
458 | 13.0 Miscellaneous.
459 |
460 | 13.1 U.S. Government End Users. The Licensed Software is a "commercial item,"
461 | as that term is defined in 48 C.F.R. 2.101 (Oct. 1995), consisting of
462 | "commercial computer software" and "commercial computer software
463 | documentation," as such terms are used in 48 C.F.R. 12.212 (Sept. 1995).
464 | Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4
465 | (June 1995), all U.S. Government End Users acquire Licensed Software with only
466 | those rights set forth herein.
467 |
468 | 13.2 Relationship of Parties. This License will not be construed as creating
469 | an agency, partnership, joint venture, or any other form of legal association
470 | between or among You, Licensor, or any Contributor, and You will not represent
471 | to the contrary, whether expressly, by implication, appearance, or otherwise.
472 |
473 | 13.3 Independent Development. Nothing in this License will impair Licensor's
474 | right to acquire, license, develop, subcontract, market, or distribute
475 | technology or products that perform the same or similar functions as, or
476 | otherwise compete with, Extensions that You may develop, produce, market, or
477 | distribute.
478 |
479 | 13.4 Consent To Breach Not Waiver. Failure by Licensor or Contributor to
480 | enforce any provision of this License will not be deemed a waiver of future enforcement
481 | of that or any other provision.
482 |
483 | 13.5 Severability. This License represents the complete agreement concerning
484 | the subject matter hereof. If any provision of this License is held to be
485 | unenforceable, such provision shall be reformed only to the extent necessary
486 | to make it enforceable.
487 |
488 | 13.6 Inability to Comply Due to Statute or Regulation. If it is impossible for
489 | You to comply with any of the terms of this License with respect to some or
490 | all of the Licensed Software due to statute, judicial order, or regulation,
491 | then You cannot use, modify, or distribute the software.
492 |
493 | 13.7 Export Restrictions. You may be restricted with respect to downloading or
494 | otherwise acquiring, exporting, or reexporting the Licensed Software or any
495 | underlying information or technology by United States and other applicable
496 | laws and regulations. By downloading or by otherwise obtaining the Licensed
497 | Software, You are agreeing to be responsible for compliance with all
498 | applicable laws and regulations.
499 |
500 | 13.8 Arbitration, Jurisdiction & Venue. This License shall be governed by
501 | Colorado law provisions (except to the extent applicable law, if any, provides
502 | otherwise), excluding its conflict-of-law provisions. You expressly agree that
503 | any dispute relating to this License shall be submitted to binding arbitration
504 | under the rules then prevailing of the American Arbitration Association. You
505 | further agree that Adams County, Colorado USA is proper venue and grant such
506 | arbitration proceeding jurisdiction as may be appropriate for purposes of
507 | resolving any dispute under this License. Judgement upon any award made in
508 | arbitration may be entered and enforced in any court of competent
509 | jurisdiction. The arbitrator shall award attorney's fees and costs of
510 | arbitration to the prevailing party. Should either party find it necessary to
511 | enforce its arbitration award or seek specific performance of such award in a
512 | civil court of competent jurisdiction, the prevailing party shall be entitled
513 | to reasonable attorney's fees and costs. The application of the United Nations
514 | Convention on Contracts for the International Sale of Goods is expressly
515 | excluded. You and Licensor expressly waive any rights to a jury trial in any
516 | litigation concerning Licensed Software or this License. Any law or regulation
517 | that provides that the language of a contract shall be construed against the
518 | drafter shall not apply to this License.
519 |
520 | 13.9 Entire Agreement. This License constitutes the entire agreement between
521 | the parties with respect to the subject matter hereof.
522 |
523 | EXHIBIT A
524 |
525 | The License Notice below must appear in each file of the Source Code of any
526 | copy You distribute of the Licensed Software or any Extensions thereto:
527 |
528 | Unless explicitly acquired and licensed from Licensor under another
529 | license, the contents of this file are subject to the Reciprocal Public
530 | License ("RPL") Version 1.5, or subsequent versions as allowed by the RPL,
531 | and You may not copy or use this file in either source code or executable
532 | form, except in compliance with the terms and conditions of the RPL.
533 |
534 | All software distributed under the RPL is provided strictly on an "AS
535 | IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, AND
536 | LICENSOR HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
537 | LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
538 | PURPOSE, QUIET ENJOYMENT, OR NON-INFRINGEMENT. See the RPL for specific
539 | language governing rights and limitations under the RPL.
540 |
541 |
542 |
543 | EXHIBIT B
544 |
545 | The User-Visible Attribution Notice below, when provided, must appear in each
546 | user-visible display as defined in Section 6.4 (d):
547 |
--------------------------------------------------------------------------------
/source/main/avr5.x:
--------------------------------------------------------------------------------
1 | /* Default linker script, for normal executables */
2 | OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
3 | OUTPUT_ARCH(avr:5)
4 | MEMORY
5 | {
6 | text (rx) : ORIGIN = 0, LENGTH = 128K
7 | data (rw!x) : ORIGIN = 0x800060, LENGTH = 0xffa0
8 | eeprom (rw!x) : ORIGIN = 0x810000, LENGTH = 64K
9 | fuse (rw!x) : ORIGIN = 0x820000, LENGTH = 1K
10 | lock (rw!x) : ORIGIN = 0x830000, LENGTH = 1K
11 | signature (rw!x) : ORIGIN = 0x840000, LENGTH = 1K
12 | user_signatures (rw!x) : ORIGIN = 0x850000, LENGTH = 1K
13 | }
14 | SECTIONS
15 | {
16 | /* custom */
17 | .flagsection 0x3500 : { KEEP(*(.flagsection)) }
18 | .set_memory_unprotected : { KEEP(*(.set_memory_unprotected)) }
19 | /* Read-only sections, merged into text segment: */
20 | .hash : { *(.hash) }
21 | .dynsym : { *(.dynsym) }
22 | .dynstr : { *(.dynstr) }
23 | .gnu.version : { *(.gnu.version) }
24 | .gnu.version_d : { *(.gnu.version_d) }
25 | .gnu.version_r : { *(.gnu.version_r) }
26 | .rel.init : { *(.rel.init) }
27 | .rela.init : { *(.rela.init) }
28 | .rel.text :
29 | {
30 | *(.rel.text)
31 | *(.rel.text.*)
32 | *(.rel.gnu.linkonce.t*)
33 | }
34 | .rela.text :
35 | {
36 | *(.rela.text)
37 | *(.rela.text.*)
38 | *(.rela.gnu.linkonce.t*)
39 | }
40 | .rel.fini : { *(.rel.fini) }
41 | .rela.fini : { *(.rela.fini) }
42 | .rel.rodata :
43 | {
44 | *(.rel.rodata)
45 | *(.rel.rodata.*)
46 | *(.rel.gnu.linkonce.r*)
47 | }
48 | .rela.rodata :
49 | {
50 | *(.rela.rodata)
51 | *(.rela.rodata.*)
52 | *(.rela.gnu.linkonce.r*)
53 | }
54 | .rel.data :
55 | {
56 | *(.rel.data)
57 | *(.rel.data.*)
58 | *(.rel.gnu.linkonce.d*)
59 | }
60 | .rela.data :
61 | {
62 | *(.rela.data)
63 | *(.rela.data.*)
64 | *(.rela.gnu.linkonce.d*)
65 | }
66 | .rel.ctors : { *(.rel.ctors) }
67 | .rela.ctors : { *(.rela.ctors) }
68 | .rel.dtors : { *(.rel.dtors) }
69 | .rela.dtors : { *(.rela.dtors) }
70 | .rel.got : { *(.rel.got) }
71 | .rela.got : { *(.rela.got) }
72 | .rel.bss : { *(.rel.bss) }
73 | .rela.bss : { *(.rela.bss) }
74 | .rel.plt : { *(.rel.plt) }
75 | .rela.plt : { *(.rela.plt) }
76 | /* Internal text space or external memory. */
77 | .text :
78 | {
79 | *(.vectors)
80 | KEEP(*(.vectors))
81 | /* For data that needs to reside in the lower 64k of progmem. */
82 | *(.progmem.gcc*)
83 | /* PR 13812: Placing the trampolines here gives a better chance
84 | that they will be in range of the code that uses them. */
85 | . = ALIGN(2);
86 | __trampolines_start = . ;
87 | /* The jump trampolines for the 16-bit limited relocs will reside here. */
88 | *(.trampolines)
89 | *(.trampolines*)
90 | __trampolines_end = . ;
91 | *(.progmem*)
92 | . = ALIGN(2);
93 | /* For future tablejump instruction arrays for 3 byte pc devices.
94 | We don't relax jump/call instructions within these sections. */
95 | *(.jumptables)
96 | *(.jumptables*)
97 | /* For code that needs to reside in the lower 128k progmem. */
98 | *(.lowtext)
99 | *(.lowtext*)
100 | __ctors_start = . ;
101 | *(.ctors)
102 | __ctors_end = . ;
103 | __dtors_start = . ;
104 | *(.dtors)
105 | __dtors_end = . ;
106 | KEEP(SORT(*)(.ctors))
107 | KEEP(SORT(*)(.dtors))
108 | /* From this point on, we don't bother about wether the insns are
109 | below or above the 16 bits boundary. */
110 | *(.init0) /* Start here after reset. */
111 | KEEP (*(.init0))
112 | *(.init1)
113 | KEEP (*(.init1))
114 | *(.init2) /* Clear __zero_reg__, set up stack pointer. */
115 | KEEP (*(.init2))
116 | *(.init3)
117 | KEEP (*(.init3))
118 | *(.init4) /* Initialize data and BSS. */
119 | KEEP (*(.init4))
120 | *(.init5)
121 | KEEP (*(.init5))
122 | *(.init6) /* C++ constructors. */
123 | KEEP (*(.init6))
124 | *(.init7)
125 | KEEP (*(.init7))
126 | *(.init8)
127 | KEEP (*(.init8))
128 | *(.init9) /* Call main(). */
129 | KEEP (*(.init9))
130 | *(.text)
131 | . = ALIGN(2);
132 | *(.text.*)
133 | . = ALIGN(2);
134 | *(.fini9) /* _exit() starts here. */
135 | KEEP (*(.fini9))
136 | *(.fini8)
137 | KEEP (*(.fini8))
138 | *(.fini7)
139 | KEEP (*(.fini7))
140 | *(.fini6) /* C++ destructors. */
141 | KEEP (*(.fini6))
142 | *(.fini5)
143 | KEEP (*(.fini5))
144 | *(.fini4)
145 | KEEP (*(.fini4))
146 | *(.fini3)
147 | KEEP (*(.fini3))
148 | *(.fini2)
149 | KEEP (*(.fini2))
150 | *(.fini1)
151 | KEEP (*(.fini1))
152 | *(.fini0) /* Infinite loop after program termination. */
153 | KEEP (*(.fini0))
154 | _etext = . ;
155 | } > text
156 | .data :
157 | {
158 | PROVIDE (__data_start = .) ;
159 | /* --gc-sections will delete empty .data. This leads to wrong start
160 | addresses for subsequent sections because -Tdata= from the command
161 | line will have no effect, see PR13697. Thus, keep .data */
162 | KEEP (*(.data))
163 | *(.data*)
164 | *(.rodata) /* We need to include .rodata here if gcc is used */
165 | *(.rodata*) /* with -fdata-sections. */
166 | *(.gnu.linkonce.d*)
167 | . = ALIGN(2);
168 | _edata = . ;
169 | PROVIDE (__data_end = .) ;
170 | } > data AT> text
171 | .bss : AT (ADDR (.bss))
172 | {
173 | PROVIDE (__bss_start = .) ;
174 | *(.bss)
175 | *(.bss*)
176 | *(COMMON)
177 | PROVIDE (__bss_end = .) ;
178 | } > data
179 | __data_load_start = LOADADDR(.data);
180 | __data_load_end = __data_load_start + SIZEOF(.data);
181 | /* Global data not cleared after reset. */
182 | .noinit :
183 | {
184 | PROVIDE (__noinit_start = .) ;
185 | *(.noinit*)
186 | PROVIDE (__noinit_end = .) ;
187 | _end = . ;
188 | PROVIDE (__heap_start = .) ;
189 | } > data
190 | .eeprom :
191 | {
192 | /* See .data above... */
193 | KEEP(*(.eeprom*))
194 | __eeprom_end = . ;
195 | } > eeprom
196 | .fuse :
197 | {
198 | KEEP(*(.fuse))
199 | KEEP(*(.lfuse))
200 | KEEP(*(.hfuse))
201 | KEEP(*(.efuse))
202 | } > fuse
203 | .lock :
204 | {
205 | KEEP(*(.lock*))
206 | } > lock
207 | .signature :
208 | {
209 | KEEP(*(.signature*))
210 | } > signature
211 | .user_signatures :
212 | {
213 | KEEP(*(.user_signatures*))
214 | } > user_signatures
215 | /* Stabs debugging sections. */
216 | .stab 0 : { *(.stab) }
217 | .stabstr 0 : { *(.stabstr) }
218 | .stab.excl 0 : { *(.stab.excl) }
219 | .stab.exclstr 0 : { *(.stab.exclstr) }
220 | .stab.index 0 : { *(.stab.index) }
221 | .stab.indexstr 0 : { *(.stab.indexstr) }
222 | .comment 0 : { *(.comment) }
223 | .note.gnu.build-id : { *(.note.gnu.build-id) }
224 | /* DWARF debug sections.
225 | Symbols in the DWARF debugging sections are relative to the beginning
226 | of the section so we begin them at 0. */
227 | /* DWARF 1 */
228 | .debug 0 : { *(.debug) }
229 | .line 0 : { *(.line) }
230 | /* GNU DWARF 1 extensions */
231 | .debug_srcinfo 0 : { *(.debug_srcinfo) }
232 | .debug_sfnames 0 : { *(.debug_sfnames) }
233 | /* DWARF 1.1 and DWARF 2 */
234 | .debug_aranges 0 : { *(.debug_aranges) }
235 | .debug_pubnames 0 : { *(.debug_pubnames) }
236 | /* DWARF 2 */
237 | .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
238 | .debug_abbrev 0 : { *(.debug_abbrev) }
239 | .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end ) }
240 | .debug_frame 0 : { *(.debug_frame) }
241 | .debug_str 0 : { *(.debug_str) }
242 | .debug_loc 0 : { *(.debug_loc) }
243 | .debug_macinfo 0 : { *(.debug_macinfo) }
244 | /* SGI/MIPS DWARF 2 extensions */
245 | .debug_weaknames 0 : { *(.debug_weaknames) }
246 | .debug_funcnames 0 : { *(.debug_funcnames) }
247 | .debug_typenames 0 : { *(.debug_typenames) }
248 | .debug_varnames 0 : { *(.debug_varnames) }
249 | /* DWARF 3 */
250 | .debug_pubtypes 0 : { *(.debug_pubtypes) }
251 | .debug_ranges 0 : { *(.debug_ranges) }
252 | /* DWARF Extension. */
253 | .debug_macro 0 : { *(.debug_macro) }
254 | }
255 |
--------------------------------------------------------------------------------
/source/main/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | set -euo pipefail
4 |
5 | #avr-gcc $GCC_COMPILE_FLAGS $GCC_LINK_FLAGS $INC_PATH -Wl,--section-start=.flagsection=0x3500 -o ctf.elf main.c $DEPS
6 | avr-gcc $GCC_COMPILE_FLAGS $GCC_LINK_FLAGS $INC_PATH -Wl,--script=avr5.x -o ctf.elf main.c $DEPS
7 | avr-objcopy $OBJCOPY_IHEX_FLAGS -j .flagsection ctf.elf ctf.hex
8 | avr-objcopy $OBJCOPY_BIN_FLAGS -j .flagsection ctf.elf ctf.bin
9 |
--------------------------------------------------------------------------------
/source/main/ldscript:
--------------------------------------------------------------------------------
1 | SECTIONS
2 | {
3 | .flagsection = 0x3500;
4 | }
5 |
--------------------------------------------------------------------------------
/source/main/main.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "serial_io.h"
8 | #include "menu.h"
9 | #include "random.h"
10 | #include "eeprom_rw.h"
11 | #include "examine_stack.h"
12 |
13 | const char *inbuff;
14 |
15 | //const char flag[] __attribute__((section(".flagsection"))) = "RHme+_Y0u_G0t_1t";
16 |
17 | /*
18 | * these externs are declared in auth.c
19 | */
20 | extern uint8_t is_authenticated;
21 | extern uint8_t is_privileged;
22 | extern uint8_t is_administrator;
23 | extern uint8_t is_auth_nonce_valid;
24 |
25 | int main(void) {
26 | /*
27 | * initialize the buffer which will be used storing input
28 | */
29 | inbuff = (char *)malloc( sizeof(char) * INBUFF_LEN );
30 |
31 | /*
32 | * just to be on the safe side,
33 | * make sure there is not auth session
34 | * enabled when the board boots
35 | */
36 | is_authenticated = 0;
37 | is_privileged = 0;
38 | is_administrator = 0;
39 | is_auth_nonce_valid = 0;
40 |
41 | /*
42 | * commence ctf! :D
43 | */
44 | serial_init();
45 | dbg_tx_init();
46 | random_init();
47 | eeprom_set_memory_protected();
48 | menu_main();
49 |
50 | return 0;
51 | }
52 |
--------------------------------------------------------------------------------
/source/menu/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | set -euo pipefail
4 |
5 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c menu.c
6 |
7 | echo "$(pwd)/menu.o"
8 |
--------------------------------------------------------------------------------
/source/menu/menu.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "serial_io.h"
8 | #include "variables.h"
9 | #include "auth.h"
10 | #include "overflow_readflash.h"
11 | #include "overflow_rop.h"
12 |
13 | static void menu_loop(void);
14 | static uint8_t verify_int(char *);
15 | static void trollTheHacker();
16 |
17 | extern uint8_t is_authenticated;
18 | extern uint8_t is_administrator;
19 | extern uint8_t is_privileged;
20 | extern char *inbuff;
21 |
22 | uint8_t valve = 0;
23 |
24 | const char commands_text[] PROGMEM =
25 | "Possible commands:\r\n";
26 |
27 | const char menu_message_start[] PROGMEM =
28 | "\tA\tauthenticate\r\n"
29 | "\tRxxxx\tsubmit response (xxxx = response in hex)\r\n"
30 | "\tV\tretrieve variables\r\n";
31 |
32 | const char menu_message_auth_user[] PROGMEM =
33 | "\tR\tread flash config\r\n"
34 | "\tP\tprint the valve state\r\n";
35 |
36 | const char menu_message_privileged_user[] PROGMEM =
37 | "\tV\tchange the valve state\r\n"
38 | "\tS\tsend command to backend ICS network\r\n";
39 |
40 | const char menu_message_auth_admin[] PROGMEM =
41 | "\tK\tread the Admin key\r\n";
42 |
43 |
44 |
45 | const char menu_message_logout[] PROGMEM =
46 | "\tX\tlog out\r\n";
47 |
48 | const char help_end[] PROGMEM =
49 | "\tH\tshow help\r\n"
50 | "\r\n";
51 |
52 | const char troll[13][26] __attribute__((section(".flagsection"))) = {"\r\nCalculating index",
53 | "\r\nChecking Key CRC",
54 | "\r\nShuffling bits",
55 | "\r\nMore shuffling",
56 | "\r\nEven more shuffling!",
57 | "\r\nDeshuffling bits",
58 | "\r\nError! Dizzy bit!",
59 | "\r\nApplying Dimenhydrinate",
60 | "\r\nThe bit doesnt respond!",
61 | "\r\nAny doctor in room?",
62 | "\r\nBit recovered.Printing",
63 | "\r\nThe key is",
64 | "\r\nMUAHAHAAH!! TROLLED!\r\n"
65 | };
66 |
67 |
68 |
69 | void menu_main(void) {
70 | serial_printf("%s", "Welcome to Erucsir ICS terminal\r\n");
71 | serial_printf("%S", commands_text);
72 | serial_printf("%S", menu_message_start);
73 | serial_printf("%S", help_end);
74 | while(1)
75 | menu_loop();
76 | }
77 |
78 | static void menu_loop(void) {
79 | int8_t aux;
80 | uint8_t res;
81 |
82 | serial_read(inbuff, INBUFF_LEN);
83 | serial_printf("%S", PSTR("\r\n"));
84 |
85 | if (is_authenticated == 0) {
86 | if (inbuff[0] == 'A') {
87 | generate_challenge();
88 |
89 | } else if (inbuff[0] == 'R') {
90 | verify_response();
91 |
92 | } else if (inbuff[0] == 'V') {
93 | /*
94 | * we will be using strtol() to convert the string to a long which
95 | * gets downcasted to int, but this is not an issue as we verify the
96 | * length of the string in verify_int
97 | *
98 | * the variables_menu function though excepts an unsigned int
99 | *
100 | * a regular int for this board is 16 bits, meaning that an unsigned
101 | * int takes values from 0 to 65535, thus -1 as signed is 65535 unsigned
102 | */
103 | serial_printf("%S", PSTR("How many variables should be printed? (max 5)\r\n"));
104 | serial_read(inbuff, INBUFF_LEN);
105 | serial_printf("%S", PSTR("\r\n"));
106 |
107 | res = verify_int(inbuff);
108 | if (res == 1) {
109 | aux = strtol(inbuff, NULL, 10);
110 | if (aux > 5) {
111 | res = 0;
112 | } else {
113 | serial_printf("Printing %d variables\r\n", aux);
114 | variables_menu(aux);
115 | }
116 | }
117 | if (res == 0) {
118 | serial_printf("%S", PSTR("Input is not a valid number \r\n"));
119 | serial_printf("%S", PSTR("Please enter a number smaller than 5\r\n"));
120 | }
121 |
122 | } else if (inbuff[0] == 'H') {
123 | serial_printf("%S", commands_text);
124 | serial_printf("%S", menu_message_start);
125 | serial_printf("%S", help_end);
126 | } else
127 | serial_printf("Command %s is invalid\r\n", inbuff);
128 |
129 | } else { // is_authenticated == 1
130 |
131 | switch (inbuff[0]) {
132 |
133 | case 'R':
134 | overflow_readflash();
135 | break;
136 |
137 | case 'X':
138 | is_privileged=is_administrator=is_authenticated=0;
139 | serial_printf("%s", "Welcome to Erucsir ICS terminal\r\n");
140 | serial_printf("%S", commands_text);
141 | serial_printf("%S", menu_message_start);
142 | serial_printf("%S", help_end);
143 | break;
144 |
145 | case 'H':
146 | serial_printf("%S", commands_text);
147 | serial_printf("%S", menu_message_auth_user);
148 | if (is_privileged==1 || is_administrator==1)
149 | serial_printf("%S", menu_message_privileged_user);
150 | if (is_administrator)
151 | serial_printf("%S", menu_message_auth_admin);
152 | serial_printf("%S", menu_message_logout);
153 | serial_printf("%S", help_end);
154 | break;
155 |
156 |
157 | case 'P':
158 | if (valve==0)
159 | serial_printf("Valve closed\r\n");
160 | else
161 | serial_printf("Valve open\r\n");
162 | break;
163 |
164 | case 'V':
165 | if (is_privileged==1 || is_administrator == 1) {
166 | if (valve==0)
167 | valve=1;
168 | else
169 | valve=0;
170 | serial_printf("Valve changed\r\n");
171 | break;
172 | }
173 | goto switch_default;
174 |
175 | case 'S':
176 | if (is_privileged==1 || is_administrator == 1) {
177 | overflow_rop();
178 | break;
179 | }
180 | goto switch_default;
181 |
182 | case 'K':
183 | if (is_administrator == 1) {
184 | trollTheHacker();
185 | break;
186 | }
187 | // Dont break here!
188 |
189 | default:
190 | switch_default:
191 | serial_printf("Command %s is invalid\r\n", inbuff);
192 |
193 | }
194 |
195 | }
196 | }
197 |
198 | static void returnTrollString (char * buffer, uint8_t index) {
199 |
200 | uint8_t i;
201 | //char key[] = "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa";
202 |
203 | strncpy_P(buffer,((const PROGMEM char *)(troll[index])),26);
204 |
205 | /*for (i=0; i<26; i++) {
206 | buffer[i] ^= 0x01;
207 | //buffer[i] ++;
208 | }*/
209 |
210 | }
211 |
212 | static void trollTheHacker() {
213 |
214 | volatile uint32_t j;
215 | uint8_t i;
216 |
217 | char buffer[26];
218 |
219 | serial_printf("Retriving the Admin Key");
220 |
221 | for (i=1; i<131; i++) {
222 | for (j=0; j<900000; j++) {
223 |
224 | }
225 | serial_printf(".");
226 | if (i%10 == 0) {
227 | returnTrollString(buffer,i/10);
228 |
229 | serial_printf("%s",buffer);
230 | }
231 | }
232 | }
233 |
234 | static uint8_t verify_int(char *buff) {
235 | int i;
236 | int len;
237 |
238 | len = strlen(buff);
239 | for (i = 0; i < len; i++)
240 | if ( !(isdigit(buff[i]) || buff[i] == '-') ) {
241 | serial_printf_debug("%S", PSTR("int parsing routine detected invalid characters\r\n"));
242 | return 0;
243 | }
244 |
245 | if ( !((buff[0] == '-' && len == 2) || len == 1) ) {
246 | serial_printf_debug("%S", PSTR("int parsing routine detected invalid input size\r\n"));
247 | return 0;
248 | }
249 |
250 | return 1;
251 | }
252 |
--------------------------------------------------------------------------------
/source/menu/menu.h:
--------------------------------------------------------------------------------
1 | #ifndef MENU_H
2 | #define MENU_H
3 |
4 | void menu_main(void);
5 |
6 | #endif
7 |
--------------------------------------------------------------------------------
/source/overflow_readflash/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | set -euo pipefail
4 |
5 | GCC_OPTIMIZATION_FLAG="-O0"
6 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c overflow_readflash.c
7 |
8 | echo "$(pwd)/overflow_readflash.o"
9 |
--------------------------------------------------------------------------------
/source/overflow_readflash/overflow_readflash.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "serial_io.h"
6 | #include "eeprom_rw.h"
7 |
8 | #define CANARY 0xc7
9 | #define READ_ADDR_MAX 0x3500
10 |
11 | const char config_string[] PROGMEM =
12 | "MCU family\tATMega328P\r\n"
13 | "Firmware\t1.2.0-ALPHA\r\n"
14 | "Build date\t01-10-2015\r\n"
15 | "Build flags\t-O +x --eep rw --pgmem r --debug\r\n"
16 | "\r\n";
17 |
18 | static uint8_t totp_validation(uint32_t);
19 |
20 | void overflow_readflash(void) {
21 | /*
22 | * the order of the locals below is rather important because of
23 | * how they are ultimately placed in the compiled binary
24 | * the required placement at runtime needs(!!!) to be
25 | * confstr_addr high address
26 | * buff low address
27 | */
28 | volatile uint8_t continue_read = 1;
29 | volatile uint8_t protected_mem;
30 | volatile uint8_t str_byte;
31 | volatile char buff[20]; // 20 bytes
32 | volatile uint16_t confstr_addr; // 2 bytes
33 | // 22 bytes in total
34 | volatile uint8_t nocrash;
35 | confstr_addr = (uint16_t)(&config_string);
36 |
37 | serial_printf("%S", PSTR("Please insert your TOTP user token\r\n"));
38 | serial_read((char *)buff, 23); // 22 calculated above + 1 for \0
39 | serial_printf("%S", PSTR("\r\n"));
40 |
41 | serial_printf("%S", PSTR("Contacting TOTP validation server\r\n"));
42 | if ( totp_validation( atoi((char *)buff) ) ) {
43 | serial_printf("%S", PSTR("Token validated\r\n"));
44 |
45 | str_byte = pgm_read_byte_near(confstr_addr++);
46 | while (str_byte != 0) {
47 | protected_mem = eeprom_is_memory_protected();
48 | if ( protected_mem == 1 && confstr_addr > READ_ADDR_MAX )
49 | continue_read = 0;
50 |
51 | if (continue_read == 1) {
52 | serial_printf("%c", str_byte);
53 | str_byte = pgm_read_byte_near(confstr_addr++);
54 | } else {
55 | serial_printf("%S", PSTR("\r\n"));
56 | serial_printf_debug("%S", PSTR("instruction at untrusted address attempted to read from unauthorized memory address\r\n"));
57 | break;
58 | }
59 | }
60 | }
61 | }
62 |
63 | static uint8_t totp_validation(uint32_t token) {
64 | serial_printf_debug("%S", PSTR("function totp_validation not implemented\r\n"));
65 | serial_printf_debug("%S", PSTR("returning 1\r\n"));
66 | return 1;
67 | }
68 |
--------------------------------------------------------------------------------
/source/overflow_readflash/overflow_readflash.h:
--------------------------------------------------------------------------------
1 | #ifndef OVERFLOW_READFLASH_H
2 | #define OVERFLOW_READFLASH_H
3 |
4 | void overflow_readflash(void);
5 |
6 | #endif
7 |
--------------------------------------------------------------------------------
/source/overflow_rop/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | set -euo pipefail
4 |
5 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c overflow_rop.c
6 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c examine_stack.c
7 |
8 | echo "$(pwd)/overflow_rop.o $(pwd)/examine_stack.o"
9 |
--------------------------------------------------------------------------------
/source/overflow_rop/examine_stack.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "serial_io.h"
4 |
5 | uint8_t lo;
6 | uint8_t hi;
7 |
8 | void examine_stack(void) {
9 | volatile uint8_t *ptr; // two bytes
10 | volatile uint8_t i; // one byte
11 |
12 | /*
13 | * here we get the current stack pointer
14 | * by the time this code gets executed, 11 bytes
15 | * are pushed (return address and 9 registers)
16 | *
17 | * after this code gets executed, the [hi;lo]
18 | * pointer will be 9 bytes(/registers) distance
19 | * from the return address of the current frame
20 | */
21 |
22 | asm volatile(
23 | "in r18, 0x3d \n\t"
24 | "in r19, 0x3e \n\t"
25 | "sts hi, r18 \n\r"
26 | "sts lo, r19 \n\t"
27 | :
28 | :
29 | : "r18", "r19"
30 | );
31 |
32 | ptr = lo;
33 | ptr = (uint8_t *)((uint16_t)ptr << 8);
34 | ptr = (uint8_t *)((uint16_t)ptr | hi);
35 |
36 | for (i = 0; i < 16 * 3; i++) {
37 | if ( i % 16 == 0 )
38 | serial_printf("\r\n");
39 | serial_printf("%02x ", ptr[i + 10]); // calculated above
40 | }
41 | serial_printf("\r\n");
42 | }
43 |
--------------------------------------------------------------------------------
/source/overflow_rop/examine_stack.h:
--------------------------------------------------------------------------------
1 | #ifndef EXAMINE_STACK_H
2 | #define EXAMINE_STACK_H
3 |
4 | void examine_stack(void);
5 |
6 | #endif
7 |
--------------------------------------------------------------------------------
/source/overflow_rop/overflow_rop.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "serial_io.h"
7 | #include "examine_stack.h"
8 |
9 | #define CANARY 0xc8
10 | #define READ_ADDR_MAX 0x2500
11 |
12 | extern char *inbuff;
13 |
14 | static uint8_t validate_len(char *, uint8_t);
15 | void send_ics_command(void);
16 |
17 | void overflow_rop(void) {
18 | /*
19 | * the order of the locals below is rather important because of
20 | * how they are ultimately placed in the compiled binary
21 | * the required placement at runtime needs(!!!) to be
22 | * canary highest address
23 | * buff lowest address
24 | */
25 | uint32_t len;
26 | int8_t i;
27 | volatile char buff[6];
28 | volatile uint8_t canary = CANARY;
29 |
30 | /*
31 | * to check that the locals are placed correctly in memory, decomment
32 | * the following lines and make sure the addresses are printed from
33 | * lowest to highest
34 | */
35 | serial_printf("%p\r\n", buff);
36 | serial_printf("%p\r\n", &canary);
37 |
38 | serial_printf("%S", PSTR("Insert instruction length (min 0, max 4)\r\n"));
39 | serial_read(inbuff, INBUFF_LEN);
40 | serial_printf("%S", PSTR("\r\n"));
41 | if ( validate_len(inbuff, INBUFF_LEN) ) {
42 | len = strtoul(inbuff, NULL, 10);
43 | serial_printf("Length %x\r\n", len);
44 |
45 | serial_printf("%S", PSTR("Insert instruction opcode\r\n"));
46 | serial_printf("%S", PSTR(""));
47 | serial_read((char *)buff, len + 1);
48 | serial_printf("%S", PSTR("\r\n"));
49 |
50 | serial_printf("%S", PSTR("The inserted command was\r\n"));
51 | for (i = 0; i < len; i++)
52 | serial_send_char(buff[i]);
53 | serial_printf("\r\n");
54 |
55 | if (canary != CANARY) {
56 | serial_printf_debug("%S", PSTR("stack buffer overflow detected\r\n"));
57 | serial_printf_debug("%S", PSTR("disabling terminal\r\n"));
58 | while(1);
59 | } else
60 | send_ics_command();
61 | } else
62 | serial_printf_debug("%S", PSTR("invalid length\r\n"));
63 | }
64 |
65 | static uint8_t validate_len(char *buff, uint8_t len) {
66 | int k = 0;
67 |
68 | if (buff[0] == '\0')
69 | return 0;
70 | while (buff[k] != '\0') {
71 | if ( !isdigit(buff[k]) )
72 | return 0;
73 | k++;
74 | }
75 | return 1;
76 | }
77 |
78 | void send_ics_command(void) {
79 | serial_printf_debug("%S", PSTR("function send_ics_command not implemented\r\n"));
80 | }
81 |
--------------------------------------------------------------------------------
/source/overflow_rop/overflow_rop.h:
--------------------------------------------------------------------------------
1 | #ifndef OVERFLOW_ROP_H
2 | #define OVERFLOW_ROP_H
3 |
4 | void overflow_rop(void);
5 |
6 | #endif
7 |
--------------------------------------------------------------------------------
/source/random/README:
--------------------------------------------------------------------------------
1 | The srand and rand functions are available from avr-libc, but the problem is getting a good seed for the random,
2 | hopefully one that is different each time the board is booted.
3 |
4 | Important reading material:
5 | http://maxembedded.com/2011/06/avr-basics/
6 | http://maxembedded.com/2011/06/port-operations-in-avr/
7 | http://maxembedded.com/2011/06/the-adc-of-the-avr/
8 |
--------------------------------------------------------------------------------
/source/random/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | set -euo pipefail
4 |
5 | DEBUG=1
6 | #RAND_SRC="RAND_PB"
7 | RAND_SRC="RAND_ADC"
8 |
9 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -D$RAND_SRC -c random.c
10 |
11 | if [[ $DEBUG == 1 ]]; then
12 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c random_test.c
13 | avr-gcc $GCC_COMPILE_FLAGS $GCC_LINK_FLAGS -o random_test.elf random_test.o random.o $DEPS
14 | avr-objcopy $OBJCOPY_IHEX_FLAGS random_test.elf random_test.hex
15 | fi
16 |
17 | echo "$(pwd)/random.o"
18 |
--------------------------------------------------------------------------------
/source/random/random.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "random.h"
7 | #include "serial_io.h"
8 |
9 | #define LFSR_ROUNDS 10
10 |
11 | static uint32_t gen_seed(void);
12 | static uint32_t lfsr(uint32_t); // linear feedback shift register
13 |
14 | #ifdef RAND_PB
15 | static void random_pb_init(void);
16 | static uint8_t get_pb_rand(void);
17 |
18 | static void random_pb_init(void) {
19 | // set all pins of port B as inputs
20 | DDRB = 0x00;
21 |
22 | // deactivate pull-up registers; make the pins floating
23 | PORTB = 0x00;
24 | }
25 |
26 | static uint8_t get_pb_rand(void) {
27 | return PINB;
28 | }
29 |
30 | #elif defined RAND_ADC
31 | static void random_adc_init(void);
32 | static uint8_t get_adc_rand(void);
33 |
34 | static void random_adc_init(void) {
35 | // AREF = AVcc
36 | ADMUX = (1 << REFS0);
37 |
38 | // ADC Enable and prescaler of 128
39 | // 16000000/128 = 125000
40 | ADCSRA = (1 << ADEN) | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0);
41 | }
42 |
43 | static uint8_t get_adc_rand(void) {
44 | /*
45 | * the ADC on the atmega has a resolution of 10 bits only
46 | * although this function return a uint16_t, the 6 MSBs will
47 | * always be the same
48 | */
49 |
50 | uint8_t ch = 1; // read ADC3
51 |
52 | // select the corresponding channel (0 to 5)
53 | ADMUX = (ADMUX & 0xF8) | ch;
54 |
55 | // start single conversion
56 | // write '1' to ADSC
57 | ADCSRA |= (1 << ADSC);
58 |
59 | // wait for conversion to complete
60 | // ADSC becomes '0' again
61 | // till then, run loop continuously
62 | while ( ADCSRA & (1 << ADSC) );
63 |
64 | return (uint8_t)(ADC);
65 | }
66 |
67 | #endif
68 |
69 | void random_init(void) {
70 | #ifdef RAND_PB
71 | random_pb_init();
72 | #elif defined RAND_ADC
73 | random_adc_init();
74 | #endif
75 | }
76 |
77 | uint8_t get_random_hw(void) {
78 | uint8_t r;
79 | #ifdef RAND_PB
80 | r = get_pb_rand();
81 | #elif defined RAND_ADC
82 | r = get_adc_rand();
83 | #endif
84 | return r;
85 | }
86 |
87 | uint32_t get_random_uint32_t(void) {
88 | /*
89 | * we use srandom and random instead of srand and rand because the former
90 | * operate on unsigned long instead
91 | *
92 | * calling srandom every time is probably not a great idea (lol..)
93 | * especially since eeprom can be changed at runtime with a programmer
94 | * thus ensuring the same random numbers are returned each time
95 | */
96 | uint32_t rnd;
97 |
98 | srandom( gen_seed() );
99 |
100 | rnd = random() & 0xFFFF;
101 | rnd <<= 16;
102 | rnd |= random() & 0xFFFF;
103 |
104 | return lfsr(rnd);
105 | }
106 |
107 | static uint32_t gen_seed(void) {
108 | uint8_t i, aux;
109 | uint32_t seed;
110 |
111 | seed = 0;
112 | for (i = 0; i < 32; i++) {
113 | /*
114 | * for each bit, a modified von neumann corrector is applied
115 | * to the last two bits of the hardware random number generator
116 | *
117 | * this is modified because we want the RNG to be easily manipulated
118 | * when the ADC is connected to GND and returns 0 always
119 | */
120 |
121 | aux = get_random_hw() & 0b11;
122 | while (aux == 0b01 || aux == 0b11)
123 | aux = get_random_hw() & 0b11;
124 |
125 | if (aux == 0b10)
126 | seed |= 1;
127 | else if (aux == 0b00)
128 | seed |= 0;
129 |
130 | seed <<= 1;
131 | }
132 |
133 | return seed;
134 | }
135 |
136 | static uint32_t lfsr(uint32_t input) {
137 | uint32_t output;
138 | uint32_t bit;
139 | int i;
140 |
141 | for (i = 0; i < LFSR_ROUNDS; i++) {
142 | bit = (input >> 7) ^ (input >> 15) ^ (input >> 19) ^ (input >> 22) ^ (input >> 26) ^ (input >> 29);
143 | bit &= 1;
144 | output = (input >> 1) | (bit << 31);
145 | }
146 |
147 | return output;
148 | }
149 |
--------------------------------------------------------------------------------
/source/random/random.h:
--------------------------------------------------------------------------------
1 | #ifndef RANDOM_H
2 | #define RANDOM_H
3 |
4 | void random_init(void);
5 | uint8_t get_random_hw(void);
6 | uint32_t get_random_uint32_t(void);
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/source/random/random_test.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "serial_io.h"
5 | #include "random.h"
6 |
7 | static void byte_to_str(uint8_t, char *);
8 |
9 | int main(void) {
10 | int i;
11 | uint16_t vals[256];
12 | char buff[9];
13 |
14 | serial_init();
15 | random_init();
16 |
17 | for (i = 0; i < 256; i++)
18 | vals[i] = 0;
19 |
20 | for (i = 0; i < 200; i++) {
21 | _delay_ms(5);
22 | vals[ get_random_hw() ]++;
23 | }
24 |
25 | serial_printf("\r\n");
26 | for (i = 0; i < 256; i++)
27 | if (vals[i] != 0) {
28 | byte_to_str(i, buff);
29 | serial_printf("%s %d\r\n", buff, vals[i]);
30 | }
31 |
32 | while(1);
33 | return 0;
34 | }
35 |
36 | static void byte_to_str(uint8_t byte, char *output) { // exptected to have at least 8 chars + '\0'
37 | int8_t i, j;
38 |
39 | i = 7;
40 | while(byte) {
41 | for (j = i; j < 7; j++)
42 | output[j] = output[j + 1];
43 | output[7] = '0' + byte % 2;
44 | i--;
45 | byte /= 2;
46 | }
47 |
48 | for (j = i; j >= 0; j--)
49 | output[j] = '0';
50 |
51 | output[8] = '\0';
52 | }
53 |
--------------------------------------------------------------------------------
/source/serial/README:
--------------------------------------------------------------------------------
1 | The usartx code is based on a library which is available online at:
2 | http://www.seanet.com/~karllunt/atxmegasource.html
3 |
4 | The raw uart code is based on a docs available online in the datasheet
5 | and some extra c magic from yours truly. Some very nice explanations at:
6 | https://hekilledmywire.wordpress.com/2011/01/05/using-the-usartserial-tutorial-part-2/
7 |
8 | The software uart code is from avrfreaks
9 | http://www.avrfreaks.net/forum/code-c-avr-gcc-software-transmit-only-uart
10 |
--------------------------------------------------------------------------------
/source/serial/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | set -euo pipefail
4 |
5 | DEBUG=0
6 |
7 | if [[ $BOARD_FAMILY == "ATX_MEGA" ]]; then
8 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c usartx.c
9 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c serial_io.c
10 | echo "$(pwd)/usartx.o $(pwd)/serial_io.o"
11 | elif [[ $BOARD_FAMILY == "AT_MEGA" ]]; then
12 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c dbg_putchar.c
13 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c usart.c
14 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c serial_io.c
15 | echo "$(pwd)/dbg_putchar.o $(pwd)/usart.o $(pwd)/serial_io.o"
16 | fi
17 |
18 | if [[ $DEBUG == 1 ]]; then
19 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c serial_test.c
20 |
21 | >&2 echo "Building serial module in DEBUG mode"
22 | if [[ $BOARD_FAMILY == "ATX_MEGA" ]]; then
23 | avr-gcc $GCC_COMPILE_FLAGS $GCC_LINK_FLAGS -o serial_test.elf usartx.o serial_io.o serial_test.o $DEPS
24 | avr-objcopy $OBJCOPY_IHEX_FLAGS serial_test.elf serial_test.hex
25 |
26 | elif [[ $BOARD_FAMILY == "AT_MEGA" ]]; then
27 | avr-gcc $GCC_COMPILE_FLAGS $GCC_LINK_FLAGS -o serial_test.elf dbg_putchar.o usart.o serial_io.o serial_test.o $DEPS
28 | avr-objcopy $OBJCOPY_IHEX_FLAGS serial_test.elf serial_test.hex
29 | fi
30 | fi
31 |
--------------------------------------------------------------------------------
/source/serial/dbg_putchar.c:
--------------------------------------------------------------------------------
1 | /*
2 | * ----------------------------------------------------------------------------
3 | * "THE BEER-WARE LICENSE" (Revision 42, by Joerg Wunsch):
4 | * wrote this file. As long as you retain this notice
5 | * you can do whatever you want with this stuff. If we meet some day, and you
6 | * think this stuff is worth it, you can buy me a beer in return.
7 | * Dimitar Dimitrov
8 | * ----------------------------------------------------------------------------
9 | */
10 |
11 | #include
12 | #include
13 | #include
14 |
15 | #include "dbg_putchar.h"
16 |
17 | #if DBG_UART_ENABLE
18 |
19 | void dbg_putchar(uint8_t c)
20 | {
21 | #define DBG_UART_TX_NUM_DELAY_CYCLES ((F_CPU/DBG_UART_BAUDRATE-16)/4+1)
22 | #define DBG_UART_TX_NUM_ADD_NOP ((F_CPU/DBG_UART_BAUDRATE-16)%4)
23 | uint8_t sreg;
24 | uint16_t tmp;
25 | uint8_t numiter = 10;
26 |
27 | sreg = SREG;
28 | cli();
29 |
30 | asm volatile (
31 | /* put the START bit */
32 | "in %A0, %3" "\n\t" /* 1 */
33 | "cbr %A0, %4" "\n\t" /* 1 */
34 | "out %3, %A0" "\n\t" /* 1 */
35 | /* compensate for the delay induced by the loop for the
36 | * other bits */
37 | "nop" "\n\t" /* 1 */
38 | "nop" "\n\t" /* 1 */
39 | "nop" "\n\t" /* 1 */
40 | "nop" "\n\t" /* 1 */
41 | "nop" "\n\t" /* 1 */
42 |
43 | /* delay */
44 | "1:" "ldi %A0, lo8(%5)" "\n\t" /* 1 */
45 | "ldi %B0, hi8(%5)" "\n\t" /* 1 */
46 | "2:" "sbiw %A0, 1" "\n\t" /* 2 */
47 | "brne 2b" "\n\t" /* 1 if EQ, 2 if NEQ */
48 | #if DBG_UART_TX_NUM_ADD_NOP > 0
49 | "nop" "\n\t" /* 1 */
50 | #if DBG_UART_TX_NUM_ADD_NOP > 1
51 | "nop" "\n\t" /* 1 */
52 | #if DBG_UART_TX_NUM_ADD_NOP > 2
53 | "nop" "\n\t" /* 1 */
54 | #endif
55 | #endif
56 | #endif
57 | /* put data or stop bit */
58 | "in %A0, %3" "\n\t" /* 1 */
59 | "sbrc %1, 0" "\n\t" /* 1 if false,2 otherwise */
60 | "sbr %A0, %4" "\n\t" /* 1 */
61 | "sbrs %1, 0" "\n\t" /* 1 if false,2 otherwise */
62 | "cbr %A0, %4" "\n\t" /* 1 */
63 | "out %3, %A0" "\n\t" /* 1 */
64 |
65 | /* shift data, putting a stop bit at the empty location */
66 | "sec" "\n\t" /* 1 */
67 | "ror %1" "\n\t" /* 1 */
68 |
69 | /* loop 10 times */
70 | "dec %2" "\n\t" /* 1 */
71 | "brne 1b" "\n\t" /* 1 if EQ, 2 if NEQ */
72 | : "=&w" (tmp), /* scratch register */
73 | "=r" (c), /* we modify the data byte */
74 | "=r" (numiter) /* we modify number of iter.*/
75 | : "I" (_SFR_IO_ADDR(DBG_UART_TX_PORT)),
76 | "M" (1< wrote this file. As long as you retain this notice
5 | * you can do whatever you want with this stuff. If we meet some day, and you
6 | * think this stuff is worth it, you can buy me a beer in return.
7 | * Dimitar Dimitrov
8 | * ----------------------------------------------------------------------------
9 | */
10 |
11 | #ifndef DBG_PUTCHAR_H
12 | #define DBG_PUTCHAR_H
13 |
14 | #include
15 |
16 | /* User setting -> Whether to enable the software UART */
17 | #define DBG_UART_ENABLE 1
18 |
19 | /* User setting -> Output pin the software UART */
20 | #define DBG_UART_TX_PORT PORTB
21 | #define DBG_UART_TX_DDR DDRB
22 | #define DBG_UART_TX_PIN PB0
23 |
24 | /* User setting -> Software UART baudrate. */
25 | #define DBG_UART_BAUDRATE 9600
26 |
27 |
28 | /* ---- DO NOT TOUCH BELOW THIS LINE ---- */
29 |
30 | #if DBG_UART_ENABLE
31 |
32 | /**
33 | * @brief Debug software UART initialization.
34 | */
35 | #define dbg_tx_init() do { \
36 | DBG_UART_TX_PORT |= (1<
2 |
3 | #include "dbg_putchar.h"
4 | #include "serial_io.h"
5 |
6 | char prbuff[PRBUFF_LEN];
7 |
8 | #ifdef ATX_MEGA
9 |
10 | void serial_printf(const char *format, ...) {
11 | va_list args;
12 |
13 | va_start(args, format);
14 | vprintf(format, args);
15 | va_end(args);
16 | }
17 |
18 | void serial_read(char *buffer, uint8_t len) {
19 | getsedit(buffer, len, NULL);
20 | }
21 |
22 | #elif defined AT_MEGA
23 |
24 | void serial_send_char(char c) {
25 | usart_send_byte(c);
26 | }
27 |
28 | void serial_printf(const char *format, ...) {
29 | va_list args;
30 |
31 | va_start(args, format);
32 | vsnprintf(prbuff, PRBUFF_LEN, format, args);
33 | usart_print(prbuff);
34 | va_end(args);
35 | }
36 |
37 | void serial_printf_debug(const char *format, ...) {
38 | va_list args;
39 |
40 | va_start(args, format);
41 | vsnprintf(prbuff, PRBUFF_LEN, format, args);
42 | dbg_puts(prbuff);
43 | va_end(args);
44 | }
45 |
46 | void serial_read(char *buffer, uint8_t len) {
47 | usart_read_str(buffer, len);
48 | }
49 |
50 | #endif
51 |
--------------------------------------------------------------------------------
/source/serial/serial_io.h:
--------------------------------------------------------------------------------
1 | #ifndef SERIAL_IO_H
2 | #define SERIAL_IO_H
3 |
4 | #include
5 |
6 | #include "dbg_putchar.h"
7 |
8 | #ifdef ATX_MEGA
9 |
10 | #include "usartx.h"
11 |
12 | #elif defined AT_MEGA
13 |
14 | #include "usart.h"
15 |
16 | #endif
17 |
18 | //#define ENABLE_DEBUG 1
19 |
20 | #ifdef ENABLE_DEBUG
21 | #define DEBUG_PRINT(x, args...) serial_printf(x, args)
22 | #else
23 | #define DEBUG_PRINT(x, args...)
24 | #endif
25 |
26 | void serial_send_char(char);
27 | void serial_printf(const char *, ...);
28 | void serial_printf_debug(const char *, ...);
29 | void serial_read(char *, uint8_t);
30 |
31 | #endif
32 |
--------------------------------------------------------------------------------
/source/serial/serial_test.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "dbg_putchar.h"
6 | #include "serial_io.h"
7 |
8 | int main(void) {
9 | char buff[20];
10 |
11 | //serial_init();
12 |
13 | dbg_tx_init();
14 | serial_printf_debug("\r\nlolz");
15 |
16 | //serial_printf("Testing output\r\n");
17 | //serial_printf("Testing input... type something and press enter\r\n");
18 | //serial_read(buff, 20);
19 | //serial_printf("\r\n");
20 | //serial_printf("You typed \"%s\"\r\n", buff);
21 |
22 | while(1);
23 | return 0;
24 | }
25 |
--------------------------------------------------------------------------------
/source/serial/usart.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "usart.h"
4 |
5 | static uint8_t append_char(char *, uint8_t, uint8_t, uint8_t);
6 |
7 | void serial_init(void) {
8 | // set baud rate
9 | uint16_t baud = BAUD_PRESCALLER;
10 | UBRR0H = (uint8_t)(baud >> 8 );
11 | UBRR0L = (uint8_t)baud;
12 |
13 | // enable received and transmitter
14 | UCSR0B = (1 << RXEN0) | (1 << TXEN0);
15 |
16 | // set frame format (8N1)
17 | UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);
18 | }
19 |
20 | void usart_send_byte(uint8_t byte) {
21 | // wait for empty transmit buffer
22 | while ( !(UCSR0A & (1 << UDRE0)) )
23 | ;
24 | // send byte
25 | UDR0 = byte;
26 | }
27 |
28 | // write a string to the usart
29 | void usart_print(char *s) {
30 | while (*s != 0)
31 | usart_send_byte( *(s++) );
32 | }
33 |
34 | uint8_t usart_data_available(void) {
35 | if ( UCSR0A & (1 << RXC0) )
36 | return 1;
37 | return 0;
38 | }
39 |
40 | uint8_t usart_recv_byte(void) {
41 | // wait until data is available
42 | while ( !usart_data_available() )
43 | ;
44 | // read byte
45 | return UDR0;
46 | }
47 |
48 | void usart_read_str(char *str, uint8_t max) {
49 | uint8_t k, eos, ch, ch2;
50 |
51 | k = 0; // index of first free position in the string
52 | eos = 0; // end of string, used as boolean
53 |
54 | while (!eos) {
55 | ch = usart_recv_byte();
56 |
57 | //if (ch == '\r' || ch == '\n') // user pressed enter
58 | if (ch == '\r') {
59 | ch2 = usart_recv_byte();
60 |
61 | if (ch2 == '\n')
62 | eos = 1;
63 | else {
64 | k = append_char(str, ch, k, max);
65 | k = append_char(str, ch2, k, max);
66 | }
67 | }
68 | //else if (ch == '\b') { // user pressed backspace
69 | // if (k > 0) {
70 | // usart_send_byte('\b'); // move cursor one char back
71 | // usart_send_byte(' '); // override char with a space
72 | // usart_send_byte('\b'); // move cursor one char back again
73 | // k--;
74 | // }
75 | //}
76 | else {
77 | //if (0x20 <= ch && ch <= 0x7e) // here we check for printable characters
78 | // usart_send_byte(ch);
79 | //if (k < max - 1) // -1 becase \0 at end
80 | // str[k++] = ch;
81 | k = append_char(str, ch, k, max);
82 | }
83 | }
84 |
85 | // terminate string accordingly
86 | str[k] = '\0';
87 | }
88 |
89 | static uint8_t append_char(char *str, uint8_t ch, uint8_t k, uint8_t max) {
90 | if (k < max - 1)
91 | str[k++] = ch;
92 | return k;
93 | }
94 |
--------------------------------------------------------------------------------
/source/serial/usart.h:
--------------------------------------------------------------------------------
1 | #ifndef USART_H
2 | #define USART_H
3 |
4 | #include
5 |
6 | # define USART_BAUDRATE 1000000
7 | # define BAUD_PRESCALLER ((( F_CPU / ( USART_BAUDRATE * 16UL))) - 1)
8 |
9 | void serial_init(void);
10 |
11 | void usart_send_byte(uint8_t);
12 | void usart_print(char *);
13 | uint8_t usart_data_available(void);
14 | uint8_t usart_recv_byte(void);
15 | void usart_read_str(char *, uint8_t);
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/source/serial/usartx.c:
--------------------------------------------------------------------------------
1 | /*
2 | * usartx.c USART code for an ATxmega-based single-board computer
3 | *
4 | * These routines provide support for stream I/O and can be hooked into
5 | * stdin, stdout, and stderr.
6 | *
7 | * This module provides support for all eight USARTs on the ATxmega128a1
8 | * and related devices. For details on using these routines, consult the
9 | * associated usart.h header file.
10 | *
11 | * This code has been developed and tested on an Atmel Xplained board, using
12 | * USARTD0 (header J3) as the serial device.
13 | *
14 | * This file can be built as a standalone library, provided you create a
15 | * suitable makefile. For testing purposes, I've included a small main()
16 | * function at the end of this file. You can build this file as a
17 | * standalone project, download it to an Xplained board, and use TeraTerm
18 | * (or other comm program) to exchange serial data with the Xplained board.
19 | */
20 |
21 | #include
22 | #include
23 | #include
24 | #include
25 |
26 | /*
27 | * This file must create the FILE objects, so define OWNER here.
28 | */
29 | #define OWNER
30 |
31 | #include "usartx.h"
32 |
33 |
34 | #ifndef STDIN_FILENO
35 | #define STDIN_FILENO 0
36 | #define STDOUT_FILENO 1
37 | #define STDERR_FILENO 2
38 | #endif
39 |
40 |
41 |
42 |
43 | #ifndef NUM_USARTS
44 | #define NUM_USARTS 8
45 | #endif
46 |
47 |
48 | /*
49 | * Create an array of pointers to the various USART I/O registers.
50 | */
51 | static USART_t *usart[NUM_USARTS] = {&USARTC0, &USARTC1, &USARTD0, &USARTD1,
52 | &USARTE0, &USARTE1, &USARTF0, &USARTF1};
53 |
54 | /*
55 | * Prototypes for the getchar and putchar functions for any USART.
56 | */
57 | static int USART_putchar(char c, FILE *stream) __attribute__((noinline));
58 | static int USART_getchar(FILE *stream) __attribute__((noinline));
59 |
60 |
61 | /*
62 | * Define the low-level FILEs used for stream I/O by the USARTs.
63 | *
64 | * These FILEs can be used to change the behavior of stdin, stdout,
65 | * and stderr. For example:
66 | *
67 | * stdin = &usartin;
68 | * stdout = &usartout;
69 | * stderr = &usartout;
70 | *
71 | * NOTE: In keeping with the comments in avr/stdio.h, the following FILE
72 | * implementations do NOT provide stream.size, stream.buf, stream.unget,
73 | * stream.flags, or stream.len! If you need support for these features,
74 | * you must provide them in code outside of any of the USART functions
75 | * defined in this library!
76 | *
77 | */
78 | FILE usartout = FDEV_SETUP_STREAM(USART_putchar, NULL, _FDEV_SETUP_WRITE);
79 | FILE usartin = FDEV_SETUP_STREAM(NULL, USART_getchar, _FDEV_SETUP_READ);
80 |
81 |
82 |
83 |
84 | /*
85 | * Define variables for holding the identifier for the USART currently connected
86 | * to a standard I/O stream.
87 | */
88 | static int usartsel_stdin = eUSARTC0; // defaults to USARTC0
89 | static int usartsel_stdout = eUSARTC0; // defaults to USARTC0
90 | static int usartsel_stderr = eUSARTC0; // defaults to USARTC0
91 |
92 |
93 |
94 |
95 | #define QUEUE_SIZE 64 /* MUST BE A POWER OF 2!! */
96 |
97 | /*
98 | * Define in and out pointers (actually, indices) for each of the queues associated
99 | * with a USART receiver. inptr[] holds the index into the queue where the next
100 | * received character will be added. outptr[] holds the index into the queue where
101 | * the next character will be extracted for passing to a calling program.
102 | */
103 | static volatile unsigned char inptr[NUM_USARTS] = {0, 0, 0, 0, 0, 0, 0, 0}; // index for adding chars to queue
104 | static volatile unsigned char outptr[NUM_USARTS] = {0, 0, 0, 0, 0, 0, 0, 0}; // index for pulling chars from queue
105 |
106 |
107 | /*
108 | * Define queues for handling chars received by each USART.
109 | */
110 | static volatile unsigned char queue[NUM_USARTS][QUEUE_SIZE];
111 |
112 |
113 |
114 | /*
115 | * Local functions
116 | */
117 | static void _rxcisr(int usartnum);
118 |
119 |
120 |
121 |
122 |
123 | /*
124 | * USART_Init() initialize hardware USARTs
125 | *
126 | * This code configures the USARTs for selected baud rate, eight data bits,
127 | * no parity, one stop bit. It also enables the USARTs' transmitter and
128 | * receiver, and enables receive interrupts.
129 | */
130 |
131 | void USART_Init(uint8_t usartnum, uint8_t bauda, uint8_t baudb)
132 | {
133 | USART_t *pusart;
134 |
135 | if (usartnum >= NUM_USARTS) return; // ignore if out of range
136 |
137 | pusart = usart[usartnum]; // point to selected USART I/O block
138 | switch (usartnum) // based on selected USART...
139 | {
140 | case eUSARTC0: // USARTC0
141 | PORTC_OUTSET = 0x08; // force TXD high
142 | PORTC_DIRSET = 0x08; // TXD is output
143 | PORTC_PIN3CTRL = 0x18; // pin is pulled high
144 | break;
145 |
146 | case eUSARTC1: // USARTC1
147 | PORTC_OUTSET = 0x80; // force TXD high
148 | PORTC_DIRSET = 0x80; // TXD is output
149 | PORTC_PIN7CTRL = 0x18; // pin is pulled high
150 | break;
151 |
152 | case eUSARTD0: // USARTD0
153 | PORTD_OUTSET = 0x08; // force TXD high
154 | PORTD_DIRSET = 0x08; // TXD is output
155 | PORTD_PIN3CTRL = 0x18; // pin is pulled high
156 | break;
157 |
158 | case eUSARTD1: // USARTD1
159 | PORTD_OUTSET = 0x80; // force TXD high
160 | PORTD_DIRSET = 0x80; // TXD is output
161 | PORTD_PIN7CTRL = 0x18; // pin is pulled high
162 | break;
163 |
164 | case eUSARTE0: // USARTE0
165 | PORTE_OUTSET = 0x08; // force TXD high
166 | PORTE_DIRSET = 0x08; // TXD is output
167 | PORTE_PIN3CTRL = 0x18; // pin is pulled high
168 | break;
169 |
170 | case eUSARTE1: // USARTE1
171 | PORTE_OUTSET = 0x80; // force TXD high
172 | PORTE_DIRSET = 0x80; // TXD is output
173 | PORTE_PIN7CTRL = 0x18; // pin is pulled high
174 | break;
175 |
176 | case eUSARTF0: // USARTF0
177 | PORTF_OUTSET = 0x08; // force TXD high
178 | PORTF_DIRSET = 0x08; // TXD is output
179 | PORTF_PIN3CTRL = 0x18; // pin is pulled high
180 | break;
181 |
182 | case eUSARTF1: // USARTF1
183 | PORTF_OUTSET = 0x80; // force TXD high
184 | PORTF_DIRSET = 0x80; // TXD is output
185 | PORTF_PIN7CTRL = 0x18; // pin is pulled high
186 | break;
187 |
188 | default: // should never happen!
189 | break;
190 | }
191 |
192 | pusart->CTRLA = USART_RXCINTLVL_HI_gc; // enable RX interrupts, high level
193 | pusart->CTRLB = USART_CLK2X_bm; // turn on 2x clock, 8 data bits, rcv and xmt disabled
194 | pusart->CTRLC = USART_CHSIZE0_bm + USART_CHSIZE1_bm; // set for 8-bit, 1 stop, no parity
195 |
196 | pusart->BAUDCTRLB = baudb; // do this reg first!
197 | pusart->BAUDCTRLA = bauda; // set up the baud rate
198 |
199 |
200 | pusart->CTRLB = pusart->CTRLB | (USART_RXEN_bm | USART_TXEN_bm); // enable rcv and xmt
201 | }
202 |
203 |
204 |
205 |
206 | /*
207 | * USART_Connect() assign an USART to one of the standard I/O streams
208 | */
209 | void USART_Connect(int usartnum, int streamsel)
210 | {
211 |
212 | if (usartnum >= NUM_USARTS) return; // illegal USART selector, ignore
213 |
214 | if (streamsel == STDIN_FILENO) usartsel_stdin = usartnum;
215 | else if (streamsel == STDOUT_FILENO) usartsel_stdout = usartnum;
216 | else if (streamsel == STDERR_FILENO) usartsel_stderr = usartnum;
217 | else return;
218 | }
219 |
220 |
221 |
222 |
223 |
224 |
225 | /*
226 | * kbhit() replaces the old DOS check-for-char routine; returns TRUE if char available
227 | */
228 | int kbhit(void)
229 | {
230 | return (inptr[usartsel_stdin] - outptr[usartsel_stdin]); // could be negative, but will always be 0 if no chars
231 | }
232 |
233 |
234 |
235 |
236 | /*
237 | * getchne() return char without echo; blocks until char is available
238 | */
239 | int getchne(void)
240 | {
241 | if (stdin) return stdin->get(stdin);
242 | else return EOF;
243 | }
244 |
245 |
246 |
247 |
248 | /*
249 | * getche() return char with echo; blocks until char is available
250 | */
251 | int getche(void)
252 | {
253 | int c;
254 |
255 | c = getchne();
256 | if (c != EOF) putchar(c);
257 | return c;
258 | }
259 |
260 |
261 |
262 |
263 | /*
264 | * getsedit() return string from stdin; allows editing by user until Enter
265 | *
266 | * str is the buffer where the incoming chars will be stored.
267 | *
268 | * knt is the maximum number of characters to accept; overwrites char at knt-1
269 | * if user enters too many chars.
270 | *
271 | * func is pointer to callback function that will be invoked as this routine
272 | * waits for a character; use NULL if you want this routine to lock until
273 | * the string is entered.
274 | */
275 | unsigned char getsedit(char *str, uint8_t knt, void (*func)(void))
276 | {
277 | char *ptr;
278 | unsigned char k;
279 | int c;
280 |
281 | ptr = str; // get a copy of the buffer addr
282 | *ptr = 0; // keep the string legal
283 | k = 0; // show no chars yet
284 |
285 | while (1) // do forever...
286 | {
287 | if (func) func(); // if user supplied a background function, call it
288 | if (kbhit()) // if char available now...
289 | {
290 | c = getchne(); // get a char
291 | switch (c) // based on the char...
292 | {
293 | case '\b': // if backspace...
294 | if (k>0) // if any chars in the buffer...
295 | {
296 | putchar('\b'); // back up to prev char
297 | putchar(' '); // erase the old char
298 | putchar('\b'); // now back up one
299 | ptr--; // back up one
300 | k--; // keep the books straight
301 | }
302 | break;
303 |
304 | case '\n': // terminating char?
305 | return k; // all ready, just leave
306 |
307 | // for the purpose of exploitation :)
308 | //case EOF: // should never happen!
309 | //return k; // is this right??
310 |
311 | default: // for all other chars...
312 | if ( // if printable
313 | ('A' <= c && c <= 'Z') ||
314 | ('a' <= c && c <= 'z') ||
315 | ('0' <= c && c <= '9')
316 | )
317 | putchar(c); // print the char
318 |
319 | if (k < (knt-1)) // if we still have room...
320 | {
321 | *ptr = (c & 0xff); // save the char
322 | ptr++; // move to next cell
323 | k++; // count this char
324 | }
325 | else // no more room
326 | {
327 | *(ptr-1) = (c & 0xff); // overwrite prev char with latest char
328 | }
329 | break;
330 | }
331 | *ptr = 0; // always make sure string is terminated
332 | }
333 | }
334 | }
335 |
336 | #define F_PER F_CPU
337 | #define BSEL_38400 ((F_PER/(8*38400))-1) /* 2x clock, 38400 baud */
338 | #define BAUDA_38400 ((BSEL_38400) & 0xff)
339 | #define BAUDB_38400 ((BSEL_38400 >> 8) | 0) /* BSCALE of 0 */
340 |
341 |
342 | void serial_init(void) {
343 |
344 | /*
345 | * 32 MHz internal oscillator setup
346 | */
347 | OSC.CTRL |= OSC_RC32MEN_bm;
348 | while (!(OSC.STATUS & OSC_RC32MRDY_bm));
349 | CCP = CCP_IOREG_gc;
350 | CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
351 | OSC.CTRL &= (~OSC_RC2MEN_bm); // disable RC2M
352 | PORTCFG.CLKEVOUT = (PORTCFG.CLKEVOUT & (~PORTCFG_CLKOUT_gm)) | PORTCFG_CLKOUT_OFF_gc; // disable peripheral clock
353 |
354 | /*
355 | * Set up USART 2 (USARTD0) as stdin, stderr, and stdout. Set baud rate, then connect the
356 | * USART to the standard streams.
357 | */
358 | USART_Init(eUSARTD1, BAUDA_38400, BAUDB_38400); // init USARTD0 to 38400, 8N1
359 |
360 | USART_Connect(eUSARTD1, STDOUT_FILENO); // use USARTD0 for stdout
361 | USART_Connect(eUSARTD1, STDIN_FILENO); // use USARTD0 for stdin
362 | USART_Connect(eUSARTD1, STDERR_FILENO); // use USARTD0 for stderr
363 |
364 | stdout = &usartout; // connect stdout to the USART drivers
365 | stdin = &usartin; // connect stdin to the USART drivers
366 | stderr = &usartout; // connect stderr to the USART drivers
367 |
368 | /*
369 | * Enable all interrupts (needed for support of the receive interrupt.
370 | */
371 | PMIC.CTRL = (PMIC_HILVLEX_bm | PMIC_MEDLVLEX_bm | PMIC_LOLVLEX_bm); // unmask all levels
372 | asm("sei");
373 | }
374 |
375 | /*
376 | * USART_putchar() write char c to selected stream
377 | *
378 | * If stream is not stdout or stderr, call is ignored.
379 | */
380 | static int USART_putchar(char c, FILE *stream)
381 | {
382 | USART_t *ptr;
383 |
384 | if (stream == stdout) ptr = usart[usartsel_stdout]; // point to active stdout USART
385 | else if (stream == stderr) ptr = usart[usartsel_stdout]; // point to active stderr USART
386 | else return 0; // is this right?
387 |
388 | while ((ptr->STATUS & USART_DREIF_bm) == 0) ; // spin until ready to send
389 | ptr->DATA = c; // send the char to selected USART
390 | return 0;
391 | }
392 |
393 |
394 |
395 |
396 | /*
397 | * USART_getchar() read a char from the selected stream
398 | *
399 | * If the stream is not stdin, call is ignored.
400 | */
401 | static int USART_getchar(FILE *stream)
402 | {
403 | int n;
404 | int c;
405 |
406 | if (stream != stdin) return 0; // is this right?
407 |
408 | n = usartsel_stdin; // shorthand
409 | while (inptr[n] == outptr[n]) ; // spin until char is available...
410 | c = queue[n][outptr[n]]; // pull char
411 | outptr[n]++; // move to next cell
412 | outptr[n] = outptr[n] & (QUEUE_SIZE-1); // keep it legal
413 | if (c == '\r') c = '\n'; // convert CRs to LFx
414 | return c;
415 | }
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 | /*
424 | * _rxcisr() low-level USART receive-char interrupt processor
425 | *
426 | * This routine is ONLY to be called by one of the recieve-char ISRs
427 | * below!
428 | *
429 | * This routine updates the receive queue for the selected USART, based
430 | * on the USART selecter passed as argument usartnum.
431 | *
432 | * If a queue overflows, the oldest char is lost.
433 | */
434 | static void _rxcisr(int usartnum)
435 | {
436 | USART_t *pusart;
437 |
438 | pusart = usart[usartnum]; // point to correct USART
439 | queue[usartnum][inptr[usartnum]] = pusart->DATA; // grab the data
440 | inptr[usartnum]++; // move to next queue slot
441 | inptr[usartnum] = inptr[usartnum] & (QUEUE_SIZE-1); // keep it legal
442 | if (inptr[usartnum] == outptr[usartnum]) // if caught up with outptr...
443 | {
444 | outptr[usartnum]++; // guess we lose the oldest char!
445 | outptr[usartnum] = outptr[usartnum] & (QUEUE_SIZE-1);
446 | }
447 | }
448 |
449 |
450 |
451 |
452 | /*
453 | * These are the eight ISRs used to support receive-char interrupts for
454 | * each USART.
455 | *
456 | * In every case, the ISR invokes _rxcisr() above with the enum associated
457 | * with that ISR's USART.
458 | */
459 |
460 | ISR(USARTC0_RXC_vect)
461 | {
462 | _rxcisr(eUSARTC0);
463 | }
464 |
465 |
466 | ISR(USARTC1_RXC_vect)
467 | {
468 | _rxcisr(eUSARTC1);
469 | }
470 |
471 |
472 | ISR(USARTD0_RXC_vect)
473 | {
474 | _rxcisr(eUSARTD0);
475 | }
476 |
477 |
478 | ISR(USARTD1_RXC_vect)
479 | {
480 | _rxcisr(eUSARTD1);
481 | }
482 |
483 |
484 | ISR(USARTE0_RXC_vect)
485 | {
486 | _rxcisr(eUSARTE0);
487 | }
488 |
489 |
490 | ISR(USARTE1_RXC_vect)
491 | {
492 | _rxcisr(eUSARTE1);
493 | }
494 |
495 |
496 | ISR(USARTF0_RXC_vect)
497 | {
498 | _rxcisr(eUSARTF0);
499 | }
500 |
501 |
502 | ISR(USARTF1_RXC_vect)
503 | {
504 | _rxcisr(eUSARTF1);
505 | }
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 | /*
516 | * ----------------------------------------------------------------------
517 | *
518 | * Temporary main(), used to test USART modules. Comment this out before
519 | * building the USART library modules.
520 | */
521 |
522 |
523 | #if DEBUG
524 |
525 | void noop(void); // dummy background function for call for getsedit
526 |
527 | int main(void)
528 | {
529 | char buff[128];
530 |
531 | serial_init();
532 |
533 |
534 | /*
535 | * Announce ourselves.
536 | */
537 | printf("\n\rATXmega USART demo\n\r");
538 |
539 |
540 | /*
541 | * Loop forever, reading a line from stdin (with editing), then echoing
542 | * that line to stdout and stderr.
543 | */
544 | while (1)
545 | {
546 | printf("\n\r> ");
547 | getsedit(buff, 127, noop); // this reads from stdin, echos to stdout
548 | printf("\n\r %s\n\r", buff); // this writes to stdout
549 | fprintf(stderr, "STDERR: %s", buff); // this writes to stderr
550 | }
551 | }
552 |
553 |
554 |
555 | /*
556 | * noop() this is a dummy background function, used in invoking getsedit() above
557 | */
558 | void noop(void)
559 | {
560 | volatile int n;
561 |
562 | n = 3;
563 | }
564 |
565 |
566 |
567 | #endif
568 |
--------------------------------------------------------------------------------
/source/serial/usartx.h:
--------------------------------------------------------------------------------
1 | /*
2 | * uartx.h header file for UART support for the atmega1284p
3 | */
4 |
5 | #ifndef UARTX_H
6 | #define UARTX_H
7 |
8 | /*
9 | * Only the file that defines OWNER creates the FILE objects below.
10 | */
11 | #ifdef OWNER
12 | #define EXTERN
13 | #else
14 | #define EXTERN extern
15 | #endif
16 |
17 |
18 |
19 | /*
20 | * Define enums for selecting one of the eight USARTS.
21 | */
22 | enum usart_ids // these are local-only indices into the queue, inptr, and outptr arrays
23 | {
24 | eUSARTC0 = 0,
25 | eUSARTC1,
26 | eUSARTD0,
27 | eUSARTD1,
28 | eUSARTE0,
29 | eUSARTE1,
30 | eUSARTF0,
31 | eUSARTF1
32 | };
33 |
34 |
35 |
36 |
37 | /*
38 | * USART_Init() initialize hardware USARTs
39 | *
40 | * This routine configures the USARTs for selected baud rate, eight data bits,
41 | * no parity, one stop bit. It also enables the USARTs' transmitter and
42 | * receiver, and enables receive interrupts.
43 | *
44 | * This function also assigns stdin, stdout, and stderr to UART0 (see FILE
45 | * definitions below).
46 | *
47 | * Note that the arguments bauda and baudb must contain the actual
48 | * value to write to the USART's baud rate registers, NOT the desired baud
49 | * rate!
50 | */
51 | void USART_Init(uint8_t usartnum, uint8_t bauda, uint8_t baudb);
52 |
53 |
54 |
55 | /*
56 | * USART_Connect() assign an USART to one of the standard I/O streams
57 | *
58 | * This routine associates a selected USART to one of the standard I/O streams.
59 | * The association is made using argument usartnum, which can range from 0 to
60 | * 7 and corresponds to the usart_ids enum above.
61 | *
62 | * Argument streamsel is one of the standard I/O stream identifiers (STDIN_FILENO,
63 | * STDOUT_FILENO, or STDERR_FILENO).
64 | *
65 | * After calling this routine, any standard I/O function, such as printf(), will
66 | * use the associated USART until the connection is changed with a later call
67 | * to this routine.
68 | */
69 | void USART_Connect(int usartnum, int streamsel);
70 |
71 |
72 |
73 | /*
74 | * Legacy routines for console I/O.
75 | *
76 | * kbhit(), getchne(), and getche() talk only to the stdin stream. These
77 | * routines are commonly available on the old DOS systems and there isn't
78 | * anything in the C standard that provides corresponding functionality.
79 | */
80 |
81 | /*
82 | * kbhit() test for character available on stdin
83 | *
84 | * This routine returns TRUE if at least one character is available from
85 | * the stdin stream, else it returns FALSE.
86 | */
87 | int kbhit(void);
88 |
89 |
90 | /*
91 | * getchne() get character from stdin, do not echo
92 | *
93 | * This routine locks until a character is available from stdin. This
94 | * routine then returns the character to the calling routine without
95 | * echoing that character to stdout.
96 | */
97 | int getchne(void);
98 |
99 |
100 | /*
101 | * getche() get character from stdin, echo char to stdout
102 | *
103 | * This routine locks until a character is available from stdin. This
104 | * routine echoes the character to stdout, then returns the character
105 | * to the calling routine.
106 | */
107 | int getche(void);
108 |
109 | void serial_init(void);
110 |
111 |
112 | /*
113 | * getsedit get string (editable) from stdin, echo to stdout
114 | *
115 | * This routine reads characters from stdin and echos those chars to
116 | * stdout. The routine accepts editing characters, such as backspace,
117 | * and modifies the string at each keystroke. The routine allows the
118 | * caller to specify a callback function; this callback function is
119 | * always invoked whenever stdin is polled for a character and no
120 | * character is available.
121 | *
122 | * Argument buff points to an array of char that holds the characters
123 | * entered by the user.
124 | *
125 | * Argument knt holds the maximum number of characters to accept,
126 | * plus one (limit of 254).
127 | *
128 | * Argument func points to a void function that acts as a callback
129 | * function. This callback function, if not NULL, will be called
130 | * each time getsedit() checks stdin for a keypress.
131 | *
132 | * Upon exit, the array at buff will hold all accepted chars plus a
133 | * terminating null; the CR entered by the user to terminate input will
134 | * NOT appear in the string!
135 | *
136 | * This routine returns the number of characters accepted, excluding the
137 | * CR (essentially, it returns strlen(buff)).
138 | */
139 | unsigned char getsedit(char *buff, uint8_t knt, void (*func)(void));
140 |
141 |
142 |
143 |
144 | #endif
145 |
--------------------------------------------------------------------------------
/source/upload.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | set -e
4 |
5 | #./build.sh
6 |
7 | # avrdude flag meanings:
8 | # -p part no (avr chip type); use ? to get a list of values
9 | # -c programmer; use ? to get a list of values
10 | # -P serial port
11 | # -b baud rate
12 | # -e erase chip
13 | # -V do not verify
14 | # -u disable safemode
15 | # -U memory operation
16 |
17 | # upload via programmer
18 | avrdude -p m328p -c avrispmkII -e -u -U flash:w:main/ctf.hex -P usb
19 | avrdude -p m328p -c avrispmkII -u -U lock:w:0x3c:m -P usb
20 |
21 | # upload via bootloader
22 | #avrdude -p m328p -c arduino -P /dev/ttyUSB0 -b 57600 -e -V -u -U flash:w:main/ctf.hex
23 |
24 | # check if board is alive
25 | python check_board.py /dev/ttyUSB0
26 | if [[ $? == 0 ]]; then
27 | echo 'Board is alive'
28 | else
29 | echo 'Board is dead'
30 | fi
31 |
--------------------------------------------------------------------------------
/source/variables/build.sh:
--------------------------------------------------------------------------------
1 | #! /bin/bash
2 |
3 | set -euo pipefail
4 |
5 | avr-gcc $GCC_COMPILE_FLAGS $GCC_OPTIMIZATION_FLAG $INC_PATH -c variables.c
6 |
7 | echo "$(pwd)/variables.o"
8 |
--------------------------------------------------------------------------------
/source/variables/variables.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "serial_io.h"
7 |
8 | char user_auth_response[9];
9 |
10 | const char *variables[7][2] = {
11 | { "Terminal name", "Erucsir007" },
12 | { "Accounts", "Enabled (2/2), Active (2/2)" },
13 | { "Operational mode", "Enabled" },
14 | { "Debug mode", "Enabled" },
15 | { "Physical location", "Delft, Netherlands" },
16 | { "User authentication token", user_auth_response },
17 | { "Hello", "World!" } // this one is just to mess with people :)
18 | };
19 |
20 | void variables_menu(uint8_t k) {
21 | uint8_t i;
22 |
23 | for (i = 0; i < k; i++)
24 | if ( isalpha(variables[i][0][0]) )
25 | serial_printf("%-30s %s\r\n", variables[i][0], variables[i][1]);
26 |
27 | serial_printf("%S", PSTR("Finished printing\r\n"));
28 | }
29 |
--------------------------------------------------------------------------------
/source/variables/variables.h:
--------------------------------------------------------------------------------
1 | #ifndef VARIABLES_H
2 | #define VARIABLES_H
3 |
4 | #include
5 |
6 | void variables_menu(uint8_t);
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------