Compare commits
344 Commits
Author | SHA1 | Date | |
---|---|---|---|
89769ecc18 | |||
3b3f47bfcf | |||
6fa443b0bc | |||
893d4131b2 | |||
4e21c0bd8f | |||
251eb6bf64 | |||
08e236df69 | |||
d2091563ab | |||
54a6a82ca0 | |||
40b9dae38a | |||
98a209e330 | |||
d3b5fb68ee | |||
74a1f0e21b | |||
e21172fff8 | |||
9d3144e9b1 | |||
a2a774125f | |||
349ea5343a | |||
c851807376 | |||
84d1629aa3 | |||
8f6ae29163 | |||
a0d27c2c56 | |||
3a10427bd9 | |||
f3b591e570 | |||
175f59d206 | |||
f5ff6a11f0 | |||
d979420324 | |||
5076af1be4 | |||
0a7845459c | |||
c4262b0f5b | |||
53fb0059a7 | |||
a1a75e4ab5 | |||
d68011ef04 | |||
02e83073e0 | |||
3a48756f96 | |||
946e932b1e | |||
142d4002e5 | |||
dbe5283e1f | |||
2d233f164e | |||
b62e9906c7 | |||
e22e636475 | |||
074225d87a | |||
bb9b2ea9d4 | |||
e8d5bc5829 | |||
850381a633 | |||
ce3ad0e56f | |||
00d86379e5 | |||
6098810167 | |||
821880a8d6 | |||
44f96f5843 | |||
6ec9fb962a | |||
c9bfe001ee | |||
5e46fd96ac | |||
103cc3cfb0 | |||
9544330dc3 | |||
0964ff69b7 | |||
e4a2b9e1ca | |||
d29fa34da1 | |||
6ed2610a5c | |||
3b9d4e5023 | |||
2da083c18a | |||
50bfbc1eff | |||
86739df7a1 | |||
c7f0d050d7 | |||
b79670a447 | |||
169ba59ed4 | |||
f3003c58c9 | |||
084e518018 | |||
6674f0a8ff | |||
f704851419 | |||
0d5e1ee872 | |||
5cb81c753d | |||
b0b0564df9 | |||
195dc2a8ae | |||
4982b13f64 | |||
63a93f6ec2 | |||
7b8ec18e76 | |||
67faef0117 | |||
0b9f0af3c7 | |||
880d54a4f0 | |||
1507758ad1 | |||
e883c5aa6e | |||
afc85e0d2e | |||
a40dcf3f17 | |||
4b82e80d7a | |||
246dea8a44 | |||
7a98764a5b | |||
dc946f5b35 | |||
0232893611 | |||
5995f84822 | |||
1ff00895b1 | |||
83641b3789 | |||
9b356076c5 | |||
6c96521c7d | |||
35707c3797 | |||
e31e703afd | |||
3a8be9eef7 | |||
e2b30ec087 | |||
495e10f3a1 | |||
11ca6bd517 | |||
a265da09fb | |||
1b4d1be9ee | |||
32f2436380 | |||
7255c4f8db | |||
4e215db42a | |||
a1ad641076 | |||
daf56b0cc7 | |||
5859073cb8 | |||
ff5207ba77 | |||
324b4a89cc | |||
9f60caf9c1 | |||
0865f2a660 | |||
b1c72c9d94 | |||
5e70c11b54 | |||
46ada5a8b9 | |||
0eac67259d | |||
9399a5f195 | |||
47aa287480 | |||
865b698bed | |||
14974e0ebe | |||
1ed7833c9f | |||
e8d0ad5e7c | |||
e2ca7f52db | |||
c97b9f9b8f | |||
ecf994b647 | |||
347d0942b1 | |||
ff0d42c8d5 | |||
a6673b0917 | |||
0c296bba30 | |||
57930aaa13 | |||
1a6895ca25 | |||
54241ecd42 | |||
e537d00173 | |||
a195408a11 | |||
54b7f42056 | |||
6128e86da2 | |||
fed9f473aa | |||
f6ff3c1b87 | |||
afd3218358 | |||
ed6da0ba1e | |||
46d7be865d | |||
596c6c1077 | |||
6c3014575f | |||
190ecc8fd8 | |||
0d2e03a5a9 | |||
991530f88b | |||
de31924be3 | |||
6b97807f51 | |||
35022775cd | |||
6fecb3c035 | |||
3fed8cebdf | |||
c81bc9fb98 | |||
99f09790f1 | |||
6745c9a0cb | |||
0651316da5 | |||
f48becc6dc | |||
85c58e9d5b | |||
c9862977bf | |||
1a40299dcb | |||
8f9ff17bef | |||
9e9d26e604 | |||
b3d76d56e0 | |||
13424fdbcd | |||
2327247c29 | |||
85004370b7 | |||
8f6f8a34e1 | |||
f0f0aaaaa4 | |||
5fddde240f | |||
b212c71da6 | |||
1ea4a2776b | |||
41f1d5efed | |||
6e497ad04e | |||
34fb8c9c24 | |||
8386ae56d2 | |||
d38d3a8342 | |||
ce364e5e87 | |||
c482d6cc74 | |||
2cb96cb793 | |||
a32bea2697 | |||
7df402a20a | |||
650e0b26cc | |||
831976f3a2 | |||
e7e83820a9 | |||
8dd211d557 | |||
747d9a194d | |||
bfd8827073 | |||
ce92c7634e | |||
f97d9ab34f | |||
a2611fb013 | |||
3b320e0aeb | |||
f2d0e3d275 | |||
c1631c7172 | |||
259020ece0 | |||
589b17c596 | |||
ad4e526497 | |||
f005ea438c | |||
2615fd39ac | |||
eba9ce8475 | |||
a4f01c3f23 | |||
c2342834dd | |||
be212fd8b1 | |||
ee817ea8bb | |||
6c6f0a0068 | |||
5862a8a5ac | |||
a966ea3a58 | |||
eed418ea33 | |||
9a037279c8 | |||
727e1f2fd9 | |||
5afdef463e | |||
1dd835d698 | |||
400b37a96a | |||
23c140fd99 | |||
894f6f7ee1 | |||
b9e6d552f8 | |||
828a8fc0b5 | |||
45eaef2663 | |||
ed676151f1 | |||
45da2f0b32 | |||
6c23532f08 | |||
bc8984aac3 | |||
020fe21546 | |||
9957a83746 | |||
72bca0765a | |||
ba4f9ed7ae | |||
eb2d377ffb | |||
8303bb04d3 | |||
d23bf0a144 | |||
a6446e67bc | |||
529b879c08 | |||
2893cd7ce3 | |||
0634510b92 | |||
858545c0c8 | |||
120fb95541 | |||
665e84d183 | |||
13d9885da4 | |||
e230a9464e | |||
342af18b1f | |||
be9bd941c8 | |||
0f6be6740b | |||
9054736e0e | |||
c6d946136e | |||
32400c8d09 | |||
587c9aad14 | |||
c624a32ef6 | |||
3005a63938 | |||
f470e9a9cd | |||
e3971a5e0f | |||
2ed8667f18 | |||
765d532f82 | |||
ca05385513 | |||
5328610ff1 | |||
bc1bb3509f | |||
375db69e3a | |||
771fffe329 | |||
4611f05051 | |||
e657e26886 | |||
3ffcc47374 | |||
102f2f261b | |||
24d8abf820 | |||
449faea7d3 | |||
1b5e230d45 | |||
81a89ed6aa | |||
ca2074de36 | |||
ee98340a03 | |||
3d0d91fa5c | |||
38171dba06 | |||
4ba57ccc85 | |||
c3bddee814 | |||
b7bc50bc4f | |||
19627a959a | |||
429e4b2a77 | |||
6e5de7bd6b | |||
c6daa4acc9 | |||
ab01d0c73d | |||
0ef42b2df7 | |||
f6e2bfa683 | |||
5c8acdd666 | |||
e996d470f9 | |||
4c36a752cb | |||
e2e29492e6 | |||
5f637992b1 | |||
91d092a27a | |||
23cbfde312 | |||
cce25b2a1c | |||
f24058d2e8 | |||
4c941997b4 | |||
37f1790028 | |||
91066292ae | |||
1ffe85f083 | |||
2049020b92 | |||
7a6abdfd0c | |||
ff4cb32bc3 | |||
1857482617 | |||
2feef8b043 | |||
3eddfbf8a9 | |||
a662a9a619 | |||
1a656d60e4 | |||
e235402fb8 | |||
6ca9f1946b | |||
df671775ba | |||
3ba83f6407 | |||
ffa4225827 | |||
cde6bc107a | |||
15de8dc4a6 | |||
94fe58d020 | |||
e8634a2d61 | |||
67b0abde4b | |||
d713167ec4 | |||
45888c9a25 | |||
d02206ba09 | |||
ad9186c13b | |||
4e0dc15dfd | |||
a75d272f4a | |||
15c3383249 | |||
c556fcd8c3 | |||
b4bfe5e3b9 | |||
29d4d88259 | |||
7bd5f29a79 | |||
a72f5029dc | |||
81e58a92f2 | |||
c3b4806e85 | |||
dffc1833cb | |||
31538faab1 | |||
1866d366fb | |||
dcf7940b3d | |||
1874e11fba | |||
302ce75ce6 | |||
178c25710b | |||
62cd7cc728 | |||
20f8aac768 | |||
5806b25fd1 | |||
4110434e33 | |||
8c103be5c0 | |||
f38b29256b | |||
121070822f | |||
96f65be9c2 | |||
78c40976c3 | |||
aa978abfc7 | |||
b7c0e4ea92 | |||
6ffba7d472 | |||
c330346c31 | |||
eda26e3c93 | |||
ca27b26c6b | |||
44077a4f2f | |||
4c6f0969c1 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -74,9 +74,12 @@ tools/python-fido2/*
|
||||
*.key
|
||||
site/
|
||||
_site/
|
||||
venv/
|
||||
env2/
|
||||
env3/
|
||||
.project
|
||||
.tags*
|
||||
targets/*/docs/
|
||||
main
|
||||
|
||||
builds/*
|
||||
|
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -1,9 +1,6 @@
|
||||
[submodule "tinycbor"]
|
||||
path = tinycbor
|
||||
url = https://github.com/intel/tinycbor
|
||||
[submodule "python-fido2"]
|
||||
path = python-fido2
|
||||
url = https://github.com/solokeys/python-fido2
|
||||
[submodule "crypto/micro-ecc"]
|
||||
path = crypto/micro-ecc
|
||||
url = https://github.com/kmackay/micro-ecc.git
|
||||
@ -13,3 +10,6 @@
|
||||
[submodule "targets/stm32l442/dfuse-tool"]
|
||||
path = targets/stm32l442/dfuse-tool
|
||||
url = https://github.com/solokeys/dfuse-tool
|
||||
[submodule "crypto/cifra"]
|
||||
path = crypto/cifra
|
||||
url = https://github.com/solokeys/cifra.git
|
||||
|
11
.travis.yml
11
.travis.yml
@ -1,4 +1,4 @@
|
||||
dist: trusty
|
||||
dist: xenial
|
||||
language: c
|
||||
compiler: gcc
|
||||
addons:
|
||||
@ -7,6 +7,13 @@ addons:
|
||||
- ubuntu-toolchain-r-test
|
||||
packages:
|
||||
- gcc-7
|
||||
- cppcheck
|
||||
before_install:
|
||||
- sudo add-apt-repository -y ppa:team-gcc-arm-embedded/ppa
|
||||
- sudo apt-get update -q
|
||||
- sudo apt-get install -y gcc-arm-embedded
|
||||
- sudo apt-get install -y python3-venv
|
||||
script:
|
||||
- export CC=gcc-7
|
||||
- make test
|
||||
- pyenv shell 3.6.7
|
||||
- make travis
|
||||
|
@ -1,6 +0,0 @@
|
||||
# Solo
|
||||
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", ATTRS{product}=="Solo", TAG+="uaccess", GROUP="plugdev", SYMLINK+="solokey"
|
||||
ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", ATTRS{product}=="Solo HACKER (Unlocked)", TAG+="uaccess", GROUP="plugdev", SYMLINK+="solohacker"
|
||||
|
||||
# U2F Zero
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="8acf", TAG+="uaccess", GROUP="plugdev", SYMLINK+="u2fzero"
|
1
99-solo.rules
Symbolic link
1
99-solo.rules
Symbolic link
@ -0,0 +1 @@
|
||||
udev/70-solokeys-access.rules
|
1
ALPHA_VERSION
Normal file
1
ALPHA_VERSION
Normal file
@ -0,0 +1 @@
|
||||
2.0.0
|
27
CHANGELOG.md
Normal file
27
CHANGELOG.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Changelog
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.1.0] - 2019-02-17
|
||||
### Added
|
||||
- Code cleanup
|
||||
- Buffer over-read bug fix
|
||||
- U2F counter endianness bug fix
|
||||
- More testing
|
||||
- Extension interface to U2F and FIDO2
|
||||
- Read firmware version
|
||||
- Read RNG bytes
|
||||
|
||||
## [1.1.1] - 2019-03-01
|
||||
|
||||
- This version fixes an incorrect error code returned in U2F.
|
||||
|
||||
## [2.0.0] - 2019-03-01
|
||||
|
||||
- Merge of NFC functionality branch
|
||||
- Bug fix with compiled USB name being too long causing buffer overrun
|
||||
- Change upper byte of counter from `0xff` to `0x7f` to fix issues with some websites.
|
33
Dockerfile
Normal file
33
Dockerfile
Normal file
@ -0,0 +1,33 @@
|
||||
FROM debian:stretch-slim
|
||||
MAINTAINER SoloKeys <hello@solokeys.com>
|
||||
|
||||
RUN apt-get update -qq
|
||||
RUN apt-get install -qq bzip2 git make wget >/dev/null
|
||||
|
||||
# 1. ARM GCC: for compilation
|
||||
RUN wget -q -O gcc.tar.bz2 https://developer.arm.com/-/media/Files/downloads/gnu-rm/8-2018q4/gcc-arm-none-eabi-8-2018-q4-major-linux.tar.bz2?revision=d830f9dd-cd4f-406d-8672-cca9210dd220?product=GNU%20Arm%20Embedded%20Toolchain,64-bit,,Linux,8-2018-q4-major
|
||||
# from website
|
||||
RUN echo "f55f90d483ddb3bcf4dae5882c2094cd gcc.tar.bz2" > gcc.md5
|
||||
RUN md5sum -c gcc.md5
|
||||
# self-generated
|
||||
RUN echo "fb31fbdfe08406ece43eef5df623c0b2deb8b53e405e2c878300f7a1f303ee52 gcc.tar.bz2" > gcc.sha256
|
||||
RUN sha256sum -c gcc.sha256
|
||||
RUN tar -C /opt -xf gcc.tar.bz2
|
||||
|
||||
# 2. Python3.7: for solo-python (merging etc.)
|
||||
RUN wget -q -O miniconda.sh https://repo.anaconda.com/miniconda/Miniconda3-4.5.12-Linux-x86_64.sh
|
||||
# from website
|
||||
RUN echo "866ae9dff53ad0874e1d1a60b1ad1ef8 miniconda.sh" > miniconda.md5
|
||||
RUN md5sum -c miniconda.md5
|
||||
# self-generated
|
||||
RUN echo "e5e5b4cd2a918e0e96b395534222773f7241dc59d776db1b9f7fedfcb489157a miniconda.sh" > miniconda.sha256
|
||||
RUN sha256sum -c miniconda.sha256
|
||||
|
||||
RUN bash ./miniconda.sh -b -p /opt/conda
|
||||
RUN ln -s /opt/conda/bin/python /usr/local/bin/python3
|
||||
RUN ln -s /opt/conda/bin/python /usr/local/bin/python
|
||||
RUN ln -s /opt/conda/bin/pip /usr/local/bin/pip3
|
||||
RUN ln -s /opt/conda/bin/pip /usr/local/bin/pip
|
||||
|
||||
# 3. Source code
|
||||
RUN git clone --recurse-submodules https://github.com/solokeys/solo /solo --config core.autocrlf=input
|
620
LICENSE
620
LICENSE
@ -1,619 +1 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
Apache-2.0 OR MIT
|
||||
|
201
LICENSE-APACHE
Normal file
201
LICENSE-APACHE
Normal file
@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
23
LICENSE-MIT
Normal file
23
LICENSE-MIT
Normal file
@ -0,0 +1,23 @@
|
||||
Permission is hereby granted, free of charge, to any
|
||||
person obtaining a copy of this software and associated
|
||||
documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without
|
||||
limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software
|
||||
is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice
|
||||
shall be included in all copies or substantial portions
|
||||
of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
107
Makefile
107
Makefile
@ -9,11 +9,10 @@
|
||||
|
||||
ecc_platform=2
|
||||
|
||||
EFM32_DEBUGGER= -s 440083537 --device EFM32JG1B200F128GM32
|
||||
#EFM32_DEBUGGER= -s 440121060 #dev board
|
||||
src = $(wildcard pc/*.c) $(wildcard fido2/*.c) $(wildcard fido2/extensions/*.c) \
|
||||
$(wildcard crypto/sha256/*.c) crypto/tiny-AES-c/aes.c
|
||||
|
||||
src = $(wildcard pc/*.c) $(wildcard fido2/*.c) $(wildcard crypto/sha256/*.c) crypto/tiny-AES-c/aes.c
|
||||
obj = $(src:.c=.o) uECC.o
|
||||
obj = $(src:.c=.o) crypto/micro-ecc/uECC.o
|
||||
|
||||
LIBCBOR = tinycbor/lib/libtinycbor.a
|
||||
|
||||
@ -23,9 +22,20 @@ else
|
||||
export LDFLAGS = -Wl,--gc-sections
|
||||
endif
|
||||
LDFLAGS += $(LIBCBOR)
|
||||
CFLAGS = -O2 -fdata-sections -ffunction-sections
|
||||
|
||||
VERSION:=$(shell git describe --abbrev=0 )
|
||||
VERSION_FULL:=$(shell git describe)
|
||||
VERSION_MAJ:=$(shell python -c 'print("$(VERSION)".split(".")[0])')
|
||||
VERSION_MIN:=$(shell python -c 'print("$(VERSION)".split(".")[1])')
|
||||
VERSION_PAT:=$(shell python -c 'print("$(VERSION)".split(".")[2])')
|
||||
|
||||
VERSION_FLAGS= -DSOLO_VERSION_MAJ=$(VERSION_MAJ) -DSOLO_VERSION_MIN=$(VERSION_MIN) \
|
||||
-DSOLO_VERSION_PATCH=$(VERSION_PAT) -DSOLO_VERSION=\"$(VERSION_FULL)\"
|
||||
|
||||
CFLAGS = -O2 -fdata-sections -ffunction-sections $(VERSION_FLAGS)
|
||||
|
||||
INCLUDES = -I./tinycbor/src -I./crypto/sha256 -I./crypto/micro-ecc/ -Icrypto/tiny-AES-c/ -I./fido2/ -I./pc -I./fido2/extensions
|
||||
INCLUDES += -I./crypto/cifra/src
|
||||
|
||||
CFLAGS += $(INCLUDES)
|
||||
# for crypto/tiny-AES-c
|
||||
@ -33,7 +43,7 @@ CFLAGS += -DAES256=1 -DAPP_CONFIG=\"app.h\"
|
||||
|
||||
name = main
|
||||
|
||||
.PHONY: all
|
||||
.PHONY: all $(LIBCBOR) black blackcheck cppcheck wink fido2-test clean full-clean travis test clean version
|
||||
all: main
|
||||
|
||||
tinycbor/Makefile crypto/tiny-AES-c/aes.c:
|
||||
@ -42,61 +52,74 @@ tinycbor/Makefile crypto/tiny-AES-c/aes.c:
|
||||
.PHONY: cbor
|
||||
cbor: $(LIBCBOR)
|
||||
|
||||
$(LIBCBOR): tinycbor/Makefile
|
||||
$(LIBCBOR):
|
||||
cd tinycbor/ && $(MAKE) clean && $(MAKE) -j8
|
||||
|
||||
test:
|
||||
version:
|
||||
@git describe
|
||||
|
||||
test: venv
|
||||
$(MAKE) clean
|
||||
$(MAKE) -C . main
|
||||
|
||||
.PHONY: efm8prog
|
||||
efm8prog:
|
||||
cd './targets/efm8\Keil 8051 v9.53 - Debug' && $(MAKE) all
|
||||
flashefm8.exe -part EFM8UB10F8G -sn 440105518 -erase
|
||||
flashefm8.exe -part EFM8UB10F8G -sn 440105518 -upload './targets/efm8/Keil 8051 v9.53 - Debug/efm8.hex'
|
||||
|
||||
.PHONY: efm32com efm32prog efm32read efm32bootprog
|
||||
efm32com:
|
||||
cd './targets/efm32/GNU ARM v7.2.1 - Debug' && $(MAKE) all
|
||||
efm32prog: efm32com
|
||||
commander flash './targets/efm32/GNU ARM v7.2.1 - Debug/EFM32.hex' $(EFM32_DEBUGGER) -p "0x1E7FC:0x00000000:4"
|
||||
efm32read: efm32com
|
||||
commander swo read $(EFM32_DEBUGGER)
|
||||
efm32bootprog: efm32com
|
||||
commander flash './efm32boot/GNU ARM v7.2.1 - Debug/efm32boot.hex' $(EFM32_DEBUGGER) --masserase
|
||||
$(MAKE) clean
|
||||
$(MAKE) -C ./targets/stm32l432 test PREFIX=$(PREFIX) "VENV=$(VENV)"
|
||||
$(MAKE) clean
|
||||
$(MAKE) cppcheck
|
||||
|
||||
$(name): $(obj) $(LIBCBOR)
|
||||
$(CC) $(LDFLAGS) -o $@ $(obj) $(LDFLAGS)
|
||||
|
||||
uECC.o: ./crypto/micro-ecc/uECC.c
|
||||
crypto/micro-ecc/uECC.o: ./crypto/micro-ecc/uECC.c
|
||||
$(CC) -c -o $@ $^ -O2 -fdata-sections -ffunction-sections -DuECC_PLATFORM=$(ecc_platform) -I./crypto/micro-ecc/
|
||||
|
||||
env2:
|
||||
virtualenv --python=python2.7 env2
|
||||
env2/bin/pip install --upgrade -r tools/requirements.txt
|
||||
|
||||
env3:
|
||||
python3 -m venv env3
|
||||
env3/bin/pip install --upgrade -r tools/requirements.txt
|
||||
env3/bin/pip install --upgrade black
|
||||
venv:
|
||||
python3 -m venv venv
|
||||
venv/bin/pip -q install --upgrade pip
|
||||
venv/bin/pip -q install --upgrade -r tools/requirements.txt
|
||||
venv/bin/pip -q install --upgrade black
|
||||
|
||||
# selectively reformat our own code
|
||||
black: env3
|
||||
env3/bin/black --skip-string-normalization tools/
|
||||
black: venv
|
||||
venv/bin/black --skip-string-normalization --check tools/
|
||||
|
||||
wink2: env2
|
||||
env2/bin/python tools/solotool.py solo --wink
|
||||
wink: venv
|
||||
venv/bin/solo key wink
|
||||
|
||||
wink3: env3
|
||||
env3/bin/python tools/solotool.py solo --wink
|
||||
fido2-test: venv
|
||||
venv/bin/python tools/ctap_test.py
|
||||
|
||||
fido2-test: env3
|
||||
env3/bin/python tools/ctap_test.py
|
||||
DOCKER_IMAGE := "solokeys/solo-firmware:local"
|
||||
SOLO_VERSIONISH := "master"
|
||||
docker-build:
|
||||
docker build -t $(DOCKER_IMAGE) .
|
||||
docker run --rm -v "$(CURDIR)/builds:/builds" \
|
||||
-v "$(CURDIR)/in-docker-build.sh:/in-docker-build.sh" \
|
||||
$(DOCKER_IMAGE) "./in-docker-build.sh" $(SOLO_VERSIONISH)
|
||||
uncached-docker-build:
|
||||
docker build --no-cache -t $(DOCKER_IMAGE) .
|
||||
docker run --rm -v "$(CURDIR)/builds:/builds" \
|
||||
-v "$(CURDIR)/in-docker-build.sh:/in-docker-build.sh" \
|
||||
$(DOCKER_IMAGE) "./in-docker-build.sh" $(SOLO_VERSIONISH)
|
||||
|
||||
CPPCHECK_FLAGS=--quiet --error-exitcode=2
|
||||
|
||||
cppcheck:
|
||||
cppcheck $(CPPCHECK_FLAGS) crypto/aes-gcm
|
||||
cppcheck $(CPPCHECK_FLAGS) crypto/sha256
|
||||
cppcheck $(CPPCHECK_FLAGS) fido2
|
||||
cppcheck $(CPPCHECK_FLAGS) pc
|
||||
|
||||
clean:
|
||||
rm -f *.o main.exe main $(obj)
|
||||
rm -rf env2 env3
|
||||
for f in crypto/tiny-AES-c/Makefile tinycbor/Makefile ; do \
|
||||
if [ -f "$$f" ]; then \
|
||||
(cd `dirname $$f` ; git checkout -- .) ;\
|
||||
fi ;\
|
||||
done
|
||||
|
||||
full-clean: clean
|
||||
rm -rf venv
|
||||
|
||||
travis:
|
||||
$(MAKE) test VENV=". ../../venv/bin/activate;"
|
||||
$(MAKE) black
|
||||
|
52
README.md
52
README.md
@ -2,6 +2,13 @@
|
||||
[](https://travis-ci.com/solokeys/solo)
|
||||
[](https://discourse.solokeys.com)
|
||||
[](https://keybase.io/team/solokeys.public)
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fsolokeys%2Fsolo?ref=badge_shield)
|
||||
|
||||
[](https://github.com/solokeys/solo/releases)
|
||||
[](https://github.com/solokeys/solo/commits/master)
|
||||
[](https://github.com/solokeys/solo/commits/master)
|
||||
[](https://github.com/solokeys/solo/commits/master)
|
||||
[](https://github.com/solokeys/solo/graphs/contributors)
|
||||
|
||||
|
||||
# Solo
|
||||
@ -12,7 +19,7 @@ Solo supports FIDO2 and U2F standards for strong two-factor authentication and p
|
||||
|
||||
<img src="https://solokeys.com/images/photos/hero-on-white-cropped.png" width="600">
|
||||
|
||||
This repo contains the Solo firmware, including implementations of FIDO2 and U2F (CTAP2 and CTAP) over USB and NFC. The main implementation is for STM32L432, and it's ported to NRF52840 and EFM32J.
|
||||
This repo contains the Solo firmware, including implementations of FIDO2 and U2F (CTAP2 and CTAP) over USB and NFC. The main implementation is for STM32L432, but it is easily portable.
|
||||
|
||||
For development no hardware is needed, Solo also runs as a standalone application for Windows, Linux, and Mac OSX. If you like (or want to learn) hardware instead, you can run Solo on the NUCLEO-L432KC development board, or we make Solo for Hacker, an unlocked version of Solo that lets you customize its firmware.
|
||||
|
||||
@ -32,9 +39,9 @@ Solo is based on the STM32L432 microcontroller. It offers the following security
|
||||
|
||||
Solo for Hacker is a special version of Solo that let you customize its firmware, for example you can change the LED color, and even build advanced applications.
|
||||
|
||||
You can only buy Solo for Hacker at [solokeys.com](https://solokeys.com), as we don't sell it on Amazon and other places to avoid confusing customers. If you buy a Hacker, you can permanently lock it into a regular Solo, but viceversa you can NOT take a regular Solo and turn it a Hacker.
|
||||
Check out [solokeys.com](https://solokeys.com), for options on where to buy Solo. Solo Hacker can be converted to a secure version, but normal Solo cannot be converted to a Hacker version.
|
||||
|
||||
If you have a Solo for Hacker, here's how you can load your own code on it. You can find more details, including how to permanently lock it, in our [documentation](https://docs.solokeys.io/solo/building/).
|
||||
If you have a Solo for Hacker, here's how you can load your own code on it. You can find more details, including how to permanently lock it, in our [documentation](https://docs.solokeys.io/solo/building/). We only support Python3.
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules https://github.com/solokeys/solo
|
||||
@ -42,27 +49,27 @@ cd solo
|
||||
|
||||
cd targets/stm32l432
|
||||
make cbor
|
||||
make all-hacker
|
||||
make build-hacker
|
||||
cd ../..
|
||||
|
||||
make env3
|
||||
source env3/bin/activate
|
||||
python tools/solotool.py program targets/stm32l432/solo.hex
|
||||
make venv
|
||||
source venv/bin/activate
|
||||
solo program aux enter-bootloader
|
||||
solo program bootloader targets/stm32l432/solo.hex
|
||||
```
|
||||
|
||||
Alternatively, run `make docker-build` and use the firmware generated in `/tmp`.
|
||||
|
||||
If you forgot the `--recurse-submodules` when cloning, simply `git submodule update --init --recursive`.
|
||||
|
||||
For example, if you want to turn off any blue light emission, you can edit [`led_rgb()`](https://github.com/solokeys/solo/blob/master/targets/stm32l432/src/led.c#L15) and force:
|
||||
```
|
||||
uint32_t b = 0;
|
||||
```
|
||||
For example, if you want to turn off any blue light emission, you can edit [`led_rgb()`](https://github.com/solokeys/solo/blob/master/targets/stm32l432/src/app.h#L48) and change `LED_INIT_VALUE`
|
||||
to be a different hex color.
|
||||
|
||||
Then recompile, load your new firmware, and enjoy a blue-light-free version of Solo.
|
||||
Then recompile, load your new firmware, and enjoy a different LED color Solo.
|
||||
|
||||
In the Hacker version, hardware is the same and firmware is unlocked, in the sense that you can 1) load an unsigned application, or 2) entirely reflash the key. By contrast, in a regular Solo you can only upgrade to a firmware signed by SoloKeys, and flash is locked and debug disabled permanently.
|
||||
|
||||
A frequently asked question is whether Solo for Hacker is less secure than regular Solo. The answer is certainly yes, and therefore we only recommend to use Solo for Hacker for development, experimentation, and fun. An attacker with physical access to a Solo for Hacker can reflash it following the steps above, and even a malware on your computer could possibly reflash it.
|
||||
In the Hacker version, hardware is the same but the firmware is unlocked, so you can 1) load an unsigned application, or 2) entirely reflash the key. By contrast, in a regular Solo you can only upgrade to a firmware signed by SoloKeys, and flash is locked and debug disabled permanently.
|
||||
|
||||
Hacker Solo isn't really secure so you should only use it for development. An attacker with physical access to a Solo for Hacker can reflash it following the steps above, and even a malware on your computer could possibly reflash it.
|
||||
|
||||
# Developing Solo (No Hardware Needed)
|
||||
|
||||
@ -79,7 +86,7 @@ This builds Solo as a standalone application. Solo application is set up to send
|
||||
Testing can be done using our fork of Yubico's client software, python-fido2. Our fork of python-fido2 has small changes to make it send USB HID over UDP to the authenticator application. You can install our fork by running the following:
|
||||
|
||||
```bash
|
||||
cd python-fido2 && python setup.py install
|
||||
pip install -r tools/requirements.txt
|
||||
```
|
||||
|
||||
Run the Solo application:
|
||||
@ -89,12 +96,7 @@ Run the Solo application:
|
||||
|
||||
In another shell, you can run client software, for example our tests:
|
||||
```bash
|
||||
python tools/ctap_test.py
|
||||
```
|
||||
|
||||
Or any client example such as:
|
||||
```bash
|
||||
python python-fido2/examples/credential.py
|
||||
python tools/ctap_test.py sim fido2
|
||||
```
|
||||
|
||||
You can find more details in our [documentation](https://docs.solokeys.io/solo/), including how to build on the the NUCLEO-L432KC development board.
|
||||
@ -117,10 +119,12 @@ Look at the issues to see what is currently being worked on. Feel free to add is
|
||||
# License
|
||||
|
||||
Solo is fully open source.
|
||||
All software is licensed under GPLv3, and hardware under CC BY-SA 4.0.
|
||||
Software and hardware are available under licenses for commercial use. Please contact SoloKeys for more information.
|
||||
All software, unless otherwise noted, is dual licensed under Apache 2.0 and MIT.
|
||||
You may use Solo under the terms of either the Apache 2.0 license or MIT license.
|
||||
|
||||
|
||||
[](https://app.fossa.io/projects/git%2Bgithub.com%2Fsolokeys%2Fsolo?ref=badge_large)
|
||||
|
||||
# Where To Buy Solo
|
||||
|
||||
You can buy Solo, Solo Tap, and Solo for Hackers at [solokeys.com](https://solokeys.com).
|
||||
|
1
STABLE_VERSION
Normal file
1
STABLE_VERSION
Normal file
@ -0,0 +1 @@
|
||||
2.0.0
|
0
builds/.gitkeep
Normal file
0
builds/.gitkeep
Normal file
1
crypto/cifra
Submodule
1
crypto/cifra
Submodule
Submodule crypto/cifra added at d04dd31860
@ -24,12 +24,6 @@ Enter the `stm32l4xx` target directory.
|
||||
cd targets/stm32l432
|
||||
```
|
||||
|
||||
Build the cbor library.
|
||||
|
||||
```bash
|
||||
make cbor
|
||||
```
|
||||
|
||||
Now build Solo.
|
||||
|
||||
```
|
||||
@ -61,11 +55,11 @@ If you use `DEBUG=2`, that means Solo will not boot until something starts readi
|
||||
it's debug messages. So it basically it waits to tether to a serial terminal so that you don't
|
||||
miss any debug messages.
|
||||
|
||||
We recommend using our `solotool.py` as a serial emulator since it will automatically
|
||||
We recommend using our `solo` tool as a serial emulator since it will automatically
|
||||
reconnect each time you program Solo.
|
||||
|
||||
```
|
||||
python tools/solotool.py monitor <serial-port>
|
||||
solo monitor <serial-port>
|
||||
```
|
||||
|
||||
#### Linux Users:
|
||||
@ -92,7 +86,7 @@ Programming `all.hex` will cause the device to permanently lock itself.
|
||||
It's recommended to test a debug/hacker build first to make sure Solo is working as expected.
|
||||
Then you can switch to a locked down build, which cannot be reprogrammed as easily (or not at all!).
|
||||
|
||||
We recommend using our `solotool.py` to manage programming. It is cross platform. First you must
|
||||
We recommend using our `solo` tool to manage programming. It is cross platform. First you must
|
||||
install the prerequisites:
|
||||
|
||||
```
|
||||
@ -107,7 +101,8 @@ If your Solo device is already programmed (it flashes green when powered), we re
|
||||
programming it using the Solo bootloader.
|
||||
|
||||
```
|
||||
python tools/solotool.py program solo.hex
|
||||
solo program aux enter-bootloader
|
||||
solo program bootloader solo.hex
|
||||
```
|
||||
|
||||
Make sure to program `solo.hex` and not `all.hex`. Nothing bad would happen, but you'd
|
||||
@ -131,7 +126,10 @@ off and it enumerates as "STM BOOTLOADER".
|
||||
You can program it by running the following.
|
||||
|
||||
```
|
||||
python tools/solotool.py program all.hex --use-dfu --detach
|
||||
solo program aux enter-bootloader
|
||||
solo program aux enter-dfu
|
||||
# powercycle key
|
||||
solo program dfu all.hex
|
||||
```
|
||||
|
||||
Make sure to program `all.hex`, as this contains both the bootloader and the Solo application.
|
||||
@ -151,14 +149,14 @@ A locked Solo will only accept signed updates.
|
||||
If this is not a device with a hacker build, you can only program signed updates.
|
||||
|
||||
```
|
||||
python tools/solotool.py program /path/to/firmware.json
|
||||
solo program bootloader /path/to/firmware.json
|
||||
```
|
||||
|
||||
If you've provisioned the Solo bootloader with your own secp256r1 public key, you can sign your
|
||||
firmware by running the following command.
|
||||
|
||||
```
|
||||
python tools/solotool.py sign /path/to/signing-key.pem /path/to/solo.hex /output-path/to/firmware.json
|
||||
solo sign /path/to/signing-key.pem /path/to/solo.hex /output-path/to/firmware.json
|
||||
```
|
||||
|
||||
If your Solo isn't locked, you can always reprogram it using a debugger connected directly
|
||||
@ -181,5 +179,5 @@ If you'd like to also permanently disable signed updates, plug in your programme
|
||||
|
||||
```
|
||||
# WARNING: No more signed updates.
|
||||
python tools/programmer.py --disable
|
||||
solo program disable-bootloader
|
||||
```
|
||||
|
@ -2,14 +2,14 @@ We are very open to contributions!
|
||||
|
||||
[Currently](https://github.com/solokeys/solo/issues), most work will go towards
|
||||
|
||||
* implementing STM32L432
|
||||
* ~~implementing STM32L432~~
|
||||
* implementing NFC
|
||||
* adding documentation and improving accessability of the code
|
||||
|
||||
In the future, we would love to see creative plugins/extensions, putting the TRNG and other features of the STM32L432 to good use!
|
||||
|
||||
Feel free to send a [pull request](https://github.com/solokeys/solo/pulls) at any time, we don't currently have a formal contribution process.
|
||||
Feel free to send a [pull request](https://github.com/solokeys/solo/pulls) at any time, please note that we do require a lightweight copyright license agreement in order to accept contributions. Reason and procedure: <https://solokeys.com/legal/contributors/>.
|
||||
|
||||
If you want to discuss your plans in quasi-realtime beforehand, you can also join our [solokeys.public](https://keybase.io/team/solokeys.public) Keybase team.
|
||||
|
||||
But first: [join our mailing list!](https://solokeys.us19.list-manage.com/subscribe/post?u=cc0c298fb99cd136bdec8294b&id=b9cb3de62d)
|
||||
But first: [join our mailing list!](https://solokeys.us19.list-manage.com/subscribe/post?u=cc0c298fb99cd136bdec8294b&id=6550fc947a)
|
||||
|
@ -15,13 +15,15 @@ A master secret, `M`, is generated at initialization. This is only used for
|
||||
all key generation and derivation in FIDO2. Solo uses a key wrapping method
|
||||
for FIDO2 operation.
|
||||
|
||||
** NOTE: The masked implementation of AES is planned, but not yet implemented. Currently it is normal AES. **
|
||||
|
||||
## Key wrapping
|
||||
|
||||
When you register a service with a FIDO2 or U2F authenticator, the
|
||||
authenticator must generate a new keypair unique to that service. This keypair
|
||||
could be stored on the authenticator to be used in subsequent authentications,
|
||||
but now a certain amount of memory needs to be allocated for this. On embedded
|
||||
devices, there isn't much memory to spare and users will always frustratingly
|
||||
devices, there isn't much memory to spare and users will allows frustratingly
|
||||
hit the limit of this memory.
|
||||
|
||||
The answer to this problem is to do key wrapping. The authenticator just
|
||||
@ -55,6 +57,8 @@ keys which are then used for FIDO2/U2F. -->
|
||||
|
||||
## Key derivation
|
||||
|
||||
** Planned, but not yet implemented. **
|
||||
|
||||
Master secret `M` consists of 64 bytes, split into equal parts `M1` and `M2`.
|
||||
In theory, we should only need 32 bytes to achieve 256 security, but we also
|
||||
plan to have side channel security hence the added bytes.
|
||||
|
12
docs/solo/metadata-statements.md
Normal file
12
docs/solo/metadata-statements.md
Normal file
@ -0,0 +1,12 @@
|
||||
For information on what this is, see the [spec](https://fidoalliance.org/specs/fido-v2.0-rd-20180702/fido-metadata-statement-v2.0-rd-20180702.html#fido2-example).
|
||||
## CTAP2
|
||||
|
||||
```
|
||||
{!metadata/Solo-FIDO2-CTAP2-Authenticator.json!}
|
||||
```
|
||||
|
||||
## U2F
|
||||
|
||||
```
|
||||
{!metadata/Solo-FIDO2-U2F-Authenticator.json!}
|
||||
```
|
@ -22,5 +22,5 @@ In order to boot the application, a valid signature must be provided to the boot
|
||||
signature using a public key stored in the bootloader section, and the data in the application section. If the signature
|
||||
is valid, the boot flag in the data section will be changed to allow boot.
|
||||
|
||||
Signature checks and checks to the data section boot flag are made redundantly to make glitching attacks more difficult. Random delays
|
||||
between redundant checks are also made.
|
||||
We are working to make the signature checking process redundantly to make glitching attacks more difficult. Also random delays
|
||||
between redundant checks.
|
||||
|
@ -1,21 +1,31 @@
|
||||
# tl;dr
|
||||
# Summary
|
||||
|
||||
Create [`/etc/udev/99-solo.rules`](https://github.com/solokeys/solo/blob/master/99-solo.rules) and add the following (which assumes your user is in group `plugdev`):
|
||||
On Linux, by default USB dongles can't be accessed by users, for security reasons. To allow user access, so-called "udev rules" must be installed. (Under Fedora, your key may work without such a rule.)
|
||||
|
||||
Create a file like [`70-solokeys-access.rules`](https://github.com/solokeys/solo/blob/master/udev/70-solokeys-access.rules) in your `/etc/udev/rules.d` directory, for instance the following rule should cover normal access (it has to be on one line):
|
||||
|
||||
```
|
||||
# Solo
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", TAG+="uaccess", GROUP="plugdev", SYMLINK+="solokey"
|
||||
|
||||
# U2F Zero
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="8acf", TAG+="uaccess", GROUP="plugdev", SYMLINK+="u2fzero"
|
||||
SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="a2ca", TAG+="uaccess", MODE="0660", GROUP="plugdev"
|
||||
```
|
||||
|
||||
Then run
|
||||
Additionally, run the following command after you create this file (it is not necessary to do this again in the future):
|
||||
|
||||
```
|
||||
udevadm trigger
|
||||
sudo udevadm control --reload-rules && sudo udevadm trigger
|
||||
```
|
||||
|
||||
A simple way to setup both the udev rule and the udevadm reload is:
|
||||
|
||||
```
|
||||
git clone git@github.com:solokeys/solo.git
|
||||
cd solo/udev
|
||||
make setup
|
||||
```
|
||||
|
||||
We are working on getting user access to Solo keys enabled automatically in common Linux distributions: <https://github.com/solokeys/solo/issues/144>.
|
||||
|
||||
|
||||
|
||||
# How do udev rules work and why are they needed
|
||||
|
||||
In Linux, `udev` (part of `systemd`, read `man 7 udev`) handles "hot-pluggable" devices, of which Solo and U2F Zero are examples. In particular, it creates nodes in the `/dev` filesystem (in Linux, everything is a file), which allow accessing the device.
|
||||
@ -50,7 +60,7 @@ This contains rules for Yubico's keys, the U2F Zero, and many others. The releva
|
||||
```
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="8acf", TAG+="uaccess"
|
||||
```
|
||||
It matches on the correct vendor/product IDs of 10c4/8acf, and adds the TAG `uaccess`. Older versions of udev use rules such as
|
||||
It matches on the correct vendor/product IDs of 10c4/8acf, and adds the TAG `uaccess`. Older versions of udev use rules such as
|
||||
```
|
||||
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="10c4", MODE="0644", GROUP="plugdev"
|
||||
```
|
||||
@ -65,8 +75,8 @@ udevadm trigger
|
||||
## What about vendor and product ID for Solo?
|
||||
| Key | Vendor ID | Product ID |
|
||||
| --- | --- | --- |
|
||||
| Solo | 10c4 | 8acf |
|
||||
| U2F Zero | 0483 | a2ca |
|
||||
| Solo | 0483 | a2ca |
|
||||
| U2F Zero | 10c4 | 8acf |
|
||||
|
||||
## You got this all wrong, I can't believe it!
|
||||
Are you suffering from [us being wrong](https://xkcd.com/386/)? Please, send us a [pull request](https://github.com/solokeys/solo/pulls) and prove us wrong :D
|
||||
|
30
fido2/apdu.h
Normal file
30
fido2/apdu.h
Normal file
@ -0,0 +1,30 @@
|
||||
#ifndef _APDU_H_
|
||||
#define _APDU_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t cla;
|
||||
uint8_t ins;
|
||||
uint8_t p1;
|
||||
uint8_t p2;
|
||||
uint8_t lc;
|
||||
} __attribute__((packed)) APDU_HEADER;
|
||||
|
||||
#define APDU_FIDO_U2F_REGISTER 0x01
|
||||
#define APDU_FIDO_U2F_AUTHENTICATE 0x02
|
||||
#define APDU_FIDO_U2F_VERSION 0x03
|
||||
#define APDU_FIDO_NFCCTAP_MSG 0x10
|
||||
#define APDU_INS_SELECT 0xA4
|
||||
#define APDU_INS_READ_BINARY 0xB0
|
||||
|
||||
#define SW_SUCCESS 0x9000
|
||||
#define SW_GET_RESPONSE 0x6100 // Command successfully executed; 'XX' bytes of data are available and can be requested using GET RESPONSE.
|
||||
#define SW_WRONG_LENGTH 0x6700
|
||||
#define SW_COND_USE_NOT_SATISFIED 0x6985
|
||||
#define SW_FILE_NOT_FOUND 0x6a82
|
||||
#define SW_INS_INVALID 0x6d00 // Instruction code not supported or invalid
|
||||
#define SW_INTERNAL_EXCEPTION 0x6f00
|
||||
|
||||
#endif //_APDU_H_
|
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#ifndef _COSE_KEY_H
|
||||
#define _COSE_KEY_H
|
||||
|
||||
|
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
/*
|
||||
* Wrapper for crypto implementation on device
|
||||
*
|
||||
@ -75,7 +60,7 @@ static const uint8_t * _signing_key = NULL;
|
||||
static int _key_len = 0;
|
||||
|
||||
// Secrets for testing only
|
||||
static uint8_t master_secret[32];
|
||||
static uint8_t master_secret[64];
|
||||
|
||||
static uint8_t transport_secret[32];
|
||||
|
||||
@ -88,13 +73,17 @@ void crypto_sha256_init()
|
||||
|
||||
void crypto_reset_master_secret()
|
||||
{
|
||||
ctap_generate_rng(master_secret, 32);
|
||||
ctap_generate_rng(master_secret, 64);
|
||||
ctap_generate_rng(transport_secret, 32);
|
||||
}
|
||||
|
||||
void crypto_load_master_secret(uint8_t * key)
|
||||
{
|
||||
memmove(master_secret, key, 32);
|
||||
memmove(transport_secret, key+32, 32);
|
||||
#if KEY_SPACE_BYTES < 96
|
||||
#error "need more key bytes"
|
||||
#endif
|
||||
memmove(master_secret, key, 64);
|
||||
memmove(transport_secret, key+64, 32);
|
||||
}
|
||||
|
||||
void crypto_sha256_update(uint8_t * data, size_t len)
|
||||
@ -123,7 +112,12 @@ void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac)
|
||||
key = master_secret;
|
||||
klen = sizeof(master_secret);
|
||||
}
|
||||
|
||||
else if (key == CRYPTO_TRANSPORT_KEY)
|
||||
{
|
||||
key = transport_secret;
|
||||
klen = 32;
|
||||
}
|
||||
|
||||
if(klen > 64)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, key size must be <= 64\n");
|
||||
|
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#ifndef _CRYPTO_H
|
||||
#define _CRYPTO_H
|
||||
|
||||
@ -34,6 +19,10 @@ void crypto_sha256_final(uint8_t * hash);
|
||||
void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac);
|
||||
void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac);
|
||||
|
||||
void crypto_sha512_init();
|
||||
void crypto_sha512_update(const uint8_t * data, size_t len);
|
||||
void crypto_sha512_final(uint8_t * hash);
|
||||
|
||||
|
||||
void crypto_ecc256_init();
|
||||
void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8_t * y);
|
||||
|
442
fido2/ctap.c
442
fido2/ctap.c
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -36,10 +21,10 @@
|
||||
#include "device.h"
|
||||
#include APP_CONFIG
|
||||
#include "wallet.h"
|
||||
#include "extensions.h"
|
||||
|
||||
#include "device.h"
|
||||
|
||||
#define PIN_TOKEN_SIZE 16
|
||||
uint8_t PIN_TOKEN[PIN_TOKEN_SIZE];
|
||||
uint8_t KEY_AGREEMENT_PUB[64];
|
||||
static uint8_t KEY_AGREEMENT_PRIV[32];
|
||||
@ -48,6 +33,8 @@ static int8_t PIN_BOOT_ATTEMPTS_LEFT = PIN_BOOT_ATTEMPTS;
|
||||
|
||||
AuthenticatorState STATE;
|
||||
|
||||
static void ctap_reset_key_agreement();
|
||||
|
||||
static struct {
|
||||
CTAP_authDataHeader authData;
|
||||
uint8_t clientDataHash[CLIENT_DATA_HASH_SIZE];
|
||||
@ -81,6 +68,8 @@ uint8_t verify_pin_auth(uint8_t * pinAuth, uint8_t * clientDataHash)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
uint8_t ctap_get_info(CborEncoder * encoder)
|
||||
{
|
||||
int ret;
|
||||
@ -89,16 +78,14 @@ uint8_t ctap_get_info(CborEncoder * encoder)
|
||||
CborEncoder options;
|
||||
CborEncoder pins;
|
||||
|
||||
const int number_of_versions = 2;
|
||||
|
||||
ret = cbor_encoder_create_map(encoder, &map, 5);
|
||||
ret = cbor_encoder_create_map(encoder, &map, 6);
|
||||
check_ret(ret);
|
||||
{
|
||||
|
||||
ret = cbor_encode_uint(&map, RESP_versions); // versions key
|
||||
check_ret(ret);
|
||||
{
|
||||
ret = cbor_encoder_create_array(&map, &array, number_of_versions);
|
||||
ret = cbor_encoder_create_array(&map, &array, 2);
|
||||
check_ret(ret);
|
||||
{
|
||||
ret = cbor_encode_text_stringz(&array, "U2F_V2");
|
||||
@ -110,6 +97,19 @@ uint8_t ctap_get_info(CborEncoder * encoder)
|
||||
check_ret(ret);
|
||||
}
|
||||
|
||||
ret = cbor_encode_uint(&map, RESP_extensions);
|
||||
check_ret(ret);
|
||||
{
|
||||
ret = cbor_encoder_create_array(&map, &array, 1);
|
||||
check_ret(ret);
|
||||
{
|
||||
ret = cbor_encode_text_stringz(&array, "hmac-secret");
|
||||
check_ret(ret);
|
||||
}
|
||||
ret = cbor_encoder_close_container(&map, &array);
|
||||
check_ret(ret);
|
||||
}
|
||||
|
||||
ret = cbor_encode_uint(&map, RESP_aaguid);
|
||||
check_ret(ret);
|
||||
{
|
||||
@ -323,18 +323,123 @@ static int is_matching_rk(CTAP_residentKey * rk, CTAP_residentKey * rk2)
|
||||
(rk->user.id_size == rk2->user.id_size);
|
||||
}
|
||||
|
||||
static int ctap_make_extensions(CTAP_extensions * ext, uint8_t * ext_encoder_buf, unsigned int * ext_encoder_buf_size)
|
||||
{
|
||||
CborEncoder extensions;
|
||||
int ret;
|
||||
uint8_t output[64];
|
||||
uint8_t shared_secret[32];
|
||||
uint8_t hmac[32];
|
||||
uint8_t credRandom[32];
|
||||
|
||||
static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * auth_data_buf, int len, CTAP_userEntity * user, uint8_t credtype, int32_t algtype, int32_t * sz, int store)
|
||||
if (ext->hmac_secret_present == EXT_HMAC_SECRET_PARSED)
|
||||
{
|
||||
printf1(TAG_CTAP, "Processing hmac-secret..\r\n");
|
||||
|
||||
crypto_ecc256_shared_secret((uint8_t*) &ext->hmac_secret.keyAgreement.pubkey,
|
||||
KEY_AGREEMENT_PRIV,
|
||||
shared_secret);
|
||||
crypto_sha256_init();
|
||||
crypto_sha256_update(shared_secret, 32);
|
||||
crypto_sha256_final(shared_secret);
|
||||
|
||||
crypto_sha256_hmac_init(shared_secret, 32, hmac);
|
||||
crypto_sha256_update(ext->hmac_secret.saltEnc, ext->hmac_secret.saltLen);
|
||||
crypto_sha256_hmac_final(shared_secret, 32, hmac);
|
||||
|
||||
if (memcmp(ext->hmac_secret.saltAuth, hmac, 16) == 0)
|
||||
{
|
||||
printf1(TAG_CTAP, "saltAuth is valid\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf1(TAG_CTAP, "saltAuth is invalid\r\n");
|
||||
return CTAP2_ERR_EXTENSION_FIRST;
|
||||
}
|
||||
|
||||
// Generate credRandom
|
||||
crypto_sha256_hmac_init(CRYPTO_TRANSPORT_KEY, 0, credRandom);
|
||||
crypto_sha256_update((uint8_t*)&ext->hmac_secret.credential->id, sizeof(CredentialId));
|
||||
crypto_sha256_hmac_final(CRYPTO_TRANSPORT_KEY, 0, credRandom);
|
||||
|
||||
// Decrypt saltEnc
|
||||
crypto_aes256_init(shared_secret, NULL);
|
||||
crypto_aes256_decrypt(ext->hmac_secret.saltEnc, ext->hmac_secret.saltLen);
|
||||
|
||||
// Generate outputs
|
||||
crypto_sha256_hmac_init(credRandom, 32, output);
|
||||
crypto_sha256_update(ext->hmac_secret.saltEnc, 32);
|
||||
crypto_sha256_hmac_final(credRandom, 32, output);
|
||||
|
||||
if (ext->hmac_secret.saltLen == 64)
|
||||
{
|
||||
crypto_sha256_hmac_init(credRandom, 32, output + 32);
|
||||
crypto_sha256_update(ext->hmac_secret.saltEnc + 32, 32);
|
||||
crypto_sha256_hmac_final(credRandom, 32, output + 32);
|
||||
}
|
||||
|
||||
// Encrypt for final output
|
||||
crypto_aes256_init(shared_secret, NULL);
|
||||
crypto_aes256_encrypt(output, ext->hmac_secret.saltLen);
|
||||
|
||||
// output
|
||||
printf1(TAG_GREEN, "have %d bytes for Extenstions encoder\r\n",*ext_encoder_buf_size);
|
||||
cbor_encoder_init(&extensions, ext_encoder_buf, *ext_encoder_buf_size, 0);
|
||||
{
|
||||
CborEncoder hmac_secret_map;
|
||||
ret = cbor_encoder_create_map(&extensions, &hmac_secret_map, 1);
|
||||
check_ret(ret);
|
||||
{
|
||||
ret = cbor_encode_text_stringz(&hmac_secret_map, "hmac-secret");
|
||||
check_ret(ret);
|
||||
|
||||
ret = cbor_encode_byte_string(&hmac_secret_map, output, ext->hmac_secret.saltLen);
|
||||
check_ret(ret);
|
||||
}
|
||||
ret = cbor_encoder_close_container(&extensions, &hmac_secret_map);
|
||||
check_ret(ret);
|
||||
}
|
||||
*ext_encoder_buf_size = cbor_encoder_get_buffer_size(&extensions, ext_encoder_buf);
|
||||
}
|
||||
else if (ext->hmac_secret_present == EXT_HMAC_SECRET_REQUESTED)
|
||||
{
|
||||
cbor_encoder_init(&extensions, ext_encoder_buf, *ext_encoder_buf_size, 0);
|
||||
{
|
||||
CborEncoder hmac_secret_map;
|
||||
ret = cbor_encoder_create_map(&extensions, &hmac_secret_map, 1);
|
||||
check_ret(ret);
|
||||
{
|
||||
ret = cbor_encode_text_stringz(&hmac_secret_map, "hmac-secret");
|
||||
check_ret(ret);
|
||||
|
||||
ret = cbor_encode_boolean(&hmac_secret_map, 1);
|
||||
check_ret(ret);
|
||||
}
|
||||
ret = cbor_encoder_close_container(&extensions, &hmac_secret_map);
|
||||
check_ret(ret);
|
||||
}
|
||||
*ext_encoder_buf_size = cbor_encoder_get_buffer_size(&extensions, ext_encoder_buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
*ext_encoder_buf_size = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * auth_data_buf, uint32_t * len, CTAP_credInfo * credInfo)
|
||||
{
|
||||
CborEncoder cose_key;
|
||||
int auth_data_sz, ret;
|
||||
|
||||
unsigned int auth_data_sz = sizeof(CTAP_authDataHeader);
|
||||
uint32_t count;
|
||||
CTAP_residentKey rk, rk2;
|
||||
CTAP_authData * authData = (CTAP_authData *)auth_data_buf;
|
||||
|
||||
uint8_t * cose_key_buf = auth_data_buf + sizeof(CTAP_authData);
|
||||
|
||||
if((sizeof(CTAP_authDataHeader)) > len)
|
||||
if((sizeof(CTAP_authDataHeader)) > *len)
|
||||
{
|
||||
printf1(TAG_ERR,"assertion fail, auth_data_buf must be at least %d bytes\n", sizeof(CTAP_authData) - sizeof(CTAP_attestHeader));
|
||||
exit(1);
|
||||
@ -350,7 +455,12 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au
|
||||
count = auth_data_update_count(&authData->head);
|
||||
|
||||
device_set_status(CTAPHID_STATUS_UPNEEDED);
|
||||
int but = ctap_user_presence_test();
|
||||
// if NFC - not need to click a button
|
||||
int but = 1;
|
||||
if(!device_is_nfc())
|
||||
{
|
||||
but = ctap_user_presence_test();
|
||||
}
|
||||
|
||||
if (!but)
|
||||
{
|
||||
@ -366,13 +476,12 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au
|
||||
authData->head.flags |= (ctap_is_pin_set() << 2);
|
||||
|
||||
|
||||
|
||||
if (credtype != 0)
|
||||
if (credInfo != NULL)
|
||||
{
|
||||
// add attestedCredentialData
|
||||
authData->head.flags |= (1 << 6);//include attestation data
|
||||
|
||||
cbor_encoder_init(&cose_key, cose_key_buf, len - sizeof(CTAP_authData), 0);
|
||||
cbor_encoder_init(&cose_key, cose_key_buf, *len - sizeof(CTAP_authData), 0);
|
||||
|
||||
memmove(authData->attest.aaguid, CTAP_AAGUID, 16);
|
||||
authData->attest.credLenL = sizeof(CredentialId) & 0x00FF;
|
||||
@ -390,13 +499,13 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au
|
||||
make_auth_tag(authData->head.rpIdHash, authData->attest.id.nonce, count, authData->attest.id.tag);
|
||||
|
||||
// resident key
|
||||
if (store)
|
||||
if (credInfo->rk)
|
||||
{
|
||||
memmove(&rk.id, &authData->attest.id, sizeof(CredentialId));
|
||||
memmove(&rk.user, user, sizeof(CTAP_userEntity));
|
||||
memmove(&rk.user, &credInfo->user, sizeof(CTAP_userEntity));
|
||||
|
||||
int index = STATE.rk_stored;
|
||||
int i;
|
||||
unsigned int index = STATE.rk_stored;
|
||||
unsigned int i;
|
||||
for (i = 0; i < index; i++)
|
||||
{
|
||||
ctap_load_rk(i, &rk2);
|
||||
@ -417,63 +526,63 @@ static int ctap_make_auth_data(struct rpId * rp, CborEncoder * map, uint8_t * au
|
||||
}
|
||||
done_rk:
|
||||
|
||||
// DELETE
|
||||
//crypto_aes256_init(CRYPTO_TRANSPORT_KEY, NULL);
|
||||
//crypto_aes256_encrypt((uint8_t*)&authData->attest.credential.user, CREDENTIAL_ENC_SIZE);
|
||||
printf1(TAG_GREEN, "MADE credId: "); dump_hex1(TAG_GREEN, (uint8_t*) &authData->attest.id, sizeof(CredentialId));
|
||||
|
||||
ctap_generate_cose_key(&cose_key, (uint8_t*)&authData->attest.id, sizeof(CredentialId), credtype, algtype);
|
||||
ctap_generate_cose_key(&cose_key, (uint8_t*)&authData->attest.id, sizeof(CredentialId), credInfo->publicKeyCredentialType, credInfo->COSEAlgorithmIdentifier);
|
||||
|
||||
auth_data_sz = sizeof(CTAP_authData) + cbor_encoder_get_buffer_size(&cose_key, cose_key_buf);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
auth_data_sz = sizeof(CTAP_authDataHeader);
|
||||
}
|
||||
|
||||
{
|
||||
ret = cbor_encode_int(map,RESP_authData);
|
||||
check_ret(ret);
|
||||
ret = cbor_encode_byte_string(map, auth_data_buf, auth_data_sz);
|
||||
check_ret(ret);
|
||||
}
|
||||
|
||||
if (sz) *sz = auth_data_sz;
|
||||
|
||||
|
||||
|
||||
*len = auth_data_sz;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ctap_encode_der_sig(uint8_t * sigbuf, uint8_t * sigder)
|
||||
/**
|
||||
*
|
||||
* @param in_sigbuf IN location to deposit signature (must be 64 bytes)
|
||||
* @param out_sigder OUT location to deposit der signature (must be 72 bytes)
|
||||
* @return length of der signature
|
||||
* // FIXME add tests for maximum and minimum length of the input and output
|
||||
*/
|
||||
int ctap_encode_der_sig(const uint8_t * const in_sigbuf, uint8_t * const out_sigder)
|
||||
{
|
||||
// Need to caress into dumb der format ..
|
||||
int i;
|
||||
int8_t lead_s = 0; // leading zeros
|
||||
int8_t lead_r = 0;
|
||||
uint8_t i;
|
||||
uint8_t lead_s = 0; // leading zeros
|
||||
uint8_t lead_r = 0;
|
||||
for (i=0; i < 32; i++)
|
||||
if (sigbuf[i] == 0) lead_r++;
|
||||
if (in_sigbuf[i] == 0) lead_r++;
|
||||
else break;
|
||||
|
||||
for (i=0; i < 32; i++)
|
||||
if (sigbuf[i+32] == 0) lead_s++;
|
||||
if (in_sigbuf[i+32] == 0) lead_s++;
|
||||
else break;
|
||||
|
||||
int8_t pad_s = ((sigbuf[32 + lead_s] & 0x80) == 0x80);
|
||||
int8_t pad_r = ((sigbuf[0 + lead_r] & 0x80) == 0x80);
|
||||
int8_t pad_s = ((in_sigbuf[32 + lead_s] & 0x80) == 0x80);
|
||||
int8_t pad_r = ((in_sigbuf[0 + lead_r] & 0x80) == 0x80);
|
||||
|
||||
sigder[0] = 0x30;
|
||||
sigder[1] = 0x44 + pad_s + pad_r - lead_s - lead_r;
|
||||
memset(out_sigder, 0, 72);
|
||||
out_sigder[0] = 0x30;
|
||||
out_sigder[1] = 0x44 + pad_s + pad_r - lead_s - lead_r;
|
||||
|
||||
sigder[2] = 0x02;
|
||||
sigder[3 + pad_r] = 0;
|
||||
sigder[3] = 0x20 + pad_r - lead_r;
|
||||
memmove(sigder + 4 + pad_r, sigbuf + lead_r, 32);
|
||||
// R ingredient
|
||||
out_sigder[2] = 0x02;
|
||||
out_sigder[3 + pad_r] = 0;
|
||||
out_sigder[3] = 0x20 + pad_r - lead_r;
|
||||
memmove(out_sigder + 4 + pad_r, in_sigbuf + lead_r, 32u - lead_r);
|
||||
|
||||
// S ingredient
|
||||
out_sigder[4 + 32 + pad_r - lead_r] = 0x02;
|
||||
out_sigder[5 + 32 + pad_r + pad_s - lead_r] = 0;
|
||||
out_sigder[5 + 32 + pad_r - lead_r] = 0x20 + pad_s - lead_s;
|
||||
memmove(out_sigder + 6 + 32 + pad_r + pad_s - lead_r, in_sigbuf + 32u + lead_s, 32u - lead_s);
|
||||
|
||||
sigder[4 + 32 + pad_r - lead_r] = 0x02;
|
||||
sigder[5 + 32 + pad_r + pad_s - lead_r] = 0;
|
||||
sigder[5 + 32 + pad_r - lead_r] = 0x20 + pad_s - lead_s;
|
||||
memmove(sigder + 6 + 32 + pad_r + pad_s - lead_r, sigbuf + 32 + lead_s, 32);
|
||||
//
|
||||
return 0x46 + pad_s + pad_r - lead_r - lead_s;
|
||||
}
|
||||
|
||||
@ -481,8 +590,8 @@ int ctap_encode_der_sig(uint8_t * sigbuf, uint8_t * sigder)
|
||||
// @data data to hash before signature
|
||||
// @clientDataHash for signature
|
||||
// @tmp buffer for hash. (can be same as data if data >= 32 bytes)
|
||||
// @sigbuf location to deposit signature (must be 64 bytes)
|
||||
// @sigder location to deposit der signature (must be 72 bytes)
|
||||
// @sigbuf OUT location to deposit signature (must be 64 bytes)
|
||||
// @sigder OUT location to deposit der signature (must be 72 bytes)
|
||||
// @return length of der signature
|
||||
int ctap_calculate_signature(uint8_t * data, int datalen, uint8_t * clientDataHash, uint8_t * hashbuf, uint8_t * sigbuf, uint8_t * sigder)
|
||||
{
|
||||
@ -554,13 +663,15 @@ int ctap_authenticate_credential(struct rpId * rp, CTAP_credentialDescriptor * d
|
||||
uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int length)
|
||||
{
|
||||
CTAP_makeCredential MC;
|
||||
int ret, i;
|
||||
uint8_t auth_data_buf[300];
|
||||
int ret;
|
||||
unsigned int i;
|
||||
uint8_t auth_data_buf[310];
|
||||
CTAP_credentialDescriptor * excl_cred = (CTAP_credentialDescriptor *) auth_data_buf;
|
||||
uint8_t * sigbuf = auth_data_buf + 32;
|
||||
uint8_t * sigder = auth_data_buf + 32 + 64;
|
||||
|
||||
ret = ctap_parse_make_credential(&MC,encoder,request,length);
|
||||
|
||||
if (ret != 0)
|
||||
{
|
||||
printf2(TAG_ERR,"error, parse_make_credential failed\n");
|
||||
@ -615,19 +726,38 @@ uint8_t ctap_make_credential(CborEncoder * encoder, uint8_t * request, int lengt
|
||||
check_ret(ret);
|
||||
}
|
||||
|
||||
|
||||
CborEncoder map;
|
||||
ret = cbor_encoder_create_map(encoder, &map, 3);
|
||||
check_ret(ret);
|
||||
int32_t auth_data_sz;
|
||||
|
||||
ret = ctap_make_auth_data(&MC.rp, &map, auth_data_buf, sizeof(auth_data_buf),
|
||||
&MC.user, MC.publicKeyCredentialType, MC.COSEAlgorithmIdentifier, &auth_data_sz, MC.rk);
|
||||
uint32_t auth_data_sz = sizeof(auth_data_buf);
|
||||
|
||||
ret = ctap_make_auth_data(&MC.rp, &map, auth_data_buf, &auth_data_sz,
|
||||
&MC.credInfo);
|
||||
check_retr(ret);
|
||||
|
||||
{
|
||||
unsigned int ext_encoder_buf_size = sizeof(auth_data_buf) - auth_data_sz;
|
||||
uint8_t * ext_encoder_buf = auth_data_buf + auth_data_sz;
|
||||
|
||||
ret = ctap_make_extensions(&MC.extensions, ext_encoder_buf, &ext_encoder_buf_size);
|
||||
check_retr(ret);
|
||||
if (ext_encoder_buf_size)
|
||||
{
|
||||
((CTAP_authData *)auth_data_buf)->head.flags |= (1 << 7);
|
||||
auth_data_sz += ext_encoder_buf_size;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ret = cbor_encode_int(&map,RESP_authData);
|
||||
check_ret(ret);
|
||||
ret = cbor_encode_byte_string(&map, auth_data_buf, auth_data_sz);
|
||||
check_ret(ret);
|
||||
}
|
||||
|
||||
crypto_ecc256_load_attestation_key();
|
||||
int sigder_sz = ctap_calculate_signature(auth_data_buf, auth_data_sz, MC.clientDataHash, auth_data_buf, sigbuf, sigder);
|
||||
|
||||
printf1(TAG_MC,"der sig [%d]: ", sigder_sz); dump_hex1(TAG_MC, sigder, sigder_sz);
|
||||
|
||||
ret = ctap_add_attest_statement(&map, sigder, sigder_sz);
|
||||
@ -780,7 +910,18 @@ int ctap_filter_invalid_credentials(CTAP_getAssertion * GA)
|
||||
if (! ctap_authenticate_credential(&GA->rp, &GA->creds[i]))
|
||||
{
|
||||
printf1(TAG_GA, "CRED #%d is invalid\n", GA->creds[i].credential.id.count);
|
||||
GA->creds[i].credential.id.count = 0; // invalidate
|
||||
#ifdef ENABLE_U2F_EXTENSIONS
|
||||
if (is_extension_request((uint8_t*)&GA->creds[i].credential.id, sizeof(CredentialId)))
|
||||
{
|
||||
printf1(TAG_EXT, "CRED #%d is extension\n", GA->creds[i].credential.id.count);
|
||||
count++;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
GA->creds[i].credential.id.count = 0; // invalidate
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -807,7 +948,7 @@ int ctap_filter_invalid_credentials(CTAP_getAssertion * GA)
|
||||
printf1(TAG_GA, "RK %d is a rpId match!\r\n", i);
|
||||
if (count == ALLOW_LIST_MAX_SIZE-1)
|
||||
{
|
||||
printf2(TAG_ERR, "not enough ram allocated for matching RK's (%d)\r\n", count);
|
||||
printf2(TAG_ERR, "not enough ram allocated for matching RK's (%d). Skipping.\r\n", count);
|
||||
break;
|
||||
}
|
||||
GA->creds[count].type = PUB_KEY_CRED_PUB_KEY;
|
||||
@ -836,6 +977,7 @@ static void save_credential_list(CTAP_authDataHeader * head, uint8_t * clientDat
|
||||
memmove(getAssertionState.clientDataHash, clientDataHash, CLIENT_DATA_HASH_SIZE);
|
||||
memmove(&getAssertionState.authData, head, sizeof(CTAP_authDataHeader));
|
||||
memmove(getAssertionState.creds, creds, sizeof(CTAP_credentialDescriptor) * (count));
|
||||
|
||||
}
|
||||
getAssertionState.count = count;
|
||||
printf1(TAG_GA,"saved %d credentials\n",count);
|
||||
@ -860,6 +1002,7 @@ uint8_t ctap_end_get_assertion(CborEncoder * map, CTAP_credentialDescriptor * cr
|
||||
int ret;
|
||||
uint8_t sigbuf[64];
|
||||
uint8_t sigder[72];
|
||||
int sigder_sz;
|
||||
|
||||
if (add_user)
|
||||
{
|
||||
@ -873,7 +1016,16 @@ uint8_t ctap_end_get_assertion(CborEncoder * map, CTAP_credentialDescriptor * cr
|
||||
|
||||
crypto_ecc256_load_key((uint8_t*)&cred->credential.id, sizeof(CredentialId), NULL, 0);
|
||||
|
||||
int sigder_sz = ctap_calculate_signature(auth_data_buf, sizeof(CTAP_authDataHeader), clientDataHash, auth_data_buf, sigbuf, sigder);
|
||||
#ifdef ENABLE_U2F_EXTENSIONS
|
||||
if ( extend_fido2(&cred->credential.id, sigder) )
|
||||
{
|
||||
sigder_sz = 72;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
sigder_sz = ctap_calculate_signature(auth_data_buf, sizeof(CTAP_authDataHeader), clientDataHash, auth_data_buf, sigbuf, sigder);
|
||||
}
|
||||
|
||||
{
|
||||
ret = cbor_encode_int(map, RESP_signature);
|
||||
@ -890,7 +1042,6 @@ uint8_t ctap_get_next_assertion(CborEncoder * encoder)
|
||||
CborEncoder map;
|
||||
CTAP_authDataHeader authData;
|
||||
memmove(&authData, &getAssertionState.authData, sizeof(CTAP_authDataHeader));
|
||||
// CTAP_authDataHeader * authData = &getAssertionState.authData;
|
||||
|
||||
CTAP_credentialDescriptor * cred = pop_credential();
|
||||
|
||||
@ -913,6 +1064,7 @@ uint8_t ctap_get_next_assertion(CborEncoder * encoder)
|
||||
ret = cbor_encoder_create_map(encoder, &map, 3);
|
||||
}
|
||||
|
||||
|
||||
check_ret(ret);
|
||||
printf1(TAG_RED, "RPID hash: "); dump_hex1(TAG_RED, authData.rpIdHash, 32);
|
||||
|
||||
@ -923,6 +1075,7 @@ uint8_t ctap_get_next_assertion(CborEncoder * encoder)
|
||||
check_ret(ret);
|
||||
}
|
||||
|
||||
|
||||
// if only one account for this RP, null out the user details
|
||||
if (!getAssertionState.user_verified)
|
||||
{
|
||||
@ -943,7 +1096,7 @@ uint8_t ctap_get_next_assertion(CborEncoder * encoder)
|
||||
uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length)
|
||||
{
|
||||
CTAP_getAssertion GA;
|
||||
uint8_t auth_data_buf[sizeof(CTAP_authDataHeader)];
|
||||
uint8_t auth_data_buf[sizeof(CTAP_authDataHeader) + 80];
|
||||
int ret = ctap_parse_get_assertion(&GA,request,length);
|
||||
|
||||
if (ret != 0)
|
||||
@ -952,19 +1105,15 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ctap_is_pin_set() && GA.pinAuthPresent == 0)
|
||||
if (GA.pinAuthPresent)
|
||||
{
|
||||
printf2(TAG_ERR,"pinAuth is required\n");
|
||||
return CTAP2_ERR_PIN_REQUIRED;
|
||||
ret = verify_pin_auth(GA.pinAuth, GA.clientDataHash);
|
||||
check_retr(ret);
|
||||
getAssertionState.user_verified = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ctap_is_pin_set() || (GA.pinAuthPresent))
|
||||
{
|
||||
ret = verify_pin_auth(GA.pinAuth, GA.clientDataHash);
|
||||
check_retr(ret);
|
||||
getAssertionState.user_verified = 1;
|
||||
}
|
||||
getAssertionState.user_verified = 0;
|
||||
}
|
||||
|
||||
if (!GA.rp.size || !GA.clientDataHashPresent)
|
||||
@ -989,34 +1138,15 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length)
|
||||
map_size += 1;
|
||||
}
|
||||
|
||||
if (GA.extensions.hmac_secret_present == EXT_HMAC_SECRET_PARSED)
|
||||
{
|
||||
printf1(TAG_GA, "hmac-secret is present\r\n");
|
||||
}
|
||||
|
||||
ret = cbor_encoder_create_map(encoder, &map, map_size);
|
||||
check_ret(ret);
|
||||
|
||||
ret = ctap_make_auth_data(&GA.rp, &map, auth_data_buf, sizeof(auth_data_buf), NULL, 0,0,NULL, 0);
|
||||
check_retr(ret);
|
||||
|
||||
/*for (int j = 0; j < GA.credLen; j++)*/
|
||||
/*{*/
|
||||
/*printf1(TAG_GA,"CRED ID (# %d): ", GA.creds[j].credential.enc.count);*/
|
||||
/*dump_hex1(TAG_GA, (uint8_t*)&GA.creds[j].credential, sizeof(struct Credential));*/
|
||||
/*if (ctap_authenticate_credential(&GA.rp, &GA.creds[j])) // warning encryption will break this*/
|
||||
/*{*/
|
||||
/*printf1(TAG_GA," Authenticated.\n");*/
|
||||
/*}*/
|
||||
/*else*/
|
||||
/*{*/
|
||||
/*printf1(TAG_GA," NOT authentic.\n");*/
|
||||
/*}*/
|
||||
/*}*/
|
||||
|
||||
// Decrypt here
|
||||
|
||||
//
|
||||
if (validCredCount > 0)
|
||||
{
|
||||
save_credential_list((CTAP_authDataHeader*)auth_data_buf, GA.clientDataHash, GA.creds, validCredCount-1); // skip last one
|
||||
}
|
||||
else
|
||||
if (validCredCount == 0)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, no authentic credential\n");
|
||||
return CTAP2_ERR_NO_CREDENTIALS;
|
||||
@ -1046,6 +1176,50 @@ uint8_t ctap_get_assertion(CborEncoder * encoder, uint8_t * request, int length)
|
||||
|
||||
CTAP_credentialDescriptor * cred = &GA.creds[validCredCount - 1];
|
||||
|
||||
GA.extensions.hmac_secret.credential = &cred->credential;
|
||||
|
||||
#ifdef ENABLE_U2F_EXTENSIONS
|
||||
if ( is_extension_request((uint8_t*)&GA.creds[validCredCount - 1].credential.id, sizeof(CredentialId)) )
|
||||
{
|
||||
ret = cbor_encode_int(&map,RESP_authData);
|
||||
check_ret(ret);
|
||||
memset(auth_data_buf,0,sizeof(CTAP_authDataHeader));
|
||||
ret = cbor_encode_byte_string(&map, auth_data_buf, sizeof(CTAP_authDataHeader));
|
||||
check_ret(ret);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
uint32_t len = sizeof(auth_data_buf);
|
||||
ret = ctap_make_auth_data(&GA.rp, &map, auth_data_buf, &len, NULL);
|
||||
check_retr(ret);
|
||||
|
||||
((CTAP_authData *)auth_data_buf)->head.flags &= ~(1 << 2);
|
||||
((CTAP_authData *)auth_data_buf)->head.flags |= (getAssertionState.user_verified << 2);
|
||||
|
||||
{
|
||||
unsigned int ext_encoder_buf_size = sizeof(auth_data_buf) - len;
|
||||
uint8_t * ext_encoder_buf = auth_data_buf + len;
|
||||
|
||||
ret = ctap_make_extensions(&GA.extensions, ext_encoder_buf, &ext_encoder_buf_size);
|
||||
check_retr(ret);
|
||||
if (ext_encoder_buf_size)
|
||||
{
|
||||
((CTAP_authData *)auth_data_buf)->head.flags |= (1 << 7);
|
||||
len += ext_encoder_buf_size;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
ret = cbor_encode_int(&map,RESP_authData);
|
||||
check_ret(ret);
|
||||
ret = cbor_encode_byte_string(&map, auth_data_buf, len);
|
||||
check_ret(ret);
|
||||
}
|
||||
}
|
||||
|
||||
save_credential_list((CTAP_authDataHeader*)auth_data_buf, GA.clientDataHash, GA.creds, validCredCount-1); // skip last one
|
||||
|
||||
ret = ctap_end_get_assertion(&map, cred, auth_data_buf, GA.clientDataHash, add_user_info);
|
||||
check_retr(ret);
|
||||
|
||||
@ -1151,7 +1325,7 @@ uint8_t ctap_update_pin_if_verified(uint8_t * pinEnc, int len, uint8_t * platfor
|
||||
crypto_aes256_decrypt(pinHashEnc, 16);
|
||||
if (memcmp(pinHashEnc, PIN_CODE_HASH, 16) != 0)
|
||||
{
|
||||
crypto_ecc256_make_key_pair(KEY_AGREEMENT_PUB, KEY_AGREEMENT_PRIV);
|
||||
ctap_reset_key_agreement();
|
||||
ctap_decrement_pin_attempts();
|
||||
if (ctap_device_boot_locked())
|
||||
{
|
||||
@ -1194,7 +1368,7 @@ uint8_t ctap_add_pin_if_verified(uint8_t * pinTokenEnc, uint8_t * platform_pubke
|
||||
printf2(TAG_ERR,"platform-pubkey: "); dump_hex1(TAG_ERR, platform_pubkey, 64);
|
||||
printf2(TAG_ERR,"device-pubkey: "); dump_hex1(TAG_ERR, KEY_AGREEMENT_PUB, 64);
|
||||
// Generate new keyAgreement pair
|
||||
crypto_ecc256_make_key_pair(KEY_AGREEMENT_PUB, KEY_AGREEMENT_PRIV);
|
||||
ctap_reset_key_agreement();
|
||||
ctap_decrement_pin_attempts();
|
||||
if (ctap_device_boot_locked())
|
||||
{
|
||||
@ -1219,6 +1393,7 @@ uint8_t ctap_client_pin(CborEncoder * encoder, uint8_t * request, int length)
|
||||
uint8_t pinTokenEnc[PIN_TOKEN_SIZE];
|
||||
int ret = ctap_parse_client_pin(&CP,request,length);
|
||||
|
||||
|
||||
switch(CP.subCommand)
|
||||
{
|
||||
case CP_cmdSetPin:
|
||||
@ -1363,8 +1538,6 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp)
|
||||
CborEncoder encoder;
|
||||
uint8_t status = 0;
|
||||
uint8_t cmd = *pkt_raw;
|
||||
uint64_t t1;
|
||||
uint64_t t2;
|
||||
pkt_raw++;
|
||||
length--;
|
||||
|
||||
@ -1397,10 +1570,9 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp)
|
||||
case CTAP_MAKE_CREDENTIAL:
|
||||
device_set_status(CTAPHID_STATUS_PROCESSING);
|
||||
printf1(TAG_CTAP,"CTAP_MAKE_CREDENTIAL\n");
|
||||
t1 = millis();
|
||||
timestamp();
|
||||
status = ctap_make_credential(&encoder, pkt_raw, length);
|
||||
t2 = millis();
|
||||
printf1(TAG_TIME,"make_credential time: %d ms\n", t2-t1);
|
||||
printf1(TAG_TIME,"make_credential time: %d ms\n", timestamp());
|
||||
|
||||
resp->length = cbor_encoder_get_buffer_size(&encoder, buf);
|
||||
dump_hex1(TAG_DUMP, buf, resp->length);
|
||||
@ -1409,10 +1581,9 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp)
|
||||
case CTAP_GET_ASSERTION:
|
||||
device_set_status(CTAPHID_STATUS_PROCESSING);
|
||||
printf1(TAG_CTAP,"CTAP_GET_ASSERTION\n");
|
||||
t1 = millis();
|
||||
timestamp();
|
||||
status = ctap_get_assertion(&encoder, pkt_raw, length);
|
||||
t2 = millis();
|
||||
printf1(TAG_TIME,"get_assertion time: %d ms\n", t2-t1);
|
||||
printf1(TAG_TIME,"get_assertion time: %d ms\n", timestamp());
|
||||
|
||||
resp->length = cbor_encoder_get_buffer_size(&encoder, buf);
|
||||
|
||||
@ -1559,12 +1730,16 @@ void ctap_init()
|
||||
exit(1);
|
||||
}
|
||||
|
||||
crypto_ecc256_make_key_pair(KEY_AGREEMENT_PUB, KEY_AGREEMENT_PRIV);
|
||||
if (! device_is_nfc())
|
||||
{
|
||||
ctap_reset_key_agreement();
|
||||
}
|
||||
|
||||
#ifdef BRIDGE_TO_WALLET
|
||||
wallet_init();
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
uint8_t ctap_is_pin_set()
|
||||
@ -1755,7 +1930,10 @@ int8_t ctap_load_key(uint8_t index, uint8_t * key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void ctap_reset_key_agreement()
|
||||
{
|
||||
crypto_ecc256_make_key_pair(KEY_AGREEMENT_PUB, KEY_AGREEMENT_PRIV);
|
||||
}
|
||||
|
||||
void ctap_reset()
|
||||
{
|
||||
@ -1772,7 +1950,7 @@ void ctap_reset()
|
||||
|
||||
ctap_reset_state();
|
||||
memset(PIN_CODE_HASH,0,sizeof(PIN_CODE_HASH));
|
||||
crypto_ecc256_make_key_pair(KEY_AGREEMENT_PUB, KEY_AGREEMENT_PRIV);
|
||||
ctap_reset_key_agreement();
|
||||
|
||||
crypto_reset_master_secret();
|
||||
}
|
||||
|
102
fido2/ctap.h
102
fido2/ctap.h
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#ifndef _CTAP_H
|
||||
#define _CTAP_H
|
||||
|
||||
@ -69,6 +54,13 @@
|
||||
#define CP_getKeyAgreement 0x07
|
||||
#define CP_getRetries 0x08
|
||||
|
||||
#define EXT_HMAC_SECRET_COSE_KEY 0x01
|
||||
#define EXT_HMAC_SECRET_SALT_ENC 0x02
|
||||
#define EXT_HMAC_SECRET_SALT_AUTH 0x03
|
||||
|
||||
#define EXT_HMAC_SECRET_REQUESTED 0x01
|
||||
#define EXT_HMAC_SECRET_PARSED 0x02
|
||||
|
||||
#define RESP_versions 0x1
|
||||
#define RESP_extensions 0x2
|
||||
#define RESP_aaguid 0x3
|
||||
@ -157,9 +149,13 @@ struct Credential {
|
||||
CredentialId id;
|
||||
CTAP_userEntity user;
|
||||
};
|
||||
|
||||
typedef struct Credential CTAP_residentKey;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t type;
|
||||
struct Credential credential;
|
||||
} CTAP_credentialDescriptor;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -196,34 +192,62 @@ struct rpId
|
||||
uint8_t name[RP_NAME_LIMIT];
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct{
|
||||
uint8_t x[32];
|
||||
uint8_t y[32];
|
||||
} pubkey;
|
||||
|
||||
int kty;
|
||||
int crv;
|
||||
} COSE_key;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t saltLen;
|
||||
uint8_t saltEnc[64];
|
||||
uint8_t saltAuth[32];
|
||||
COSE_key keyAgreement;
|
||||
struct Credential * credential;
|
||||
} CTAP_hmac_secret;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t hmac_secret_present;
|
||||
CTAP_hmac_secret hmac_secret;
|
||||
} CTAP_extensions;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CTAP_userEntity user;
|
||||
uint8_t publicKeyCredentialType;
|
||||
int32_t COSEAlgorithmIdentifier;
|
||||
uint8_t rk;
|
||||
} CTAP_credInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32_t paramsParsed;
|
||||
uint8_t clientDataHash[CLIENT_DATA_HASH_SIZE];
|
||||
struct rpId rp;
|
||||
CTAP_userEntity user;
|
||||
|
||||
uint8_t publicKeyCredentialType;
|
||||
int32_t COSEAlgorithmIdentifier;
|
||||
CTAP_credInfo credInfo;
|
||||
|
||||
CborValue excludeList;
|
||||
size_t excludeListSize;
|
||||
|
||||
uint8_t rk;
|
||||
uint8_t uv;
|
||||
uint8_t up;
|
||||
|
||||
uint8_t pinAuth[16];
|
||||
uint8_t pinAuthPresent;
|
||||
int pinProtocol;
|
||||
CTAP_extensions extensions;
|
||||
|
||||
} CTAP_makeCredential;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t type;
|
||||
struct Credential credential;
|
||||
} CTAP_credentialDescriptor;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -245,22 +269,16 @@ typedef struct
|
||||
|
||||
CTAP_credentialDescriptor creds[ALLOW_LIST_MAX_SIZE];
|
||||
uint8_t allowListPresent;
|
||||
|
||||
CTAP_extensions extensions;
|
||||
|
||||
} CTAP_getAssertion;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int pinProtocol;
|
||||
int subCommand;
|
||||
struct
|
||||
{
|
||||
struct{
|
||||
uint8_t x[32];
|
||||
uint8_t y[32];
|
||||
} pubkey;
|
||||
|
||||
int kty;
|
||||
int crv;
|
||||
} keyAgreement;
|
||||
COSE_key keyAgreement;
|
||||
uint8_t keyAgreementPresent;
|
||||
uint8_t pinAuth[16];
|
||||
uint8_t pinAuthPresent;
|
||||
@ -279,7 +297,7 @@ uint8_t ctap_request(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp);
|
||||
|
||||
// Encodes R,S signature to 2 der sequence of two integers. Sigder must be at least 72 bytes.
|
||||
// @return length of der signature
|
||||
int ctap_encode_der_sig(uint8_t * sigbuf, uint8_t * sigder);
|
||||
int ctap_encode_der_sig(uint8_t const * const in_sigbuf, uint8_t * const out_sigder);
|
||||
|
||||
// Run ctap related power-up procedures (init pinToken, generate shared secret)
|
||||
void ctap_init();
|
||||
|
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#define CTAP1_ERR_SUCCESS 0x00
|
||||
#define CTAP1_ERR_INVALID_COMMAND 0x01
|
||||
#define CTAP1_ERR_INVALID_PARAMETER 0x02
|
||||
|
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#include <stdint.h>
|
||||
|
||||
#include "cbor.h"
|
||||
@ -94,7 +79,7 @@ uint8_t parse_user(CTAP_makeCredential * MC, CborValue * val)
|
||||
size_t sz, map_length;
|
||||
uint8_t key[24];
|
||||
int ret;
|
||||
int i;
|
||||
unsigned int i;
|
||||
CborValue map;
|
||||
|
||||
|
||||
@ -143,14 +128,14 @@ uint8_t parse_user(CTAP_makeCredential * MC, CborValue * val)
|
||||
}
|
||||
|
||||
sz = USER_ID_MAX_SIZE;
|
||||
ret = cbor_value_copy_byte_string(&map, MC->user.id, &sz, NULL);
|
||||
ret = cbor_value_copy_byte_string(&map, MC->credInfo.user.id, &sz, NULL);
|
||||
if (ret == CborErrorOutOfMemory)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, USER_ID is too large\n");
|
||||
return CTAP2_ERR_LIMIT_EXCEEDED;
|
||||
}
|
||||
MC->user.id_size = sz;
|
||||
printf1(TAG_GREEN,"parsed id_size: %d\r\n", MC->user.id_size);
|
||||
MC->credInfo.user.id_size = sz;
|
||||
printf1(TAG_GREEN,"parsed id_size: %d\r\n", MC->credInfo.user.id_size);
|
||||
check_ret(ret);
|
||||
}
|
||||
else if (strcmp((const char *)key, "name") == 0)
|
||||
@ -161,12 +146,12 @@ uint8_t parse_user(CTAP_makeCredential * MC, CborValue * val)
|
||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||
}
|
||||
sz = USER_NAME_LIMIT;
|
||||
ret = cbor_value_copy_text_string(&map, (char *)MC->user.name, &sz, NULL);
|
||||
ret = cbor_value_copy_text_string(&map, (char *)MC->credInfo.user.name, &sz, NULL);
|
||||
if (ret != CborErrorOutOfMemory)
|
||||
{ // Just truncate the name it's okay
|
||||
check_ret(ret);
|
||||
}
|
||||
MC->user.name[USER_NAME_LIMIT - 1] = 0;
|
||||
MC->credInfo.user.name[USER_NAME_LIMIT - 1] = 0;
|
||||
}
|
||||
else if (strcmp((const char *)key, "displayName") == 0)
|
||||
{
|
||||
@ -176,12 +161,12 @@ uint8_t parse_user(CTAP_makeCredential * MC, CborValue * val)
|
||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||
}
|
||||
sz = DISPLAY_NAME_LIMIT;
|
||||
ret = cbor_value_copy_text_string(&map, (char *)MC->user.displayName, &sz, NULL);
|
||||
ret = cbor_value_copy_text_string(&map, (char *)MC->credInfo.user.displayName, &sz, NULL);
|
||||
if (ret != CborErrorOutOfMemory)
|
||||
{ // Just truncate the name it's okay
|
||||
check_ret(ret);
|
||||
}
|
||||
MC->user.displayName[DISPLAY_NAME_LIMIT - 1] = 0;
|
||||
MC->credInfo.user.displayName[DISPLAY_NAME_LIMIT - 1] = 0;
|
||||
}
|
||||
else if (strcmp((const char *)key, "icon") == 0)
|
||||
{
|
||||
@ -191,12 +176,12 @@ uint8_t parse_user(CTAP_makeCredential * MC, CborValue * val)
|
||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||
}
|
||||
sz = ICON_LIMIT;
|
||||
ret = cbor_value_copy_text_string(&map, (char *)MC->user.icon, &sz, NULL);
|
||||
ret = cbor_value_copy_text_string(&map, (char *)MC->credInfo.user.icon, &sz, NULL);
|
||||
if (ret != CborErrorOutOfMemory)
|
||||
{ // Just truncate the name it's okay
|
||||
check_ret(ret);
|
||||
}
|
||||
MC->user.icon[ICON_LIMIT - 1] = 0;
|
||||
MC->credInfo.user.icon[ICON_LIMIT - 1] = 0;
|
||||
|
||||
}
|
||||
else
|
||||
@ -285,7 +270,7 @@ uint8_t parse_pub_key_cred_params(CTAP_makeCredential * MC, CborValue * val)
|
||||
uint8_t cred_type;
|
||||
int32_t alg_type;
|
||||
int ret;
|
||||
int i;
|
||||
unsigned int i;
|
||||
CborValue arr;
|
||||
|
||||
|
||||
@ -320,8 +305,8 @@ uint8_t parse_pub_key_cred_params(CTAP_makeCredential * MC, CborValue * val)
|
||||
{
|
||||
if (pub_key_cred_param_supported(cred_type, alg_type) == CREDENTIAL_IS_SUPPORTED)
|
||||
{
|
||||
MC->publicKeyCredentialType = cred_type;
|
||||
MC->COSEAlgorithmIdentifier = alg_type;
|
||||
MC->credInfo.publicKeyCredentialType = cred_type;
|
||||
MC->credInfo.COSEAlgorithmIdentifier = alg_type;
|
||||
MC->paramsParsed |= PARAM_pubKeyCredParams;
|
||||
return 0;
|
||||
}
|
||||
@ -334,7 +319,7 @@ uint8_t parse_pub_key_cred_params(CTAP_makeCredential * MC, CborValue * val)
|
||||
return CTAP2_ERR_UNSUPPORTED_ALGORITHM;
|
||||
}
|
||||
|
||||
uint8_t parse_fixed_byte_string(CborValue * map, uint8_t * dst, int len)
|
||||
uint8_t parse_fixed_byte_string(CborValue * map, uint8_t * dst, unsigned int len)
|
||||
{
|
||||
size_t sz;
|
||||
int ret;
|
||||
@ -359,7 +344,7 @@ uint8_t parse_fixed_byte_string(CborValue * map, uint8_t * dst, int len)
|
||||
|
||||
uint8_t parse_verify_exclude_list(CborValue * val)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
CborValue arr;
|
||||
size_t size;
|
||||
@ -408,7 +393,7 @@ uint8_t parse_rp(struct rpId * rp, CborValue * val)
|
||||
size_t sz, map_length;
|
||||
char key[8];
|
||||
int ret;
|
||||
int i;
|
||||
unsigned int i;
|
||||
CborValue map;
|
||||
|
||||
|
||||
@ -496,7 +481,7 @@ uint8_t parse_options(CborValue * val, uint8_t * rk, uint8_t * uv, uint8_t * up)
|
||||
size_t sz, map_length;
|
||||
char key[8];
|
||||
int ret;
|
||||
int i;
|
||||
unsigned int i;
|
||||
_Bool b;
|
||||
CborValue map;
|
||||
|
||||
@ -536,7 +521,7 @@ uint8_t parse_options(CborValue * val, uint8_t * rk, uint8_t * uv, uint8_t * up)
|
||||
|
||||
if (cbor_value_get_type(&map) != CborBooleanType)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, expecting text string type for rp map value\n");
|
||||
printf2(TAG_ERR,"Error, expecting bool type for option map value\n");
|
||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||
}
|
||||
|
||||
@ -571,10 +556,158 @@ uint8_t parse_options(CborValue * val, uint8_t * rk, uint8_t * uv, uint8_t * up)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ctap_parse_hmac_secret(CborValue * val, CTAP_hmac_secret * hs)
|
||||
{
|
||||
size_t map_length;
|
||||
size_t salt_len;
|
||||
uint8_t parsed_count = 0;
|
||||
int key;
|
||||
int ret;
|
||||
unsigned int i;
|
||||
CborValue map;
|
||||
|
||||
if (cbor_value_get_type(val) != CborMapType)
|
||||
{
|
||||
printf2(TAG_ERR,"error, wrong type\n");
|
||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||
}
|
||||
|
||||
ret = cbor_value_enter_container(val,&map);
|
||||
check_ret(ret);
|
||||
|
||||
ret = cbor_value_get_map_length(val, &map_length);
|
||||
check_ret(ret);
|
||||
|
||||
for (i = 0; i < map_length; i++)
|
||||
{
|
||||
if (cbor_value_get_type(&map) != CborIntegerType)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, expecting CborIntegerTypefor hmac-secret map key, got %s\n", cbor_value_get_type_string(&map));
|
||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||
}
|
||||
ret = cbor_value_get_int(&map, &key);
|
||||
check_ret(ret);
|
||||
|
||||
ret = cbor_value_advance(&map);
|
||||
check_ret(ret);
|
||||
|
||||
switch(key)
|
||||
{
|
||||
case EXT_HMAC_SECRET_COSE_KEY:
|
||||
ret = parse_cose_key(&map, &hs->keyAgreement);
|
||||
check_retr(ret);
|
||||
parsed_count++;
|
||||
break;
|
||||
case EXT_HMAC_SECRET_SALT_ENC:
|
||||
salt_len = 64;
|
||||
ret = cbor_value_copy_byte_string(&map, hs->saltEnc, &salt_len, NULL);
|
||||
if ((salt_len != 32 && salt_len != 64) || ret == CborErrorOutOfMemory)
|
||||
{
|
||||
return CTAP1_ERR_INVALID_LENGTH;
|
||||
}
|
||||
check_ret(ret);
|
||||
hs->saltLen = salt_len;
|
||||
parsed_count++;
|
||||
break;
|
||||
case EXT_HMAC_SECRET_SALT_AUTH:
|
||||
salt_len = 32;
|
||||
ret = cbor_value_copy_byte_string(&map, hs->saltAuth, &salt_len, NULL);
|
||||
check_ret(ret);
|
||||
parsed_count++;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = cbor_value_advance(&map);
|
||||
check_ret(ret);
|
||||
}
|
||||
|
||||
if (parsed_count != 3)
|
||||
{
|
||||
printf2(TAG_ERR, "ctap_parse_hmac_secret missing parameter. Got %d.\r\n", parsed_count);
|
||||
return CTAP2_ERR_MISSING_PARAMETER;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
uint8_t ctap_parse_extensions(CborValue * val, CTAP_extensions * ext)
|
||||
{
|
||||
CborValue map;
|
||||
size_t sz, map_length;
|
||||
char key[16];
|
||||
int ret;
|
||||
unsigned int i;
|
||||
bool b;
|
||||
|
||||
if (cbor_value_get_type(val) != CborMapType)
|
||||
{
|
||||
printf2(TAG_ERR,"error, wrong type\n");
|
||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||
}
|
||||
|
||||
ret = cbor_value_enter_container(val, &map);
|
||||
check_ret(ret);
|
||||
|
||||
ret = cbor_value_get_map_length(val, &map_length);
|
||||
check_ret(ret);
|
||||
|
||||
for (i = 0; i < map_length; i++)
|
||||
{
|
||||
if (cbor_value_get_type(&map) != CborTextStringType)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, expecting text string type for options map key, got %s\n", cbor_value_get_type_string(&map));
|
||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||
}
|
||||
sz = sizeof(key);
|
||||
ret = cbor_value_copy_text_string(&map, key, &sz, NULL);
|
||||
|
||||
if (ret == CborErrorOutOfMemory)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, rp map key is too large. Ignoring.\n");
|
||||
cbor_value_advance(&map);
|
||||
cbor_value_advance(&map);
|
||||
continue;
|
||||
}
|
||||
check_ret(ret);
|
||||
key[sizeof(key) - 1] = 0;
|
||||
|
||||
ret = cbor_value_advance(&map);
|
||||
check_ret(ret);
|
||||
|
||||
|
||||
if (strncmp(key, "hmac-secret",11) == 0)
|
||||
{
|
||||
if (cbor_value_get_type(&map) == CborBooleanType)
|
||||
{
|
||||
ret = cbor_value_get_boolean(&map, &b);
|
||||
check_ret(ret);
|
||||
if (b) ext->hmac_secret_present = EXT_HMAC_SECRET_REQUESTED;
|
||||
printf1(TAG_CTAP, "set hmac_secret_present to %d\r\n", b);
|
||||
}
|
||||
else if (cbor_value_get_type(&map) == CborMapType)
|
||||
{
|
||||
ret = ctap_parse_hmac_secret(&map, &ext->hmac_secret);
|
||||
check_retr(ret);
|
||||
ext->hmac_secret_present = EXT_HMAC_SECRET_PARSED;
|
||||
printf1(TAG_CTAP, "parsed hmac_secret request\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf1(TAG_RED, "warning: hmac_secret request ignored for being wrong type\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
ret = cbor_value_advance(&map);
|
||||
check_ret(ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t ctap_parse_make_credential(CTAP_makeCredential * MC, CborEncoder * encoder, uint8_t * request, int length)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
unsigned int i;
|
||||
int key;
|
||||
size_t map_length;
|
||||
CborParser parser;
|
||||
@ -646,8 +779,8 @@ uint8_t ctap_parse_make_credential(CTAP_makeCredential * MC, CborEncoder * encod
|
||||
|
||||
ret = parse_user(MC, &map);
|
||||
|
||||
printf1(TAG_MC," ID: "); dump_hex1(TAG_MC, MC->user.id, MC->user.id_size);
|
||||
printf1(TAG_MC," name: %s\n", MC->user.name);
|
||||
printf1(TAG_MC," ID: "); dump_hex1(TAG_MC, MC->credInfo.user.id, MC->credInfo.user.id_size);
|
||||
printf1(TAG_MC," name: %s\n", MC->credInfo.user.name);
|
||||
|
||||
break;
|
||||
case MC_pubKeyCredParams:
|
||||
@ -655,8 +788,8 @@ uint8_t ctap_parse_make_credential(CTAP_makeCredential * MC, CborEncoder * encod
|
||||
|
||||
ret = parse_pub_key_cred_params(MC, &map);
|
||||
|
||||
printf1(TAG_MC," cred_type: 0x%02x\n", MC->publicKeyCredentialType);
|
||||
printf1(TAG_MC," alg_type: %d\n", MC->COSEAlgorithmIdentifier);
|
||||
printf1(TAG_MC," cred_type: 0x%02x\n", MC->credInfo.publicKeyCredentialType);
|
||||
printf1(TAG_MC," alg_type: %d\n", MC->credInfo.COSEAlgorithmIdentifier);
|
||||
|
||||
break;
|
||||
case MC_excludeList:
|
||||
@ -680,11 +813,13 @@ uint8_t ctap_parse_make_credential(CTAP_makeCredential * MC, CborEncoder * encod
|
||||
{
|
||||
return CTAP2_ERR_INVALID_CBOR_TYPE;
|
||||
}
|
||||
ret = ctap_parse_extensions(&map, &MC->extensions);
|
||||
check_retr(ret);
|
||||
break;
|
||||
|
||||
case MC_options:
|
||||
printf1(TAG_MC,"CTAP_options\n");
|
||||
ret = parse_options(&map, &MC->rk, &MC->uv, &MC->up);
|
||||
ret = parse_options(&map, &MC->credInfo.rk, &MC->uv, &MC->up);
|
||||
check_retr(ret);
|
||||
break;
|
||||
case MC_pinAuth:
|
||||
@ -790,7 +925,8 @@ uint8_t parse_allow_list(CTAP_getAssertion * GA, CborValue * it)
|
||||
{
|
||||
CborValue arr;
|
||||
size_t len;
|
||||
int i,ret;
|
||||
int ret;
|
||||
unsigned int i;
|
||||
CTAP_credentialDescriptor * cred;
|
||||
|
||||
if (cbor_value_get_type(it) != CborArrayType)
|
||||
@ -832,7 +968,7 @@ uint8_t parse_allow_list(CTAP_getAssertion * GA, CborValue * it)
|
||||
uint8_t ctap_parse_get_assertion(CTAP_getAssertion * GA, uint8_t * request, int length)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
unsigned int i;
|
||||
int key;
|
||||
size_t map_length;
|
||||
CborParser parser;
|
||||
@ -900,6 +1036,8 @@ uint8_t ctap_parse_get_assertion(CTAP_getAssertion * GA, uint8_t * request, int
|
||||
break;
|
||||
case GA_extensions:
|
||||
printf1(TAG_GA,"GA_extensions\n");
|
||||
ret = ctap_parse_extensions(&map, &GA->extensions);
|
||||
check_retr(ret);
|
||||
break;
|
||||
|
||||
case GA_options:
|
||||
@ -954,14 +1092,15 @@ uint8_t ctap_parse_get_assertion(CTAP_getAssertion * GA, uint8_t * request, int
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t parse_cose_key(CborValue * it, uint8_t * x, uint8_t * y, int * kty, int * crv)
|
||||
uint8_t parse_cose_key(CborValue * it, COSE_key * cose)
|
||||
{
|
||||
CborValue map;
|
||||
size_t map_length;
|
||||
int i,ret,key;
|
||||
int ret,key;
|
||||
unsigned int i;
|
||||
int xkey = 0,ykey = 0;
|
||||
*kty = 0;
|
||||
*crv = 0;
|
||||
cose->kty = 0;
|
||||
cose->crv = 0;
|
||||
|
||||
|
||||
CborType type = cbor_value_get_type(it);
|
||||
@ -999,7 +1138,7 @@ uint8_t parse_cose_key(CborValue * it, uint8_t * x, uint8_t * y, int * kty, int
|
||||
printf1(TAG_PARSE,"COSE_KEY_LABEL_KTY\n");
|
||||
if (cbor_value_get_type(&map) == CborIntegerType)
|
||||
{
|
||||
ret = cbor_value_get_int_checked(&map, kty);
|
||||
ret = cbor_value_get_int_checked(&map, &cose->kty);
|
||||
check_ret(ret);
|
||||
}
|
||||
else
|
||||
@ -1014,7 +1153,7 @@ uint8_t parse_cose_key(CborValue * it, uint8_t * x, uint8_t * y, int * kty, int
|
||||
printf1(TAG_PARSE,"COSE_KEY_LABEL_CRV\n");
|
||||
if (cbor_value_get_type(&map) == CborIntegerType)
|
||||
{
|
||||
ret = cbor_value_get_int_checked(&map, crv);
|
||||
ret = cbor_value_get_int_checked(&map, &cose->crv);
|
||||
check_ret(ret);
|
||||
}
|
||||
else
|
||||
@ -1024,14 +1163,14 @@ uint8_t parse_cose_key(CborValue * it, uint8_t * x, uint8_t * y, int * kty, int
|
||||
break;
|
||||
case COSE_KEY_LABEL_X:
|
||||
printf1(TAG_PARSE,"COSE_KEY_LABEL_X\n");
|
||||
ret = parse_fixed_byte_string(&map, x, 32);
|
||||
ret = parse_fixed_byte_string(&map, cose->pubkey.x, 32);
|
||||
check_retr(ret);
|
||||
xkey = 1;
|
||||
|
||||
break;
|
||||
case COSE_KEY_LABEL_Y:
|
||||
printf1(TAG_PARSE,"COSE_KEY_LABEL_Y\n");
|
||||
ret = parse_fixed_byte_string(&map, y, 32);
|
||||
ret = parse_fixed_byte_string(&map, cose->pubkey.y, 32);
|
||||
check_retr(ret);
|
||||
ykey = 1;
|
||||
|
||||
@ -1043,7 +1182,7 @@ uint8_t parse_cose_key(CborValue * it, uint8_t * x, uint8_t * y, int * kty, int
|
||||
ret = cbor_value_advance(&map);
|
||||
check_ret(ret);
|
||||
}
|
||||
if (xkey == 0 || ykey == 0 || *kty == 0 || *crv == 0)
|
||||
if (xkey == 0 || ykey == 0 || cose->kty == 0 || cose->crv == 0)
|
||||
{
|
||||
return CTAP2_ERR_MISSING_PARAMETER;
|
||||
}
|
||||
@ -1053,7 +1192,7 @@ uint8_t parse_cose_key(CborValue * it, uint8_t * x, uint8_t * y, int * kty, int
|
||||
uint8_t ctap_parse_client_pin(CTAP_clientPin * CP, uint8_t * request, int length)
|
||||
{
|
||||
int ret;
|
||||
int i;
|
||||
unsigned int i;
|
||||
int key;
|
||||
size_t map_length;
|
||||
size_t sz;
|
||||
@ -1123,7 +1262,7 @@ uint8_t ctap_parse_client_pin(CTAP_clientPin * CP, uint8_t * request, int length
|
||||
break;
|
||||
case CP_keyAgreement:
|
||||
printf1(TAG_CP,"CP_keyAgreement\n");
|
||||
ret = parse_cose_key(&map, CP->keyAgreement.pubkey.x, CP->keyAgreement.pubkey.y, &CP->keyAgreement.kty, &CP->keyAgreement.crv);
|
||||
ret = parse_cose_key(&map, &CP->keyAgreement);
|
||||
check_retr(ret);
|
||||
CP->keyAgreementPresent = 1;
|
||||
break;
|
||||
|
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#ifndef _CTAP_PARSE_H
|
||||
#define _CTAP_PARSE_H
|
||||
|
||||
@ -39,13 +24,13 @@ const char * cbor_value_get_type_string(const CborValue *value);
|
||||
uint8_t parse_user(CTAP_makeCredential * MC, CborValue * val);
|
||||
uint8_t parse_pub_key_cred_param(CborValue * val, uint8_t * cred_type, int32_t * alg_type);
|
||||
uint8_t parse_pub_key_cred_params(CTAP_makeCredential * MC, CborValue * val);
|
||||
uint8_t parse_fixed_byte_string(CborValue * map, uint8_t * dst, int len);
|
||||
uint8_t parse_fixed_byte_string(CborValue * map, uint8_t * dst, unsigned int len);
|
||||
uint8_t parse_rp_id(struct rpId * rp, CborValue * val);
|
||||
uint8_t parse_rp(struct rpId * rp, CborValue * val);
|
||||
uint8_t parse_options(CborValue * val, uint8_t * rk, uint8_t * uv, uint8_t * up);
|
||||
|
||||
uint8_t parse_allow_list(CTAP_getAssertion * GA, CborValue * it);
|
||||
uint8_t parse_cose_key(CborValue * it, uint8_t * x, uint8_t * y, int * kty, int * crv);
|
||||
uint8_t parse_cose_key(CborValue * it, COSE_key * cose);
|
||||
|
||||
|
||||
uint8_t ctap_parse_make_credential(CTAP_makeCredential * MC, CborEncoder * encoder, uint8_t * request, int length);
|
||||
|
211
fido2/ctaphid.c
211
fido2/ctaphid.c
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -31,6 +16,12 @@
|
||||
#include "util.h"
|
||||
#include "log.h"
|
||||
#include "extensions.h"
|
||||
|
||||
// move custom SHA512 command out,
|
||||
// and the following headers too
|
||||
#include "sha2.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#include APP_CONFIG
|
||||
|
||||
typedef enum
|
||||
@ -113,7 +104,7 @@ static uint32_t get_new_cid()
|
||||
|
||||
static int8_t add_cid(uint32_t cid)
|
||||
{
|
||||
int i;
|
||||
uint32_t i;
|
||||
for(i = 0; i < CID_MAX-1; i++)
|
||||
{
|
||||
if (!CIDS[i].busy)
|
||||
@ -129,7 +120,7 @@ static int8_t add_cid(uint32_t cid)
|
||||
|
||||
static int8_t cid_exists(uint32_t cid)
|
||||
{
|
||||
int i;
|
||||
uint32_t i;
|
||||
for(i = 0; i < CID_MAX-1; i++)
|
||||
{
|
||||
if (CIDS[i].cid == cid)
|
||||
@ -142,7 +133,7 @@ static int8_t cid_exists(uint32_t cid)
|
||||
|
||||
static int8_t cid_refresh(uint32_t cid)
|
||||
{
|
||||
int i;
|
||||
uint32_t i;
|
||||
for(i = 0; i < CID_MAX-1; i++)
|
||||
{
|
||||
if (CIDS[i].cid == cid)
|
||||
@ -157,7 +148,7 @@ static int8_t cid_refresh(uint32_t cid)
|
||||
|
||||
static int8_t cid_del(uint32_t cid)
|
||||
{
|
||||
int i;
|
||||
uint32_t i;
|
||||
for(i = 0; i < CID_MAX-1; i++)
|
||||
{
|
||||
if (CIDS[i].cid == cid)
|
||||
@ -395,7 +386,7 @@ static int ctaphid_buffer_packet(uint8_t * pkt_raw, uint8_t * cmd, uint32_t * ci
|
||||
printf1(TAG_HID, "Recv packet\n");
|
||||
printf1(TAG_HID, " CID: %08x \n", pkt->cid);
|
||||
printf1(TAG_HID, " cmd: %02x\n", pkt->pkt.init.cmd);
|
||||
if (!is_cont_pkt(pkt)) printf1(TAG_HID, " length: %d\n", ctaphid_packet_len(pkt));
|
||||
if (!is_cont_pkt(pkt)) {printf1(TAG_HID, " length: %d\n", ctaphid_packet_len(pkt));}
|
||||
|
||||
int ret;
|
||||
uint32_t oldcid;
|
||||
@ -543,19 +534,23 @@ static int ctaphid_buffer_packet(uint8_t * pkt_raw, uint8_t * cmd, uint32_t * ci
|
||||
return buffer_status();
|
||||
}
|
||||
|
||||
extern void _check_ret(CborError ret, int line, const char * filename);
|
||||
#define check_hardcore(r) _check_ret(r,__LINE__, __FILE__);\
|
||||
if ((r) != CborNoError) exit(1);
|
||||
|
||||
uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
|
||||
{
|
||||
uint8_t cmd;
|
||||
uint32_t cid;
|
||||
int len;
|
||||
#ifndef DISABLE_CTAPHID_CBOR
|
||||
int status;
|
||||
#endif
|
||||
|
||||
static uint8_t is_busy = 0;
|
||||
static CTAPHID_WRITE_BUFFER wb;
|
||||
CTAP_RESPONSE ctap_resp;
|
||||
|
||||
uint32_t t1,t2;
|
||||
|
||||
int bufstatus = ctaphid_buffer_packet(pkt_raw, &cmd, &cid, &len);
|
||||
|
||||
if (bufstatus == HID_IGNORE)
|
||||
@ -596,11 +591,11 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
|
||||
wb.cid = cid;
|
||||
wb.cmd = CTAPHID_PING;
|
||||
wb.bcnt = len;
|
||||
t1 = millis();
|
||||
timestamp();
|
||||
ctaphid_write(&wb, ctap_buffer, len);
|
||||
ctaphid_write(&wb, NULL,0);
|
||||
t2 = millis();
|
||||
printf1(TAG_TIME,"PING writeback: %d ms\n",(uint32_t)(t2-t1));
|
||||
printf1(TAG_TIME,"PING writeback: %d ms\n",timestamp());
|
||||
|
||||
break;
|
||||
#endif
|
||||
#ifndef DISABLE_CTAPHID_WINK
|
||||
@ -644,12 +639,11 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
|
||||
wb.bcnt = (ctap_resp.length+1);
|
||||
|
||||
|
||||
t1 = millis();
|
||||
timestamp();
|
||||
ctaphid_write(&wb, &status, 1);
|
||||
ctaphid_write(&wb, ctap_resp.data, ctap_resp.length);
|
||||
ctaphid_write(&wb, NULL, 0);
|
||||
t2 = millis();
|
||||
printf1(TAG_TIME,"CBOR writeback: %d ms\n",(uint32_t)(t2-t1));
|
||||
printf1(TAG_TIME,"CBOR writeback: %d ms\n",timestamp());
|
||||
is_busy = 0;
|
||||
break;
|
||||
#endif
|
||||
@ -734,6 +728,155 @@ uint8_t ctaphid_handle_packet(uint8_t * pkt_raw)
|
||||
ctaphid_write(&wb, NULL, 0);
|
||||
is_busy = 0;
|
||||
break;
|
||||
#endif
|
||||
#if defined(SOLO_HACKER) && (DEBUG_LEVEL > 0) && (!IS_BOOTLOADER == 1)
|
||||
case CTAPHID_PROBE:
|
||||
|
||||
/*
|
||||
* Expects CBOR-serialized data of the form
|
||||
* {"subcommand": "hash_type", "data": b"the_data"}
|
||||
* with hash_type in SHA256, SHA512
|
||||
*/
|
||||
|
||||
// some random logging
|
||||
printf1(TAG_HID,"CTAPHID_PROBE\n");
|
||||
// initialise CTAP response object
|
||||
ctap_response_init(&ctap_resp);
|
||||
// initialise write buffer
|
||||
ctaphid_write_buffer_init(&wb);
|
||||
wb.cid = cid;
|
||||
wb.cmd = CTAPHID_PROBE;
|
||||
|
||||
// prepare parsing (or halt)
|
||||
int ret;
|
||||
CborParser parser;
|
||||
CborValue it, map;
|
||||
ret = cbor_parser_init(
|
||||
ctap_buffer, (size_t) buffer_len(),
|
||||
// strictly speaking, CTAP is not RFC canonical...
|
||||
CborValidateCanonicalFormat,
|
||||
&parser, &it);
|
||||
check_hardcore(ret);
|
||||
|
||||
CborType type = cbor_value_get_type(&it);
|
||||
if (type != CborMapType) exit(1);
|
||||
|
||||
ret = cbor_value_enter_container(&it,&map);
|
||||
check_hardcore(ret);
|
||||
|
||||
size_t map_length = 0;
|
||||
ret = cbor_value_get_map_length(&it, &map_length);
|
||||
if (map_length != 2) exit(1);
|
||||
|
||||
// parse subcommand (or halt)
|
||||
CborValue val;
|
||||
ret = cbor_value_map_find_value(&it, "subcommand", &val);
|
||||
check_hardcore(ret);
|
||||
if (!cbor_value_is_text_string(&val))
|
||||
exit(1);
|
||||
|
||||
int sha_version = 0;
|
||||
bool found = false;
|
||||
if (!found) {
|
||||
ret = cbor_value_text_string_equals(
|
||||
&val, "SHA256", &found);
|
||||
check_hardcore(ret);
|
||||
if (found)
|
||||
sha_version = 256;
|
||||
}
|
||||
if (!found) {
|
||||
ret = cbor_value_text_string_equals(
|
||||
&val, "SHA512", &found);
|
||||
check_hardcore(ret);
|
||||
if (found)
|
||||
sha_version = 512;
|
||||
}
|
||||
if (sha_version == 0)
|
||||
exit(1);
|
||||
|
||||
// parse data (or halt)
|
||||
ret = cbor_value_map_find_value(&it, "data", &val);
|
||||
check_hardcore(ret);
|
||||
if (!cbor_value_is_byte_string(&val))
|
||||
exit(1);
|
||||
|
||||
size_t data_length = 0;
|
||||
ret = cbor_value_calculate_string_length(&val, &data_length);
|
||||
check_hardcore(ret);
|
||||
if (data_length > 6*1024)
|
||||
exit(1);
|
||||
|
||||
unsigned char data[6*1024];
|
||||
ret = cbor_value_copy_byte_string (
|
||||
&val, &data[0], &data_length, &val);
|
||||
check_hardcore(ret);
|
||||
|
||||
// execute subcommand
|
||||
if (sha_version == 256) {
|
||||
// calculate hash
|
||||
crypto_sha256_init();
|
||||
crypto_sha256_update(data, data_length);
|
||||
crypto_sha256_final(ctap_buffer);
|
||||
// write output
|
||||
wb.bcnt = CF_SHA256_HASHSZ; // 32 bytes
|
||||
ctaphid_write(&wb, &ctap_buffer, CF_SHA256_HASHSZ);
|
||||
}
|
||||
|
||||
if (sha_version == 512) {
|
||||
// calculate hash
|
||||
crypto_sha512_init();
|
||||
crypto_sha512_update(data, data_length);
|
||||
crypto_sha512_final(ctap_buffer);
|
||||
// write output
|
||||
wb.bcnt = CF_SHA512_HASHSZ; // 64 bytes
|
||||
ctaphid_write(&wb, &ctap_buffer, CF_SHA512_HASHSZ);
|
||||
}
|
||||
|
||||
// finalize
|
||||
ctaphid_write(&wb, NULL, 0);
|
||||
is_busy = 0;
|
||||
break;
|
||||
|
||||
/*
|
||||
case CTAPHID_SHA256:
|
||||
// some random logging
|
||||
printf1(TAG_HID,"CTAPHID_SHA256\n");
|
||||
// initialise CTAP response object
|
||||
ctap_response_init(&ctap_resp);
|
||||
// initialise write buffer
|
||||
ctaphid_write_buffer_init(&wb);
|
||||
wb.cid = cid;
|
||||
wb.cmd = CTAPHID_SHA256;
|
||||
wb.bcnt = CF_SHA256_HASHSZ; // 32 bytes
|
||||
// calculate hash
|
||||
crypto_sha256_init();
|
||||
crypto_sha256_update(ctap_buffer, buffer_len());
|
||||
crypto_sha256_final(ctap_buffer);
|
||||
// copy to output
|
||||
ctaphid_write(&wb, &ctap_buffer, CF_SHA256_HASHSZ);
|
||||
ctaphid_write(&wb, NULL, 0);
|
||||
is_busy = 0;
|
||||
break;
|
||||
case CTAPHID_SHA512:
|
||||
// some random logging
|
||||
printf1(TAG_HID,"CTAPHID_SHA512\n");
|
||||
// initialise CTAP response object
|
||||
ctap_response_init(&ctap_resp);
|
||||
// initialise write buffer
|
||||
ctaphid_write_buffer_init(&wb);
|
||||
wb.cid = cid;
|
||||
wb.cmd = CTAPHID_SHA512;
|
||||
wb.bcnt = CF_SHA512_HASHSZ; // 64 bytes
|
||||
// calculate hash
|
||||
crypto_sha512_init();
|
||||
crypto_sha512_update(ctap_buffer, buffer_len());
|
||||
crypto_sha512_final(ctap_buffer);
|
||||
// copy to output
|
||||
ctaphid_write(&wb, &ctap_buffer, CF_SHA512_HASHSZ);
|
||||
ctaphid_write(&wb, NULL, 0);
|
||||
is_busy = 0;
|
||||
break;
|
||||
*/
|
||||
#endif
|
||||
default:
|
||||
printf2(TAG_ERR,"error, unimplemented HID cmd: %02x\r\n", buffer_cmd());
|
||||
|
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#ifndef _CTAPHID_H_H
|
||||
#define _CTAPHID_H_H
|
||||
|
||||
@ -43,6 +28,8 @@
|
||||
#define CTAPHID_ENTERBOOT (TYPE_INIT | 0x51)
|
||||
#define CTAPHID_ENTERSTBOOT (TYPE_INIT | 0x52)
|
||||
#define CTAPHID_GETRNG (TYPE_INIT | 0x60)
|
||||
// reserved for debug, not implemented except for HACKER and DEBUG_LEVEl > 0
|
||||
#define CTAPHID_PROBE (TYPE_INIT | 0x70)
|
||||
|
||||
#define ERR_INVALID_CMD 0x01
|
||||
#define ERR_INVALID_PAR 0x02
|
||||
|
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#ifndef _DEVICE_H
|
||||
#define _DEVICE_H
|
||||
|
||||
@ -61,7 +46,7 @@ void device_manage();
|
||||
|
||||
// sets status that's uses for sending status updates ~100ms.
|
||||
// A timer should be set up to call `ctaphid_update_status`
|
||||
void device_set_status(int status);
|
||||
void device_set_status(uint32_t status);
|
||||
|
||||
// Returns if button is currently pressed
|
||||
int device_is_button_pressed();
|
||||
@ -101,5 +86,22 @@ void boot_st_bootloader();
|
||||
// HID wink command
|
||||
void device_wink();
|
||||
|
||||
typedef enum {
|
||||
DEVICE_LOW_POWER_IDLE = 0,
|
||||
DEVICE_LOW_POWER_FAST = 1,
|
||||
DEVICE_FAST = 2,
|
||||
} DEVICE_CLOCK_RATE;
|
||||
|
||||
// Set the clock rate for the device.
|
||||
// Three modes are targetted for Solo.
|
||||
// 0: Lowest clock rate for NFC.
|
||||
// 1: fastest clock rate supported at a low power setting for NFC FIDO.
|
||||
// 2: fastest clock rate. Generally for USB interface.
|
||||
void device_set_clock_rate(DEVICE_CLOCK_RATE param);
|
||||
|
||||
// Returns 1 if operating in NFC mode.
|
||||
// 0 otherwise.
|
||||
bool device_is_nfc();
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,28 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
|
||||
#include <stdint.h>
|
||||
#include "extensions.h"
|
||||
#include "u2f.h"
|
||||
#include "ctap.h"
|
||||
#include "wallet.h"
|
||||
#include "solo.h"
|
||||
#include "device.h"
|
||||
|
||||
#include "log.h"
|
||||
@ -69,6 +57,9 @@ int16_t bridge_u2f_to_extensions(uint8_t * _chal, uint8_t * _appid, uint8_t klen
|
||||
ret = bootloader_bridge(klen, keyh);
|
||||
#elif defined(WALLET_EXTENSION)
|
||||
ret = bridge_u2f_to_wallet(_chal, _appid, klen, keyh);
|
||||
#else
|
||||
ret = bridge_u2f_to_solo(sig, keyh, klen);
|
||||
u2f_response_writeback(sig,72);
|
||||
#endif
|
||||
|
||||
if (ret != 0)
|
||||
@ -85,10 +76,25 @@ int16_t bridge_u2f_to_extensions(uint8_t * _chal, uint8_t * _appid, uint8_t klen
|
||||
return U2F_SW_NO_ERROR;
|
||||
}
|
||||
|
||||
int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len)
|
||||
// Returns 1 if this is a extension request.
|
||||
// Else 0 if nothing is done.
|
||||
int16_t extend_fido2(CredentialId * credid, uint8_t * output)
|
||||
{
|
||||
if (is_extension_request((uint8_t*)credid, sizeof(CredentialId)))
|
||||
{
|
||||
output[0] = bridge_u2f_to_solo(output+1, (uint8_t*)credid, sizeof(CredentialId));
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int16_t extend_u2f(APDU_HEADER * req, uint8_t * payload, uint32_t len)
|
||||
{
|
||||
|
||||
struct u2f_authenticate_request * auth = (struct u2f_authenticate_request *) req->payload;
|
||||
struct u2f_authenticate_request * auth = (struct u2f_authenticate_request *) payload;
|
||||
uint16_t rcode;
|
||||
|
||||
if (req->ins == U2F_AUTHENTICATE)
|
||||
@ -104,7 +110,7 @@ int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len)
|
||||
{
|
||||
rcode = U2F_SW_WRONG_DATA;
|
||||
}
|
||||
printf1(TAG_EXT,"Ignoring U2F request\n");
|
||||
printf1(TAG_EXT,"Ignoring U2F check request\n");
|
||||
dump_hex1(TAG_EXT, (uint8_t *) &auth->kh, auth->khl);
|
||||
goto end;
|
||||
}
|
||||
@ -112,8 +118,8 @@ int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len)
|
||||
{
|
||||
if ( ! is_extension_request((uint8_t *) &auth->kh, auth->khl)) // Pin requests
|
||||
{
|
||||
rcode = U2F_SW_WRONG_PAYLOAD;
|
||||
printf1(TAG_EXT, "Ignoring U2F request\n");
|
||||
rcode = U2F_SW_WRONG_DATA;
|
||||
printf1(TAG_EXT, "Ignoring U2F auth request\n");
|
||||
dump_hex1(TAG_EXT, (uint8_t *) &auth->kh, auth->khl);
|
||||
goto end;
|
||||
}
|
||||
|
@ -1,30 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#ifndef EXTENSIONS_H_
|
||||
#define EXTENSIONS_H_
|
||||
#include "u2f.h"
|
||||
#include "apdu.h"
|
||||
|
||||
int16_t extend_u2f(struct u2f_request_apdu* req, uint32_t len);
|
||||
int16_t extend_u2f(APDU_HEADER * req, uint8_t * payload, uint32_t len);
|
||||
|
||||
int16_t extend_fido2(CredentialId * credid, uint8_t * output);
|
||||
|
||||
int bootloader_bridge(int klen, uint8_t * keyh);
|
||||
|
||||
int is_extension_request(uint8_t * kh, int len);
|
||||
|
||||
#endif /* EXTENSIONS_H_ */
|
||||
|
73
fido2/extensions/solo.c
Normal file
73
fido2/extensions/solo.c
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "extensions.h"
|
||||
#include "u2f.h"
|
||||
#include "wallet.h"
|
||||
#include "device.h"
|
||||
#include "ctap.h"
|
||||
#include "ctap_errors.h"
|
||||
|
||||
#include "log.h"
|
||||
#include APP_CONFIG
|
||||
|
||||
// output must be at least 71 bytes
|
||||
int16_t bridge_u2f_to_solo(uint8_t * output, uint8_t * keyh, int keylen)
|
||||
{
|
||||
int8_t ret = 0;
|
||||
|
||||
wallet_request * req = (wallet_request *) keyh;
|
||||
|
||||
printf1(TAG_WALLET, "u2f-solo [%d]: ", keylen); dump_hex1(TAG_WALLET, keyh, keylen);
|
||||
|
||||
switch(req->operation)
|
||||
{
|
||||
case WalletVersion:
|
||||
output[0] = SOLO_VERSION_MAJ;
|
||||
output[1] = SOLO_VERSION_MIN;
|
||||
output[2] = SOLO_VERSION_PATCH;
|
||||
break;
|
||||
case WalletRng:
|
||||
printf1(TAG_WALLET,"SoloRng\n");
|
||||
|
||||
ret = ctap_generate_rng(output, 71);
|
||||
if (ret != 1)
|
||||
{
|
||||
printf1(TAG_WALLET,"Rng failed\n");
|
||||
ret = CTAP2_ERR_PROCESSING;
|
||||
goto cleanup;
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
printf2(TAG_ERR,"Invalid wallet command: %x\n",req->operation);
|
||||
ret = CTAP1_ERR_INVALID_COMMAND;
|
||||
break;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,31 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
#ifndef _USB_H
|
||||
#define _USB_H
|
||||
#ifndef SOLO_H_
|
||||
#define SOLO_H_
|
||||
|
||||
#include "app_fifo.h"
|
||||
|
||||
void usb_init(void);
|
||||
|
||||
extern app_fifo_t USBHID_RECV_FIFO;
|
||||
int16_t bridge_u2f_to_solo(uint8_t * output, uint8_t * keyh, int keylen);
|
||||
|
||||
#endif
|
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#include "wallet.h"
|
||||
#include APP_CONFIG
|
||||
#include "ctap.h"
|
||||
|
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#ifndef WALLET_H_
|
||||
#define WALLET_H_
|
||||
|
||||
|
46
fido2/log.c
46
fido2/log.c
@ -1,29 +1,15 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
#include "device.h"
|
||||
|
||||
#if DEBUG_LEVEL > 0
|
||||
|
||||
@ -61,7 +47,9 @@ struct logtag tagtable[] = {
|
||||
{TAG_WALLET,"[1;34mWALLET[0m"},
|
||||
{TAG_STOR,"[1;35mSTOR[0m"},
|
||||
{TAG_BOOT,"[1;36mBOOT[0m"},
|
||||
{TAG_BOOT,"[1;37mEXT[0m"},
|
||||
{TAG_EXT,"[1;37mEXT[0m"},
|
||||
{TAG_NFC,"[1;38mNFC[0m"},
|
||||
{TAG_NFC_APDU, "NAPDU"},
|
||||
};
|
||||
|
||||
|
||||
@ -72,7 +60,7 @@ __attribute__((weak)) void set_logging_tag(uint32_t tag)
|
||||
|
||||
void LOG(uint32_t tag, const char * filename, int num, const char * fmt, ...)
|
||||
{
|
||||
int i;
|
||||
unsigned int i;
|
||||
|
||||
if (((tag & 0x7fffffff) & LOGMASK) == 0)
|
||||
{
|
||||
@ -82,7 +70,7 @@ void LOG(uint32_t tag, const char * filename, int num, const char * fmt, ...)
|
||||
{
|
||||
if (tag & tagtable[i].tagn)
|
||||
{
|
||||
if (tagtable[i].tag[0]) printf("[%s] ", tagtable[i].tag);
|
||||
if (tagtable[i].tag[0] && !(tag & TAG_NO_TAG)) printf("[%s] ", tagtable[i].tag);
|
||||
i = 0;
|
||||
break;
|
||||
}
|
||||
@ -114,4 +102,14 @@ void LOG_HEX(uint32_t tag, uint8_t * data, int length)
|
||||
set_logging_tag(tag);
|
||||
dump_hex(data,length);
|
||||
}
|
||||
|
||||
uint32_t timestamp()
|
||||
{
|
||||
static uint32_t t1 = 0;
|
||||
uint32_t t2 = millis();
|
||||
uint32_t diff = t2 - t1;
|
||||
t1 = t2;
|
||||
return diff;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
79
fido2/log.h
79
fido2/log.h
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#ifndef _LOG_H
|
||||
#define _LOG_H
|
||||
|
||||
@ -38,27 +23,30 @@ void set_logging_tag(uint32_t tag);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TAG_GEN = (1 << 0),
|
||||
TAG_MC = (1 << 1),
|
||||
TAG_GA = (1 << 2),
|
||||
TAG_CP = (1 << 3),
|
||||
TAG_ERR = (1 << 4),
|
||||
TAG_PARSE= (1 << 5),
|
||||
TAG_CTAP = (1 << 6),
|
||||
TAG_U2F = (1 << 7),
|
||||
TAG_DUMP = (1 << 8),
|
||||
TAG_GREEN = (1 << 9),
|
||||
TAG_RED= (1 << 10),
|
||||
TAG_TIME= (1 << 11),
|
||||
TAG_HID = (1 << 12),
|
||||
TAG_USB = (1 << 13),
|
||||
TAG_WALLET = (1 << 14),
|
||||
TAG_STOR = (1 << 15),
|
||||
TAG_DUMP2 = (1 << 16),
|
||||
TAG_BOOT = (1 << 17),
|
||||
TAG_EXT = (1 << 17),
|
||||
TAG_GEN = (1 << 0),
|
||||
TAG_MC = (1 << 1),
|
||||
TAG_GA = (1 << 2),
|
||||
TAG_CP = (1 << 3),
|
||||
TAG_ERR = (1 << 4),
|
||||
TAG_PARSE = (1 << 5),
|
||||
TAG_CTAP = (1 << 6),
|
||||
TAG_U2F = (1 << 7),
|
||||
TAG_DUMP = (1 << 8),
|
||||
TAG_GREEN = (1 << 9),
|
||||
TAG_RED = (1 << 10),
|
||||
TAG_TIME = (1 << 11),
|
||||
TAG_HID = (1 << 12),
|
||||
TAG_USB = (1 << 13),
|
||||
TAG_WALLET = (1 << 14),
|
||||
TAG_STOR = (1 << 15),
|
||||
TAG_DUMP2 = (1 << 16),
|
||||
TAG_BOOT = (1 << 17),
|
||||
TAG_EXT = (1 << 18),
|
||||
TAG_NFC = (1 << 19),
|
||||
TAG_NFC_APDU = (1 << 20),
|
||||
|
||||
TAG_FILENO = (1<<31)
|
||||
TAG_NO_TAG = (1UL << 30),
|
||||
TAG_FILENO = (1UL << 31)
|
||||
} LOG_TAG;
|
||||
|
||||
#if DEBUG_LEVEL > 0
|
||||
@ -70,13 +58,16 @@ void set_logging_mask(uint32_t mask);
|
||||
|
||||
#define dump_hex1(tag,data,len) LOG_HEX(tag,data,len)
|
||||
|
||||
uint32_t timestamp();
|
||||
|
||||
#else
|
||||
|
||||
#define set_logging_mask(mask)
|
||||
#define printf1(fmt, ...)
|
||||
#define printf2(fmt, ...)
|
||||
#define printf3(fmt, ...)
|
||||
#define printf1(tag,fmt, ...)
|
||||
#define printf2(tag,fmt, ...)
|
||||
#define printf3(tag,fmt, ...)
|
||||
#define dump_hex1(tag,data,len)
|
||||
#define timestamp()
|
||||
|
||||
#endif
|
||||
|
||||
|
77
fido2/main.c
77
fido2/main.c
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
@ -34,46 +19,39 @@
|
||||
|
||||
#if !defined(TEST)
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
int main()
|
||||
{
|
||||
uint8_t hidmsg[64];
|
||||
uint32_t t1 = 0;
|
||||
|
||||
set_logging_mask(
|
||||
/*0*/
|
||||
// TAG_GEN|
|
||||
// TAG_MC |
|
||||
// TAG_GA |
|
||||
// TAG_WALLET |
|
||||
TAG_STOR |
|
||||
// TAG_CP |
|
||||
// TAG_CTAP|
|
||||
// TAG_HID|
|
||||
/*TAG_U2F|*/
|
||||
// TAG_PARSE |
|
||||
// TAG_TIME|
|
||||
// TAG_DUMP|
|
||||
TAG_GREEN|
|
||||
TAG_RED|
|
||||
TAG_ERR
|
||||
);
|
||||
/*0*/
|
||||
//TAG_GEN|
|
||||
//TAG_MC |
|
||||
//TAG_GA |
|
||||
//TAG_WALLET |
|
||||
TAG_STOR |
|
||||
//TAG_NFC_APDU |
|
||||
TAG_NFC |
|
||||
//TAG_CP |
|
||||
//TAG_CTAP|
|
||||
//TAG_HID|
|
||||
//TAG_U2F|
|
||||
//TAG_PARSE |
|
||||
//TAG_TIME|
|
||||
//TAG_DUMP|
|
||||
TAG_GREEN|
|
||||
TAG_RED|
|
||||
TAG_ERR
|
||||
);
|
||||
|
||||
device_init();
|
||||
printf1(TAG_GEN,"init device\n");
|
||||
|
||||
usbhid_init();
|
||||
printf1(TAG_GEN,"init usb\n");
|
||||
|
||||
|
||||
ctaphid_init();
|
||||
printf1(TAG_GEN,"init ctaphid\n");
|
||||
|
||||
ctap_init();
|
||||
printf1(TAG_GEN,"init ctap\n");
|
||||
|
||||
memset(hidmsg,0,sizeof(hidmsg));
|
||||
|
||||
printf1(TAG_GEN,"recv'ing hid msg \n");
|
||||
// printf1(TAG_GEN,"recv'ing hid msg \n");
|
||||
|
||||
|
||||
while(1)
|
||||
@ -95,6 +73,7 @@ int main(int argc, char * argv[])
|
||||
{
|
||||
}
|
||||
ctaphid_check_timeouts();
|
||||
|
||||
}
|
||||
|
||||
// Should never get here
|
||||
|
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#ifndef _STORAGE_H
|
||||
#define _STORAGE_H
|
||||
|
||||
|
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#include <stdio.h>
|
||||
#include "device.h"
|
||||
#include "util.h"
|
||||
|
@ -1,25 +1,10 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
#include APP_CONFIG
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#include APP_CONFIG
|
||||
#ifdef TEST_POWER
|
||||
|
||||
/*
|
||||
|
121
fido2/u2f.c
121
fido2/u2f.c
@ -1,49 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#include <stdlib.h>
|
||||
#include "u2f.h"
|
||||
#include "ctap.h"
|
||||
#include "crypto.h"
|
||||
#include "log.h"
|
||||
#include "device.h"
|
||||
#include "apdu.h"
|
||||
#include "wallet.h"
|
||||
#ifdef ENABLE_U2F_EXTENSIONS
|
||||
#include "extensions.h"
|
||||
#endif
|
||||
#include APP_CONFIG
|
||||
|
||||
// void u2f_response_writeback(uint8_t * buf, uint8_t len);
|
||||
#ifdef ENABLE_U2F
|
||||
static int16_t u2f_register(struct u2f_register_request * req);
|
||||
static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t control);
|
||||
#endif
|
||||
int8_t u2f_response_writeback(const uint8_t * buf, uint16_t len);
|
||||
void u2f_reset_response();
|
||||
|
||||
|
||||
static CTAP_RESPONSE * _u2f_resp = NULL;
|
||||
|
||||
void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp)
|
||||
void u2f_request_ex(APDU_HEADER *req, uint8_t *payload, uint32_t len, CTAP_RESPONSE * resp)
|
||||
{
|
||||
uint16_t rcode = 0;
|
||||
uint64_t t1,t2;
|
||||
uint32_t len = ((req->LC3) | ((uint32_t)req->LC2 << 8) | ((uint32_t)req->LC1 << 16));
|
||||
uint8_t byte;
|
||||
|
||||
ctap_response_init(resp);
|
||||
u2f_set_writeback_buffer(resp);
|
||||
|
||||
if (req->cla != 0)
|
||||
@ -53,9 +43,9 @@ void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp)
|
||||
goto end;
|
||||
}
|
||||
#ifdef ENABLE_U2F_EXTENSIONS
|
||||
rcode = extend_u2f(req, len);
|
||||
rcode = extend_u2f(req, payload, len);
|
||||
#endif
|
||||
if (rcode != U2F_SW_NO_ERROR) // If the extension didn't do anything...
|
||||
if (rcode != U2F_SW_NO_ERROR && rcode != U2F_SW_CONDITIONS_NOT_SATISFIED) // If the extension didn't do anything...
|
||||
{
|
||||
#ifdef ENABLE_U2F
|
||||
switch(req->ins)
|
||||
@ -68,18 +58,18 @@ void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp)
|
||||
}
|
||||
else
|
||||
{
|
||||
t1 = millis();
|
||||
rcode = u2f_register((struct u2f_register_request*)req->payload);
|
||||
t2 = millis();
|
||||
printf1(TAG_TIME,"u2f_register time: %d ms\n", t2-t1);
|
||||
|
||||
timestamp();
|
||||
rcode = u2f_register((struct u2f_register_request*)payload);
|
||||
printf1(TAG_TIME,"u2f_register time: %d ms\n", timestamp());
|
||||
|
||||
}
|
||||
break;
|
||||
case U2F_AUTHENTICATE:
|
||||
printf1(TAG_U2F, "U2F_AUTHENTICATE\n");
|
||||
t1 = millis();
|
||||
rcode = u2f_authenticate((struct u2f_authenticate_request*)req->payload, req->p1);
|
||||
t2 = millis();
|
||||
printf1(TAG_TIME,"u2f_authenticate time: %d ms\n", t2-t1);
|
||||
timestamp();
|
||||
rcode = u2f_authenticate((struct u2f_authenticate_request*)payload, req->p1);
|
||||
printf1(TAG_TIME,"u2f_authenticate time: %d ms\n", timestamp());
|
||||
break;
|
||||
case U2F_VERSION:
|
||||
printf1(TAG_U2F, "U2F_VERSION\n");
|
||||
@ -120,6 +110,22 @@ end:
|
||||
printf1(TAG_U2F,"u2f resp: "); dump_hex1(TAG_U2F, _u2f_resp->data, _u2f_resp->length);
|
||||
}
|
||||
|
||||
void u2f_request_nfc(uint8_t * req, int len, CTAP_RESPONSE * resp)
|
||||
{
|
||||
if (len < 5 || !req)
|
||||
return;
|
||||
|
||||
uint32_t alen = req[4];
|
||||
|
||||
u2f_request_ex((APDU_HEADER *)req, &req[5], alen, resp);
|
||||
}
|
||||
|
||||
void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp)
|
||||
{
|
||||
uint32_t len = ((req->LC3) | ((uint32_t)req->LC2 << 8) | ((uint32_t)req->LC1 << 16));
|
||||
|
||||
u2f_request_ex((APDU_HEADER *)req, req->payload, len, resp);
|
||||
}
|
||||
|
||||
int8_t u2f_response_writeback(const uint8_t * buf, uint16_t len)
|
||||
{
|
||||
@ -143,6 +149,7 @@ void u2f_set_writeback_buffer(CTAP_RESPONSE * resp)
|
||||
_u2f_resp = resp;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_U2F
|
||||
static void dump_signature_der(uint8_t * sig)
|
||||
{
|
||||
uint8_t sigder[72];
|
||||
@ -166,7 +173,7 @@ static void u2f_make_auth_tag(struct u2f_key_handle * kh, uint8_t * appid, uint8
|
||||
memmove(tag, hashbuf, CREDENTIAL_TAG_SIZE);
|
||||
}
|
||||
|
||||
static int8_t u2f_new_keypair(struct u2f_key_handle * kh, uint8_t * appid, uint8_t * pubkey)
|
||||
int8_t u2f_new_keypair(struct u2f_key_handle * kh, uint8_t * appid, uint8_t * pubkey)
|
||||
{
|
||||
ctap_generate_rng(kh->key, U2F_KEY_HANDLE_KEY_SIZE);
|
||||
u2f_make_auth_tag(kh, appid, kh->tag);
|
||||
@ -206,6 +213,7 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
|
||||
|
||||
if (control == U2F_AUTHENTICATE_CHECK)
|
||||
{
|
||||
printf1(TAG_U2F, "CHECK-ONLY\r\n");
|
||||
if (u2f_appid_eq(&req->kh, req->app) == 0)
|
||||
{
|
||||
return U2F_SW_CONDITIONS_NOT_SATISFIED;
|
||||
@ -216,22 +224,27 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
|
||||
}
|
||||
}
|
||||
if (
|
||||
control != U2F_AUTHENTICATE_SIGN ||
|
||||
req->khl != U2F_KEY_HANDLE_SIZE ||
|
||||
(control != U2F_AUTHENTICATE_SIGN && control != U2F_AUTHENTICATE_SIGN_NO_USER) ||
|
||||
req->khl != U2F_KEY_HANDLE_SIZE ||
|
||||
u2f_appid_eq(&req->kh, req->app) != 0 || // Order of checks is important
|
||||
u2f_load_key(&req->kh, req->app) != 0
|
||||
|
||||
)
|
||||
{
|
||||
return U2F_SW_WRONG_PAYLOAD;
|
||||
return U2F_SW_WRONG_DATA;
|
||||
}
|
||||
|
||||
// dont-enforce-user-presence-and-sign
|
||||
if (control == U2F_AUTHENTICATE_SIGN_NO_USER)
|
||||
up = 0;
|
||||
|
||||
|
||||
if (ctap_user_presence_test() == 0)
|
||||
{
|
||||
return U2F_SW_CONDITIONS_NOT_SATISFIED;
|
||||
}
|
||||
if(!device_is_nfc() && up)
|
||||
{
|
||||
if (ctap_user_presence_test() == 0)
|
||||
{
|
||||
return U2F_SW_CONDITIONS_NOT_SATISFIED;
|
||||
}
|
||||
}
|
||||
|
||||
count = ctap_atomic_count(0);
|
||||
hash[0] = (count >> 24) & 0xff;
|
||||
@ -240,14 +253,14 @@ static int16_t u2f_authenticate(struct u2f_authenticate_request * req, uint8_t c
|
||||
hash[3] = (count >> 0) & 0xff;
|
||||
crypto_sha256_init();
|
||||
|
||||
crypto_sha256_update(req->app,32);
|
||||
crypto_sha256_update(&up,1);
|
||||
crypto_sha256_update(hash,4);
|
||||
crypto_sha256_update(req->chal,32);
|
||||
crypto_sha256_update(req->app, 32);
|
||||
crypto_sha256_update(&up, 1);
|
||||
crypto_sha256_update(hash, 4);
|
||||
crypto_sha256_update(req->chal, 32);
|
||||
|
||||
crypto_sha256_final(hash);
|
||||
|
||||
printf1(TAG_U2F, "sha256: "); dump_hex1(TAG_U2F,hash,32);
|
||||
printf1(TAG_U2F, "sha256: "); dump_hex1(TAG_U2F, hash, 32);
|
||||
crypto_ecc256_sign(hash, 32, sig);
|
||||
|
||||
u2f_response_writeback(&up,1);
|
||||
@ -273,10 +286,13 @@ static int16_t u2f_register(struct u2f_register_request * req)
|
||||
|
||||
const uint16_t attest_size = attestation_cert_der_size;
|
||||
|
||||
if ( ! ctap_user_presence_test())
|
||||
{
|
||||
return U2F_SW_CONDITIONS_NOT_SATISFIED;
|
||||
}
|
||||
if(!device_is_nfc())
|
||||
{
|
||||
if ( ! ctap_user_presence_test())
|
||||
{
|
||||
return U2F_SW_CONDITIONS_NOT_SATISFIED;
|
||||
}
|
||||
}
|
||||
|
||||
if ( u2f_new_keypair(&key_handle, req->app, pubkey) == -1)
|
||||
{
|
||||
@ -315,6 +331,7 @@ static int16_t u2f_register(struct u2f_register_request * req)
|
||||
|
||||
return U2F_SW_NO_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
int16_t u2f_version()
|
||||
{
|
||||
|
38
fido2/u2f.h
38
fido2/u2f.h
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#ifndef _U2F_H_
|
||||
#define _U2F_H_
|
||||
|
||||
@ -53,16 +38,16 @@
|
||||
// U2F Authenticate
|
||||
#define U2F_AUTHENTICATE_CHECK 0x7
|
||||
#define U2F_AUTHENTICATE_SIGN 0x3
|
||||
#define U2F_AUTHENTICATE_SIGN_NO_USER 0x8
|
||||
|
||||
|
||||
// Command status responses
|
||||
#define U2F_SW_NO_ERROR 0x9000
|
||||
#define U2F_SW_WRONG_DATA 0x6984
|
||||
#define U2F_SW_CONDITIONS_NOT_SATISFIED 0x6985
|
||||
#define U2F_SW_INS_NOT_SUPPORTED 0x6d00
|
||||
#define U2F_SW_WRONG_LENGTH 0x6700
|
||||
#define U2F_SW_CLASS_NOT_SUPPORTED 0x6E00
|
||||
#define U2F_SW_WRONG_PAYLOAD 0x6a80
|
||||
#define U2F_SW_WRONG_DATA 0x6a80
|
||||
#define U2F_SW_INSUFFICIENT_MEMORY 0x9210
|
||||
|
||||
// Delay in milliseconds to wait for user input
|
||||
@ -110,9 +95,14 @@ struct u2f_authenticate_request
|
||||
};
|
||||
|
||||
// u2f_request send a U2F message to U2F protocol
|
||||
// @req U2F message
|
||||
// @req U2F message
|
||||
void u2f_request(struct u2f_request_apdu* req, CTAP_RESPONSE * resp);
|
||||
|
||||
// u2f_request send a U2F message to NFC protocol
|
||||
// @req data with iso7816 apdu message
|
||||
// @len data length
|
||||
void u2f_request_nfc(uint8_t * req, int len, CTAP_RESPONSE * resp);
|
||||
|
||||
|
||||
int8_t u2f_response_writeback(const uint8_t * buf, uint16_t len);
|
||||
void u2f_reset_response();
|
||||
|
27
fido2/util.c
27
fido2/util.c
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
27
fido2/util.h
27
fido2/util.h
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#ifndef _UTIL_H
|
||||
#define _UTIL_H
|
||||
|
||||
|
21
fido2/version.h
Normal file
21
fido2/version.h
Normal file
@ -0,0 +1,21 @@
|
||||
#ifndef _VERSION_H_
|
||||
#define _VERSION_H_
|
||||
|
||||
|
||||
#ifndef SOLO_VERSION_MAJ
|
||||
|
||||
#define SOLO_VERSION_MAJ 0
|
||||
#define SOLO_VERSION_MIN 0
|
||||
#define SOLO_VERSION_PATCH 0
|
||||
|
||||
#endif
|
||||
|
||||
#define __STR_HELPER(x) #x
|
||||
#define __STR(x) __STR_HELPER(x)
|
||||
|
||||
#ifndef SOLO_VERSION
|
||||
#define SOLO_VERSION __STR(SOLO_VERSION_MAJ) "." __STR(SOLO_VERSION_MIN) "." __STR(SOLO_VERSION_PATCH)
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
51
in-docker-build.sh
Executable file
51
in-docker-build.sh
Executable file
@ -0,0 +1,51 @@
|
||||
#!/bin/bash -xe
|
||||
|
||||
version=${1:-master}
|
||||
|
||||
export PREFIX=/opt/gcc-arm-none-eabi-8-2018-q4-major/bin/
|
||||
|
||||
cd /solo/targets/stm32l432
|
||||
git fetch --tags
|
||||
git checkout ${version}
|
||||
git submodule update --init --recursive
|
||||
version=$(git describe)
|
||||
|
||||
make cbor
|
||||
|
||||
out_dir="/builds"
|
||||
|
||||
function build() {
|
||||
part=${1}
|
||||
variant=${2}
|
||||
output=${3:-${part}}
|
||||
what="${part}-${variant}"
|
||||
|
||||
make full-clean
|
||||
|
||||
make ${what}
|
||||
|
||||
out_hex="${what}-${version}.hex"
|
||||
out_sha2="${what}-${version}.sha2"
|
||||
|
||||
mv ${output}.hex ${out_hex}
|
||||
sha256sum ${out_hex} > ${out_sha2}
|
||||
cp ${out_hex} ${out_sha2} ${out_dir}
|
||||
}
|
||||
|
||||
build bootloader nonverifying
|
||||
build bootloader verifying
|
||||
build firmware hacker solo
|
||||
build firmware hacker-debug-1 solo
|
||||
build firmware hacker-debug-2 solo
|
||||
build firmware secure solo
|
||||
|
||||
pip install -U pip
|
||||
pip install -U solo-python
|
||||
cd ${out_dir}
|
||||
bundle="bundle-hacker-${version}"
|
||||
/opt/conda/bin/solo mergehex bootloader-nonverifying-${version}.hex firmware-hacker-${version}.hex ${bundle}.hex
|
||||
sha256sum ${bundle}.hex > ${bundle}.sha2
|
||||
bundle="bundle-hacker-debug-1-${version}"
|
||||
/opt/conda/bin/solo mergehex bootloader-nonverifying-${version}.hex firmware-hacker-debug-1-${version}.hex ${bundle}.hex
|
||||
bundle="bundle-hacker-debug-2-${version}"
|
||||
/opt/conda/bin/solo mergehex bootloader-nonverifying-${version}.hex firmware-hacker-debug-2-${version}.hex ${bundle}.hex
|
39
metadata/Solo-FIDO2-CTAP2-Authenticator.json
Normal file
39
metadata/Solo-FIDO2-CTAP2-Authenticator.json
Normal file
File diff suppressed because one or more lines are too long
37
metadata/Solo-FIDO2-U2F-Authenticator.json
Normal file
37
metadata/Solo-FIDO2-U2F-Authenticator.json
Normal file
File diff suppressed because one or more lines are too long
@ -9,6 +9,7 @@ copyright: 'Copyright © 2018 - 2019 SoloKeys'
|
||||
nav:
|
||||
- Home: solo/index.md
|
||||
- FIDO2 Implementation: solo/fido2-impl.md
|
||||
- Metadata Statements: solo/metadata-statements.md
|
||||
- Build instructions: solo/building.md
|
||||
- Signed update process: solo/signed-updates.md
|
||||
- Code documentation: solo/code-overview.md
|
||||
@ -21,3 +22,6 @@ theme:
|
||||
name: material
|
||||
logo: 'solo/images/logo.svg'
|
||||
favicon: 'solo/images/favicon.ico'
|
||||
|
||||
markdown_extensions:
|
||||
- markdown_include.include
|
||||
|
30
pc/app.h
30
pc/app.h
@ -1,24 +1,10 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
|
||||
#ifndef SRC_APP_H_
|
||||
#define SRC_APP_H_
|
||||
|
||||
@ -29,7 +15,7 @@
|
||||
#define DEBUG_LEVEL 1
|
||||
|
||||
#define ENABLE_U2F
|
||||
|
||||
#define ENABLE_U2F_EXTENSIONS
|
||||
//#define BRIDGE_TO_WALLET
|
||||
|
||||
void printing_init();
|
||||
|
153
pc/device.c
153
pc/device.c
@ -1,24 +1,9 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
// Copyright 2019 SoloKeys Developers
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
||||
// http://opensource.org/licenses/MIT>, at your option. This file may not be
|
||||
// copied, modified, or distributed except according to those terms.
|
||||
#include <sys/time.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@ -37,11 +22,16 @@
|
||||
#include "log.h"
|
||||
#include "ctaphid.h"
|
||||
|
||||
#define RK_NUM 50
|
||||
|
||||
struct ResidentKeyStore {
|
||||
CTAP_residentKey rks[RK_NUM];
|
||||
} RK_STORE;
|
||||
|
||||
void authenticator_initialize();
|
||||
|
||||
uint32_t __device_status = 0;
|
||||
void device_set_status(int status)
|
||||
void device_set_status(uint32_t status)
|
||||
{
|
||||
if (status != CTAPHID_STATUS_IDLE && __device_status != status)
|
||||
{
|
||||
@ -54,7 +44,11 @@ void device_set_status(int status)
|
||||
|
||||
int udp_server()
|
||||
{
|
||||
int fd;
|
||||
static bool run_already = false;
|
||||
static int fd = -1;
|
||||
if (run_already && fd >= 0) return fd;
|
||||
run_already = true;
|
||||
|
||||
if ( (fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
|
||||
perror( "socket failed" );
|
||||
return 1;
|
||||
@ -152,11 +146,20 @@ void usbhid_init()
|
||||
int usbhid_recv(uint8_t * msg)
|
||||
{
|
||||
int l = udp_recv(serverfd, msg, HID_MESSAGE_SIZE);
|
||||
/*if (l && l != HID_MESSAGE_SIZE)*/
|
||||
/*{*/
|
||||
/*printf("Error, recv'd message of wrong size %d", l);*/
|
||||
/*exit(1);*/
|
||||
/*}*/
|
||||
uint8_t magic_cmd[] = "\xac\x10\x52\xca\x95\xe5\x69\xde\x69\xe0\x2e\xbf"
|
||||
"\xf3\x33\x48\x5f\x13\xf9\xb2\xda\x34\xc5\xa8\xa3"
|
||||
"\x40\x52\x66\x97\xa9\xab\x2e\x0b\x39\x4d\x8d\x04"
|
||||
"\x97\x3c\x13\x40\x05\xbe\x1a\x01\x40\xbf\xf6\x04"
|
||||
"\x5b\xb2\x6e\xb7\x7a\x73\xea\xa4\x78\x13\xf6\xb4"
|
||||
"\x9a\x72\x50\xdc";
|
||||
if ( memcmp(magic_cmd, msg, 64) == 0 )
|
||||
{
|
||||
printf1(TAG_RED, "MAGIC REBOOT command recieved!\r\n");
|
||||
memset(msg,0,64);
|
||||
exit(100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
@ -185,6 +188,10 @@ void device_init()
|
||||
usbhid_init();
|
||||
|
||||
authenticator_initialize();
|
||||
|
||||
ctaphid_init();
|
||||
|
||||
ctap_init( 1 );
|
||||
}
|
||||
|
||||
|
||||
@ -192,7 +199,7 @@ void main_loop_delay()
|
||||
{
|
||||
struct timespec ts;
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 1000*1000*25;
|
||||
ts.tv_nsec = 1000*1000*100;
|
||||
nanosleep(&ts,NULL);
|
||||
}
|
||||
|
||||
@ -258,6 +265,7 @@ int ctap_generate_rng(uint8_t * dst, size_t num)
|
||||
|
||||
const char * state_file = "authenticator_state.bin";
|
||||
const char * backup_file = "authenticator_state2.bin";
|
||||
const char * rk_file = "resident_keys.bin";
|
||||
|
||||
void authenticator_read_state(AuthenticatorState * state)
|
||||
{
|
||||
@ -377,6 +385,24 @@ int authenticator_is_backup_initialized()
|
||||
|
||||
/*}*/
|
||||
|
||||
static void sync_rk()
|
||||
{
|
||||
FILE * f = fopen(rk_file, "wb+");
|
||||
if (f== NULL)
|
||||
{
|
||||
perror("fopen");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int ret = fwrite(&RK_STORE, 1, sizeof(RK_STORE), f);
|
||||
fclose(f);
|
||||
if (ret != sizeof(RK_STORE))
|
||||
{
|
||||
perror("fwrite");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void authenticator_initialize()
|
||||
{
|
||||
uint8_t header[16];
|
||||
@ -400,6 +426,22 @@ void authenticator_initialize()
|
||||
perror("fwrite");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// resident_keys
|
||||
f = fopen(rk_file, "rb");
|
||||
if (f== NULL)
|
||||
{
|
||||
perror("fopen");
|
||||
exit(1);
|
||||
}
|
||||
ret = fread(&RK_STORE, 1, sizeof(RK_STORE), f);
|
||||
fclose(f);
|
||||
if(ret != sizeof(RK_STORE))
|
||||
{
|
||||
perror("fwrite");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -438,6 +480,12 @@ void authenticator_initialize()
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// resident_keys
|
||||
memset(&RK_STORE,0xff,sizeof(RK_STORE));
|
||||
sync_rk();
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -446,29 +494,60 @@ void device_manage()
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ctap_reset_rk()
|
||||
{
|
||||
memset(&RK_STORE,0xff,sizeof(RK_STORE));
|
||||
sync_rk();
|
||||
|
||||
}
|
||||
|
||||
uint32_t ctap_rk_size()
|
||||
{
|
||||
printf("Warning: rk not implemented\n");
|
||||
return 0;
|
||||
return RK_NUM;
|
||||
}
|
||||
void ctap_store_rk(int index,CTAP_residentKey * rk)
|
||||
|
||||
|
||||
void ctap_store_rk(int index, CTAP_residentKey * rk)
|
||||
{
|
||||
printf("Warning: rk not implemented\n");
|
||||
if (index < RK_NUM)
|
||||
{
|
||||
memmove(RK_STORE.rks + index, rk, sizeof(CTAP_residentKey));
|
||||
sync_rk();
|
||||
}
|
||||
else
|
||||
{
|
||||
printf1(TAG_ERR,"Out of bounds for store_rk\r\n");
|
||||
}
|
||||
|
||||
}
|
||||
void ctap_load_rk(int index,CTAP_residentKey * rk)
|
||||
|
||||
|
||||
void ctap_load_rk(int index, CTAP_residentKey * rk)
|
||||
{
|
||||
printf("Warning: rk not implemented\n");
|
||||
memmove(rk, RK_STORE.rks + index, sizeof(CTAP_residentKey));
|
||||
}
|
||||
void ctap_overwrite_rk(int index,CTAP_residentKey * rk)
|
||||
|
||||
void ctap_overwrite_rk(int index, CTAP_residentKey * rk)
|
||||
{
|
||||
printf("Warning: rk not implemented\n");
|
||||
if (index < RK_NUM)
|
||||
{
|
||||
memmove(RK_STORE.rks + index, rk, sizeof(CTAP_residentKey));
|
||||
sync_rk();
|
||||
}
|
||||
else
|
||||
{
|
||||
printf1(TAG_ERR,"Out of bounds for store_rk\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
void device_wink()
|
||||
{
|
||||
printf("*WINK*\n");
|
||||
}
|
||||
|
||||
bool device_is_nfc()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
Submodule python-fido2 deleted from 329434fdd4
File diff suppressed because one or more lines are too long
@ -1,49 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>EFM32</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>com.silabs.ss.framework.ide.project.sls.core.SLSProjectNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>crypto</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/crypto</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>fido2</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-2-PROJECT_LOC%7D/fido2</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>CMSIS/EFM32JG1B/startup_gcc_efm32jg1b.s</name>
|
||||
<type>1</type>
|
||||
<locationURI>STUDIO_SDK_LOC/platform/Device/SiliconLabs/EFM32JG1B/Source/GCC/startup_efm32jg1b.S</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>CMSIS/EFM32JG1B/system_efm32jg1b.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>STUDIO_SDK_LOC/platform/Device/SiliconLabs/EFM32JG1B/Source/system_efm32jg1b.c</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
@ -1,2 +0,0 @@
|
||||
copiedFilesOriginState={}
|
||||
eclipse.preferences.version=1
|
@ -1,70 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn=Warning
|
||||
org.eclipse.cdt.codan.checkers.errnoreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue=Error
|
||||
org.eclipse.cdt.codan.checkers.errreturnvalue.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.checkers.nocommentinside=-Error
|
||||
org.eclipse.cdt.codan.checkers.nocommentinside.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.checkers.nolinecomment=-Error
|
||||
org.eclipse.cdt.codan.checkers.nolinecomment.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.checkers.noreturn=Error
|
||||
org.eclipse.cdt.codan.checkers.noreturn.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},implicit\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AbstractClassCreation.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.AmbiguousProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentInConditionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.AssignmentToItselfProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CaseBreakProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},no_break_comment\=>"no break",last_case_param\=>false,empty_case_param\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.CatchByReference.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},unknown\=>false,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.CircularReferenceProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ClassMembersInitialization.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},skip\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FieldResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.FunctionResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidArguments.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.InvalidTemplateArgumentsProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.LabelStatementNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MemberDeclarationNotFoundProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.MethodResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker=-Info
|
||||
org.eclipse.cdt.codan.internal.checkers.NamingConventionFunctionChecker.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},pattern\=>"^[a-z]",macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.NonVirtualDestructorProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.OverloadProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.RedefinitionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ReturnStyleProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem=-Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.ScanfFormatStringSecurityProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.StatementHasNoEffectProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>()}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuggestedParenthesisProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},paramNot\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.SuspiciousSemicolonProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},else\=>false,afterelse\=>false}
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedFunctionDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedStaticFunctionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true}
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem=Warning
|
||||
org.eclipse.cdt.codan.internal.checkers.UnusedVariableDeclarationProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true},macro\=>true,exceptions\=>("@(\#)","$Id")}
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem=Error
|
||||
org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem.params={launchModes\=>{RUN_ON_FULL_BUILD\=>true,RUN_ON_INC_BUILD\=>true,RUN_ON_FILE_OPEN\=>false,RUN_ON_FILE_SAVE\=>false,RUN_AS_YOU_TYPE\=>true,RUN_ON_DEMAND\=>true}}
|
@ -1,317 +0,0 @@
|
||||
/* @file startup_efm32pg1b.S
|
||||
* @brief startup file for Silicon Labs EFM32PG1B devices.
|
||||
* For use with GCC for ARM Embedded Processors
|
||||
* @version 5.2.2
|
||||
* Date: 12 June 2014
|
||||
*
|
||||
*/
|
||||
/* Copyright (c) 2011 - 2014 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
.syntax unified
|
||||
.arch armv7-m
|
||||
.section .stack
|
||||
.align 3
|
||||
#ifdef __STACK_SIZE
|
||||
.equ Stack_Size, __STACK_SIZE
|
||||
#else
|
||||
.equ Stack_Size, 0x00000400
|
||||
#endif
|
||||
.globl __StackTop
|
||||
.globl __StackLimit
|
||||
__StackLimit:
|
||||
.space Stack_Size
|
||||
.size __StackLimit, . - __StackLimit
|
||||
__StackTop:
|
||||
.size __StackTop, . - __StackTop
|
||||
|
||||
.section .heap
|
||||
.align 3
|
||||
#ifdef __HEAP_SIZE
|
||||
.equ Heap_Size, __HEAP_SIZE
|
||||
#else
|
||||
.equ Heap_Size, 0x00000C00
|
||||
#endif
|
||||
.globl __HeapBase
|
||||
.globl __HeapLimit
|
||||
__HeapBase:
|
||||
.if Heap_Size
|
||||
.space Heap_Size
|
||||
.endif
|
||||
.size __HeapBase, . - __HeapBase
|
||||
__HeapLimit:
|
||||
.size __HeapLimit, . - __HeapLimit
|
||||
|
||||
.section .vectors
|
||||
.align 2
|
||||
.globl __Vectors
|
||||
__Vectors:
|
||||
.long __StackTop /* Top of Stack */
|
||||
.long Reset_Handler /* Reset Handler */
|
||||
.long NMI_Handler /* NMI Handler */
|
||||
.long HardFault_Handler /* Hard Fault Handler */
|
||||
.long MemManage_Handler /* MPU Fault Handler */
|
||||
.long BusFault_Handler /* Bus Fault Handler */
|
||||
.long UsageFault_Handler /* Usage Fault Handler */
|
||||
.long Default_Handler /* Reserved */
|
||||
.long Default_Handler /* Reserved */
|
||||
.long Default_Handler /* Reserved */
|
||||
.long Default_Handler /* Reserved */
|
||||
.long SVC_Handler /* SVCall Handler */
|
||||
.long DebugMon_Handler /* Debug Monitor Handler */
|
||||
.long Default_Handler /* Reserved */
|
||||
.long PendSV_Handler /* PendSV Handler */
|
||||
.long SysTick_Handler /* SysTick Handler */
|
||||
|
||||
/* External interrupts */
|
||||
.long EMU_IRQHandler /* 0 - EMU */
|
||||
.long Default_Handler /* 1 - Reserved */
|
||||
.long WDOG0_IRQHandler /* 2 - WDOG0 */
|
||||
.long Default_Handler /* 3 - Reserved */
|
||||
.long Default_Handler /* 4 - Reserved */
|
||||
.long Default_Handler /* 5 - Reserved */
|
||||
.long Default_Handler /* 6 - Reserved */
|
||||
.long Default_Handler /* 7 - Reserved */
|
||||
.long LDMA_IRQHandler /* 8 - LDMA */
|
||||
.long GPIO_EVEN_IRQHandler /* 9 - GPIO_EVEN */
|
||||
.long TIMER0_IRQHandler /* 10 - TIMER0 */
|
||||
.long USART0_RX_IRQHandler /* 11 - USART0_RX */
|
||||
.long USART0_TX_IRQHandler /* 12 - USART0_TX */
|
||||
.long ACMP0_IRQHandler /* 13 - ACMP0 */
|
||||
.long ADC0_IRQHandler /* 14 - ADC0 */
|
||||
.long IDAC0_IRQHandler /* 15 - IDAC0 */
|
||||
.long I2C0_IRQHandler /* 16 - I2C0 */
|
||||
.long GPIO_ODD_IRQHandler /* 17 - GPIO_ODD */
|
||||
.long TIMER1_IRQHandler /* 18 - TIMER1 */
|
||||
.long USART1_RX_IRQHandler /* 19 - USART1_RX */
|
||||
.long USART1_TX_IRQHandler /* 20 - USART1_TX */
|
||||
.long LEUART0_IRQHandler /* 21 - LEUART0 */
|
||||
.long PCNT0_IRQHandler /* 22 - PCNT0 */
|
||||
.long CMU_IRQHandler /* 23 - CMU */
|
||||
.long MSC_IRQHandler /* 24 - MSC */
|
||||
.long CRYPTO_IRQHandler /* 25 - CRYPTO */
|
||||
.long LETIMER0_IRQHandler /* 26 - LETIMER0 */
|
||||
.long Default_Handler /* 27 - Reserved */
|
||||
.long Default_Handler /* 28 - Reserved */
|
||||
.long RTCC_IRQHandler /* 29 - RTCC */
|
||||
.long Default_Handler /* 30 - Reserved */
|
||||
.long CRYOTIMER_IRQHandler /* 31 - CRYOTIMER */
|
||||
.long Default_Handler /* 32 - Reserved */
|
||||
.long FPUEH_IRQHandler /* 33 - FPUEH */
|
||||
|
||||
|
||||
.size __Vectors, . - __Vectors
|
||||
|
||||
.text
|
||||
.thumb
|
||||
.thumb_func
|
||||
.align 2
|
||||
.globl Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
#ifndef __NO_SYSTEM_INIT
|
||||
ldr r0, =SystemInit
|
||||
blx r0
|
||||
#endif
|
||||
|
||||
/* Firstly it copies data from read only memory to RAM. There are two schemes
|
||||
* to copy. One can copy more than one sections. Another can only copy
|
||||
* one section. The former scheme needs more instructions and read-only
|
||||
* data to implement than the latter.
|
||||
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
|
||||
|
||||
#ifdef __STARTUP_COPY_MULTIPLE
|
||||
/* Multiple sections scheme.
|
||||
*
|
||||
* Between symbol address __copy_table_start__ and __copy_table_end__,
|
||||
* there are array of triplets, each of which specify:
|
||||
* offset 0: LMA of start of a section to copy from
|
||||
* offset 4: VMA of start of a section to copy to
|
||||
* offset 8: size of the section to copy. Must be multiply of 4
|
||||
*
|
||||
* All addresses must be aligned to 4 bytes boundary.
|
||||
*/
|
||||
ldr r4, =__copy_table_start__
|
||||
ldr r5, =__copy_table_end__
|
||||
|
||||
.L_loop0:
|
||||
cmp r4, r5
|
||||
bge .L_loop0_done
|
||||
ldr r1, [r4]
|
||||
ldr r2, [r4, #4]
|
||||
ldr r3, [r4, #8]
|
||||
|
||||
.L_loop0_0:
|
||||
subs r3, #4
|
||||
ittt ge
|
||||
ldrge r0, [r1, r3]
|
||||
strge r0, [r2, r3]
|
||||
bge .L_loop0_0
|
||||
|
||||
adds r4, #12
|
||||
b .L_loop0
|
||||
|
||||
.L_loop0_done:
|
||||
#else
|
||||
/* Single section scheme.
|
||||
*
|
||||
* The ranges of copy from/to are specified by following symbols
|
||||
* __etext: LMA of start of the section to copy from. Usually end of text
|
||||
* __data_start__: VMA of start of the section to copy to
|
||||
* __data_end__: VMA of end of the section to copy to
|
||||
*
|
||||
* All addresses must be aligned to 4 bytes boundary.
|
||||
*/
|
||||
ldr r1, =__etext
|
||||
ldr r2, =__data_start__
|
||||
ldr r3, =__data_end__
|
||||
|
||||
.L_loop1:
|
||||
cmp r2, r3
|
||||
ittt lt
|
||||
ldrlt r0, [r1], #4
|
||||
strlt r0, [r2], #4
|
||||
blt .L_loop1
|
||||
#endif /*__STARTUP_COPY_MULTIPLE */
|
||||
|
||||
/* This part of work usually is done in C library startup code. Otherwise,
|
||||
* define this macro to enable it in this startup.
|
||||
*
|
||||
* There are two schemes too. One can clear multiple BSS sections. Another
|
||||
* can only clear one section. The former is more size expensive than the
|
||||
* latter.
|
||||
*
|
||||
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
|
||||
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
|
||||
*/
|
||||
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
|
||||
/* Multiple sections scheme.
|
||||
*
|
||||
* Between symbol address __zero_table_start__ and __zero_table_end__,
|
||||
* there are array of tuples specifying:
|
||||
* offset 0: Start of a BSS section
|
||||
* offset 4: Size of this BSS section. Must be multiply of 4
|
||||
*/
|
||||
ldr r3, =__zero_table_start__
|
||||
ldr r4, =__zero_table_end__
|
||||
|
||||
.L_loop2:
|
||||
cmp r3, r4
|
||||
bge .L_loop2_done
|
||||
ldr r1, [r3]
|
||||
ldr r2, [r3, #4]
|
||||
movs r0, 0
|
||||
|
||||
.L_loop2_0:
|
||||
subs r2, #4
|
||||
itt ge
|
||||
strge r0, [r1, r2]
|
||||
bge .L_loop2_0
|
||||
adds r3, #8
|
||||
b .L_loop2
|
||||
.L_loop2_done:
|
||||
#elif defined (__STARTUP_CLEAR_BSS)
|
||||
/* Single BSS section scheme.
|
||||
*
|
||||
* The BSS section is specified by following symbols
|
||||
* __bss_start__: start of the BSS section.
|
||||
* __bss_end__: end of the BSS section.
|
||||
*
|
||||
* Both addresses must be aligned to 4 bytes boundary.
|
||||
*/
|
||||
ldr r1, =__bss_start__
|
||||
ldr r2, =__bss_end__
|
||||
|
||||
movs r0, 0
|
||||
.L_loop3:
|
||||
cmp r1, r2
|
||||
itt lt
|
||||
strlt r0, [r1], #4
|
||||
blt .L_loop3
|
||||
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
|
||||
|
||||
#ifndef __START
|
||||
#define __START _start
|
||||
#endif
|
||||
bl __START
|
||||
|
||||
.pool
|
||||
.size Reset_Handler, . - Reset_Handler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak Default_Handler
|
||||
.type Default_Handler, %function
|
||||
Default_Handler:
|
||||
b .
|
||||
.size Default_Handler, . - Default_Handler
|
||||
|
||||
/* Macro to define default handlers. Default handler
|
||||
* will be weak symbol and just dead loops. They can be
|
||||
* overwritten by other handlers */
|
||||
.macro def_irq_handler handler_name
|
||||
.weak \handler_name
|
||||
.set \handler_name, Default_Handler
|
||||
.endm
|
||||
|
||||
def_irq_handler NMI_Handler
|
||||
def_irq_handler HardFault_Handler
|
||||
def_irq_handler MemManage_Handler
|
||||
def_irq_handler BusFault_Handler
|
||||
def_irq_handler UsageFault_Handler
|
||||
def_irq_handler SVC_Handler
|
||||
def_irq_handler DebugMon_Handler
|
||||
def_irq_handler PendSV_Handler
|
||||
def_irq_handler SysTick_Handler
|
||||
|
||||
|
||||
def_irq_handler EMU_IRQHandler
|
||||
def_irq_handler WDOG0_IRQHandler
|
||||
def_irq_handler LDMA_IRQHandler
|
||||
def_irq_handler GPIO_EVEN_IRQHandler
|
||||
def_irq_handler TIMER0_IRQHandler
|
||||
def_irq_handler USART0_RX_IRQHandler
|
||||
def_irq_handler USART0_TX_IRQHandler
|
||||
def_irq_handler ACMP0_IRQHandler
|
||||
def_irq_handler ADC0_IRQHandler
|
||||
def_irq_handler IDAC0_IRQHandler
|
||||
def_irq_handler I2C0_IRQHandler
|
||||
def_irq_handler GPIO_ODD_IRQHandler
|
||||
def_irq_handler TIMER1_IRQHandler
|
||||
def_irq_handler USART1_RX_IRQHandler
|
||||
def_irq_handler USART1_TX_IRQHandler
|
||||
def_irq_handler LEUART0_IRQHandler
|
||||
def_irq_handler PCNT0_IRQHandler
|
||||
def_irq_handler CMU_IRQHandler
|
||||
def_irq_handler MSC_IRQHandler
|
||||
def_irq_handler CRYPTO_IRQHandler
|
||||
def_irq_handler LETIMER0_IRQHandler
|
||||
def_irq_handler RTCC_IRQHandler
|
||||
def_irq_handler CRYOTIMER_IRQHandler
|
||||
def_irq_handler FPUEH_IRQHandler
|
||||
|
||||
.end
|
@ -1,389 +0,0 @@
|
||||
/***************************************************************************//**
|
||||
* @file system_efm32pg1b.c
|
||||
* @brief CMSIS Cortex-M3/M4 System Layer for EFM32 devices.
|
||||
* @version 5.2.2
|
||||
******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2017 Silicon Laboratories, Inc. http://www.silabs.com</b>
|
||||
******************************************************************************
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software.@n
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.@n
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc.
|
||||
* has no obligation to support this Software. Silicon Laboratories, Inc. is
|
||||
* providing the Software "AS IS", with no express or implied warranties of any
|
||||
* kind, including, but not limited to, any implied warranties of
|
||||
* merchantability or fitness for any particular purpose or warranties against
|
||||
* infringement of any proprietary rights of a third party.
|
||||
*
|
||||
* Silicon Laboratories, Inc. will not be liable for any consequential,
|
||||
* incidental, or special damages, or any other relief, or for any claim by
|
||||
* any third party, arising from your use of this Software.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "em_device.h"
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** DEFINES ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** LFRCO frequency, tuned to below frequency during manufacturing. */
|
||||
#define EFM32_LFRCO_FREQ (32768UL)
|
||||
/** ULFRCO frequency */
|
||||
#define EFM32_ULFRCO_FREQ (1000UL)
|
||||
|
||||
/*******************************************************************************
|
||||
************************** LOCAL VARIABLES ********************************
|
||||
******************************************************************************/
|
||||
|
||||
/* System oscillator frequencies. These frequencies are normally constant */
|
||||
/* for a target, but they are made configurable in order to allow run-time */
|
||||
/* handling of different boards. The crystal oscillator clocks can be set */
|
||||
/* compile time to a non-default value by defining respective EFM_nFXO_FREQ */
|
||||
/* values according to board design. By defining the EFM_nFXO_FREQ to 0, */
|
||||
/* one indicates that the oscillator is not present, in order to save some */
|
||||
/* SW footprint. */
|
||||
|
||||
#ifndef EFM32_HFRCO_MAX_FREQ
|
||||
/** Maximum HFRCO frequency */
|
||||
#define EFM32_HFRCO_MAX_FREQ (38000000UL)
|
||||
#endif
|
||||
|
||||
#ifndef EFM32_HFXO_FREQ
|
||||
/** HFXO frequency */
|
||||
#define EFM32_HFXO_FREQ (40000000UL)
|
||||
#endif
|
||||
|
||||
#ifndef EFM32_HFRCO_STARTUP_FREQ
|
||||
/** HFRCO startup frequency */
|
||||
#define EFM32_HFRCO_STARTUP_FREQ (19000000UL)
|
||||
#endif
|
||||
|
||||
|
||||
/* Do not define variable if HF crystal oscillator not present */
|
||||
#if (EFM32_HFXO_FREQ > 0UL)
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
/** System HFXO clock. */
|
||||
static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
|
||||
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
|
||||
#endif
|
||||
|
||||
#ifndef EFM32_LFXO_FREQ
|
||||
/** LFXO frequency */
|
||||
#define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
|
||||
#endif
|
||||
/* Do not define variable if LF crystal oscillator not present */
|
||||
#if (EFM32_LFXO_FREQ > 0UL)
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
/** System LFXO clock. */
|
||||
static uint32_t SystemLFXOClock = 32768UL;
|
||||
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL VARIABLES *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* System System Clock Frequency (Core Clock).
|
||||
*
|
||||
* @details
|
||||
* Required CMSIS global variable that must be kept up-to-date.
|
||||
*/
|
||||
uint32_t SystemCoreClock = EFM32_HFRCO_STARTUP_FREQ;
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* System HFRCO frequency
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary variable, not part of the CMSIS definition.
|
||||
*
|
||||
* @details
|
||||
* Frequency of the system HFRCO oscillator
|
||||
*/
|
||||
uint32_t SystemHfrcoFreq = EFM32_HFRCO_STARTUP_FREQ;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the current core clock frequency.
|
||||
*
|
||||
* @details
|
||||
* Calculate and get the current core clock frequency based on the current
|
||||
* configuration. Assuming that the SystemCoreClock global variable is
|
||||
* maintained, the core clock frequency is stored in that variable as well.
|
||||
* This function will however calculate the core clock based on actual HW
|
||||
* configuration. It will also update the SystemCoreClock global variable.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* The current core clock frequency in Hz.
|
||||
******************************************************************************/
|
||||
uint32_t SystemCoreClockGet(void)
|
||||
{
|
||||
uint32_t ret;
|
||||
uint32_t presc;
|
||||
|
||||
ret = SystemHFClockGet();
|
||||
presc = (CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK) >>
|
||||
_CMU_HFCOREPRESC_PRESC_SHIFT;
|
||||
ret /= (presc + 1);
|
||||
|
||||
/* Keep CMSIS system clock variable up-to-date */
|
||||
SystemCoreClock = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the maximum core clock frequency.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* The maximum core clock frequency in Hz.
|
||||
******************************************************************************/
|
||||
uint32_t SystemMaxCoreClockGet(void)
|
||||
{
|
||||
return (EFM32_HFRCO_MAX_FREQ > EFM32_HFXO_FREQ ? \
|
||||
EFM32_HFRCO_MAX_FREQ : EFM32_HFXO_FREQ);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the current HFCLK frequency.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* The current HFCLK frequency in Hz.
|
||||
******************************************************************************/
|
||||
uint32_t SystemHFClockGet(void)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
switch (CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK)
|
||||
{
|
||||
case CMU_HFCLKSTATUS_SELECTED_LFXO:
|
||||
#if (EFM32_LFXO_FREQ > 0)
|
||||
ret = SystemLFXOClock;
|
||||
#else
|
||||
/* We should not get here, since core should not be clocked. May */
|
||||
/* be caused by a misconfiguration though. */
|
||||
ret = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case CMU_HFCLKSTATUS_SELECTED_LFRCO:
|
||||
ret = EFM32_LFRCO_FREQ;
|
||||
break;
|
||||
|
||||
case CMU_HFCLKSTATUS_SELECTED_HFXO:
|
||||
#if (EFM32_HFXO_FREQ > 0)
|
||||
ret = SystemHFXOClock;
|
||||
#else
|
||||
/* We should not get here, since core should not be clocked. May */
|
||||
/* be caused by a misconfiguration though. */
|
||||
ret = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default: /* CMU_HFCLKSTATUS_SELECTED_HFRCO */
|
||||
ret = SystemHfrcoFreq;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret / (1U + ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)
|
||||
>> _CMU_HFPRESC_PRESC_SHIFT));
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Get high frequency crystal oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* HFXO frequency in Hz.
|
||||
*****************************************************************************/
|
||||
uint32_t SystemHFXOClockGet(void)
|
||||
{
|
||||
/* External crystal oscillator present? */
|
||||
#if (EFM32_HFXO_FREQ > 0)
|
||||
return SystemHFXOClock;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Set high frequency crystal oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This function is mainly provided for being able to handle target systems
|
||||
* with different HF crystal oscillator frequencies run-time. If used, it
|
||||
* should probably only be used once during system startup.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @param[in] freq
|
||||
* HFXO frequency in Hz used for target.
|
||||
*****************************************************************************/
|
||||
void SystemHFXOClockSet(uint32_t freq)
|
||||
{
|
||||
/* External crystal oscillator present? */
|
||||
#if (EFM32_HFXO_FREQ > 0)
|
||||
SystemHFXOClock = freq;
|
||||
|
||||
/* Update core clock frequency if HFXO is used to clock core */
|
||||
if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_HFXO)
|
||||
{
|
||||
/* The function will update the global variable */
|
||||
SystemCoreClockGet();
|
||||
}
|
||||
#else
|
||||
(void)freq; /* Unused parameter */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Initialize the system.
|
||||
*
|
||||
* @details
|
||||
* Do required generic HW system init.
|
||||
*
|
||||
* @note
|
||||
* This function is invoked during system init, before the main() routine
|
||||
* and any data has been initialized. For this reason, it cannot do any
|
||||
* initialization of variables etc.
|
||||
*****************************************************************************/
|
||||
void SystemInit(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
/* Set floating point coprosessor access mode. */
|
||||
SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */
|
||||
(3UL << 11*2) ); /* set CP11 Full Access */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Get low frequency RC oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* LFRCO frequency in Hz.
|
||||
*****************************************************************************/
|
||||
uint32_t SystemLFRCOClockGet(void)
|
||||
{
|
||||
/* Currently we assume that this frequency is properly tuned during */
|
||||
/* manufacturing and is not changed after reset. If future requirements */
|
||||
/* for re-tuning by user, we can add support for that. */
|
||||
return EFM32_LFRCO_FREQ;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Get ultra low frequency RC oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* ULFRCO frequency in Hz.
|
||||
*****************************************************************************/
|
||||
uint32_t SystemULFRCOClockGet(void)
|
||||
{
|
||||
/* The ULFRCO frequency is not tuned, and can be very inaccurate */
|
||||
return EFM32_ULFRCO_FREQ;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Get low frequency crystal oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* LFXO frequency in Hz.
|
||||
*****************************************************************************/
|
||||
uint32_t SystemLFXOClockGet(void)
|
||||
{
|
||||
/* External crystal oscillator present? */
|
||||
#if (EFM32_LFXO_FREQ > 0)
|
||||
return SystemLFXOClock;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Set low frequency crystal oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This function is mainly provided for being able to handle target systems
|
||||
* with different HF crystal oscillator frequencies run-time. If used, it
|
||||
* should probably only be used once during system startup.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @param[in] freq
|
||||
* LFXO frequency in Hz used for target.
|
||||
*****************************************************************************/
|
||||
void SystemLFXOClockSet(uint32_t freq)
|
||||
{
|
||||
/* External crystal oscillator present? */
|
||||
#if (EFM32_LFXO_FREQ > 0)
|
||||
SystemLFXOClock = freq;
|
||||
|
||||
/* Update core clock frequency if LFXO is used to clock core */
|
||||
if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_LFXO)
|
||||
{
|
||||
/* The function will update the global variable */
|
||||
SystemCoreClockGet();
|
||||
}
|
||||
#else
|
||||
(void)freq; /* Unused parameter */
|
||||
#endif
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
<?xml version="1.0" encoding="ASCII"?>
|
||||
<device:XMLDevice xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:device="http://www.silabs.com/ss/hwconfig/document/device.ecore" name="EFM32PG1B200F256GM48" partId="mcu.arm.efm32.pg1.efm32pg1b200f256gm48" contextId="%DEFAULT%">
|
||||
<mode name="DefaultMode">
|
||||
<property object="ADC0" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="CMU" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="CMU" propertyId="clocksettings.hfrcosettings.hfrcofrequency" value="38 MHz"/>
|
||||
<property object="CMU" propertyId="clocksettings.lfclocksettings.ulfrcorequired" value="Yes"/>
|
||||
<property object="CRYOTIMER" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="CRYOTIMER" propertyId="cryotimer.clocking.clocksourceforcryotimer" value="ULFRCO"/>
|
||||
<property object="CRYOTIMER" propertyId="cryotimer.clocking.eventafterevery" value="1 cycle"/>
|
||||
<property object="CRYPTO" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="DefaultMode" propertyId="mode.diagramLocation" value="100, 100"/>
|
||||
<property object="EMU" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="GPIO" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="PA0" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PA1" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PA1" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PA1" propertyId="ports.settings.pinmode" value="Input pull"/>
|
||||
<property object="PA1" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PA1" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PA3" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PA4" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PA4" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PA4" propertyId="ports.settings.pinmode" value="Wired-and pullup filter"/>
|
||||
<property object="PA4" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PA4" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PA5" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PA5" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PA5" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PA5" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PA5" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PB13" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PB13" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PB13" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PB13" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PB13" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PC10" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PC10" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PC10" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PC10" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PC10" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PC6" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PC6" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PC6" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PC6" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PC6" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PC7" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PC7" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PC7" propertyId="ports.settings.pinmode" value="Input pull"/>
|
||||
<property object="PC7" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PC7" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PC8" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PC8" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PC8" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PC8" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PC8" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PC9" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PC9" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PC9" propertyId="ports.settings.pinmode" value="Input pull"/>
|
||||
<property object="PC9" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PC9" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PD10" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PD10" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PD10" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PD10" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PD10" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PD15" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PD15" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PD15" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PD15" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PD15" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PF2" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PF2" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PF2" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PF2" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PF2" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PF3" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PF3" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PF3" propertyId="ports.settings.pinmode" value="Wired-and pullup filter"/>
|
||||
<property object="PF3" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PF3" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PF4" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PF5" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PF6" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PF6" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PF6" propertyId="ports.settings.pinmode" value="Input pull"/>
|
||||
<property object="PF6" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PF6" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.i2c0.location.i2c0_sclloc" value="3"/>
|
||||
<property object="PORTIO" propertyId="portio.i2c0.location.i2c0_sdaloc" value="27"/>
|
||||
<property object="PORTIO" propertyId="portio.usart0.enable.cts" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.usart0.enable.rts" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.usart0.enable.rx" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.usart0.enable.tx" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.usart0.location.usart0_ctsloc" value="30"/>
|
||||
<property object="PORTIO" propertyId="portio.usart0.location.usart0_rtsloc" value="30"/>
|
||||
<property object="PORTIO" propertyId="portio.usart1.enable.clk" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.usart1.enable.rx" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.usart1.enable.tx" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.usart1.location.usart1_clkloc" value="11"/>
|
||||
<property object="PORTIO" propertyId="portio.usart1.location.usart1_rxloc" value="11"/>
|
||||
<property object="PORTIO" propertyId="portio.usart1.location.usart1_txloc" value="11"/>
|
||||
<property object="TIMER0" propertyId="timer.clocksettings.clockselection" value="TIM0_CC1 input"/>
|
||||
<property object="USART0" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="USART0" propertyId="usart.outputsettings.clockselect" value="Disabled"/>
|
||||
<property object="USART1" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="USART1" propertyId="usart.mode.usartmode" value="Synchronous Mode (SPI / I2S)"/>
|
||||
<property object="USART1" propertyId="usart.outputsettings.clockselect" value="Disabled"/>
|
||||
<property object="USART1" propertyId="usart.synchronoussettings.baudrate" value="130000"/>
|
||||
<property object="USART1" propertyId="usart.synchronoussettings.clockpolarityphasemode" value="Clock idle low, sample on falling edge"/>
|
||||
</mode>
|
||||
<modeTransition>
|
||||
<property object="RESET → DefaultMode" propertyId="modeTransition.source" value="RESET"/>
|
||||
<property object="RESET → DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
|
||||
</modeTransition>
|
||||
</device:XMLDevice>
|
@ -1,107 +0,0 @@
|
||||
<?xml version="1.0" encoding="ASCII"?>
|
||||
<device:XMLDevice xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:device="http://www.silabs.com/ss/hwconfig/document/device.ecore" name="EFM32JG1B200F128GM32" partId="mcu.arm.efm32.jg1.efm32jg1b200f128gm32" contextId="%DEFAULT%">
|
||||
<mode name="DefaultMode">
|
||||
<property object="ADC0" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="CMU" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="CMU" propertyId="clocksettings.hfrcosettings.hfrcofrequency" value="38 MHz"/>
|
||||
<property object="CMU" propertyId="clocksettings.lfclocksettings.ulfrcorequired" value="Yes"/>
|
||||
<property object="CRYOTIMER" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="CRYOTIMER" propertyId="cryotimer.clocking.clocksourceforcryotimer" value="ULFRCO"/>
|
||||
<property object="CRYOTIMER" propertyId="cryotimer.clocking.eventafterevery" value="1 cycle"/>
|
||||
<property object="CRYPTO" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="DefaultMode" propertyId="mode.diagramLocation" value="100, 100"/>
|
||||
<property object="EMU" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="EMU" propertyId="emu.powerconfiguration.externalpowercircuitwiring" value="Not wired for DCDC"/>
|
||||
<property object="GPIO" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="PA0" propertyId="ports.settings.pinmode" value="Input"/>
|
||||
<property object="PA1" propertyId="ports.settings.pinmode" value="Input"/>
|
||||
<property object="PB11" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PB11" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PB11" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PB11" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PB11" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PB12" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PB12" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PB12" propertyId="ports.settings.pinmode" value="Input pull"/>
|
||||
<property object="PB12" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PB12" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PB13" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PB13" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PB13" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PB13" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PB13" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PB15" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PB15" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PB15" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PB15" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PB15" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PD10" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PD10" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PD10" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PD10" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PD10" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PD11" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PD11" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PD11" propertyId="ports.settings.pinmode" value="Input pull"/>
|
||||
<property object="PD11" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PD11" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PD12" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PD12" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PD12" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PD12" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PD12" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PD13" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PD13" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PD13" propertyId="ports.settings.pinmode" value="Input pull"/>
|
||||
<property object="PD13" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PD13" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PD14" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PD14" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PD14" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PD14" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PD14" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PD15" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PD15" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PD15" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PD15" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PD15" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PD9" propertyId="ports.settings.dout" value="1"/>
|
||||
<property object="PD9" propertyId="ports.settings.filter" value="Enabled"/>
|
||||
<property object="PD9" propertyId="ports.settings.pinmode" value="Push-pull"/>
|
||||
<property object="PD9" propertyId="ports.settings.pulldirection" value="Pullup"/>
|
||||
<property object="PD9" propertyId="ports.settings.pullup" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.timer0.enable.cc0" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.timer0.enable.cc1" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.timer0.enable.cc2" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.timer0.location.timer0_cc0loc" value="18"/>
|
||||
<property object="PORTIO" propertyId="portio.timer0.location.timer0_cc1loc" value="16"/>
|
||||
<property object="PORTIO" propertyId="portio.timer0.location.timer0_cc2loc" value="20"/>
|
||||
<property object="PORTIO" propertyId="portio.usart0.enable.rx" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.usart0.enable.tx" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.usart0.location.usart0_txloc" value="20"/>
|
||||
<property object="PORTIO" propertyId="portio.usart1.enable.clk" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.usart1.enable.rx" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.usart1.enable.tx" value="Enabled"/>
|
||||
<property object="PORTIO" propertyId="portio.usart1.location.usart1_rxloc" value="6"/>
|
||||
<property object="PORTIO" propertyId="portio.usart1.location.usart1_txloc" value="8"/>
|
||||
<property object="TIMER0" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="TIMER0" propertyId="timer.capturecomparech0.ccmode" value="PWM"/>
|
||||
<property object="TIMER0" propertyId="timer.capturecomparech0.countermatchoutputaction" value="Toggle on event"/>
|
||||
<property object="TIMER0" propertyId="timer.capturecomparech1.ccmode" value="PWM"/>
|
||||
<property object="TIMER0" propertyId="timer.capturecomparech1.countermatchoutputaction" value="Toggle on event"/>
|
||||
<property object="TIMER0" propertyId="timer.capturecomparech2.ccmode" value="PWM"/>
|
||||
<property object="TIMER0" propertyId="timer.capturecomparech2.countermatchoutputaction" value="Toggle on event"/>
|
||||
<property object="TIMER0" propertyId="timer.clocksettings.hfperprescaler" value="Divide by 512"/>
|
||||
<property object="USART0" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="USART0" propertyId="usart.outputsettings.clockselect" value="Disabled"/>
|
||||
<property object="USART1" propertyId="ABPeripheral.included" value="true"/>
|
||||
<property object="USART1" propertyId="usart.asynchronoussettings.baudrate" value="130000"/>
|
||||
<property object="USART1" propertyId="usart.mode.usartmode" value="Synchronous Mode (SPI / I2S)"/>
|
||||
<property object="USART1" propertyId="usart.outputsettings.clockselect" value="Disabled"/>
|
||||
<property object="USART1" propertyId="usart.synchronoussettings.baudrate" value="130000"/>
|
||||
</mode>
|
||||
<modeTransition>
|
||||
<property object="RESET → DefaultMode" propertyId="modeTransition.source" value="RESET"/>
|
||||
<property object="RESET → DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
|
||||
</modeTransition>
|
||||
</device:XMLDevice>
|
@ -1,23 +0,0 @@
|
||||
|
||||
CC=arm-none-eabi-gcc
|
||||
|
||||
all:
|
||||
cd 'GNU ARM v7.2.1 - Debug' && make all
|
||||
|
||||
|
||||
#arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m4 -mthumb -std=c99 '-DDEBUG=1' '-DEFM32PG1B200F256GM48=1' -IC:/Users/conor/Desktop/u2f-one/crypto/sha256 -IC:/Users/conor/Desktop/u2f-one/crypto/micro-ecc -IC:/Users/conor/Desktop/u2f-one/crypto/tiny-AES-c -I"C:\Users\conor\Desktop\u2f-one\efm32\inc" -IC:/Users/conor/Desktop/u2f-one/fido2 -IC:/Users/conor/Desktop/u2f-one/tinycbor/src -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//platform/CMSIS/Include" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//hardware/kit/common/drivers" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//hardware/kit/SLSTK3401A_EFM32PG/config" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//platform/Device/SiliconLabs/EFM32PG1B/Include" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//platform/emlib/inc" -I"C:/SiliconLabs/SimplicityStudio/v4/developer/sdks/gecko_sdk_suite/v1.1//hardware/kit/common/bsp" -O0 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -MMD -MP -MF"src/device.d" -MT"src/device.o" -o "src/device.o" "../src/device.c"
|
||||
|
||||
|
||||
#arm-none-eabi-gcc -g -gdwarf-2 -mcpu=cortex-m4 -mthumb -T "EFM32.ld" -Xlinker --gc-sections -Xlinker -Map="EFM32.map" -mfpu=fpv4-sp-d16 -mfloat-abi=softfp --specs=nano.specs -o EFM32.axf "./CMSIS/EFM32PG1B/startup_gcc_efm32pg1b.o" "./CMSIS/EFM32PG1B/system_efm32pg1b.o" "./crypto/micro-ecc/uECC.o" "./crypto/sha256/sha256.o" "./crypto/tiny-AES-c/aes.o" "./emlib/em_assert.o" "./emlib/em_cmu.o" "./emlib/em_emu.o" "./emlib/em_gpio.o" "./emlib/em_system.o" "./emlib/em_usart.o" "./fido2/crypto.o" "./fido2/ctap.o" "./fido2/ctap_parse.o" "./fido2/ctaphid.o" "./fido2/log.o" "./fido2/main.o" "./fido2/stubs.o" "./fido2/test_power.o" "./fido2/u2f.o" "./fido2/util.o" "./src/InitDevice.o" "./src/device.o" "./src/main.o" "./src/printing.o" "./src/retargetio.o" -Wl,--start-group -lgcc -lc -lnosys -Wl,--end-group
|
||||
|
||||
|
||||
cbor:
|
||||
cd ../tinycbor/ && make clean
|
||||
cd ../tinycbor/ && make CC="$(CC)" \
|
||||
LDFLAGS="-lgcc -lc -lnosys --specs=nosys.specs -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -mthumb " \
|
||||
CFLAGS="-g -gdwarf-2 -mcpu=cortex-m4 -mthumb -std=c99 -DEFM32PG1B200F256GM48=1 -O3 -Wall -c -fmessage-length=0 -mno-sched-prolog -fno-builtin -ffunction-sections -fdata-sections -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -MMD -MP "
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
cd 'GNU ARM v7.2.1 - Debug' && make clean
|
File diff suppressed because it is too large
Load Diff
@ -1,81 +0,0 @@
|
||||
/***************************************************************************//**
|
||||
* @file em_assert.c
|
||||
* @brief Assert API
|
||||
* @version 5.2.2
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
|
||||
* obligation to support this Software. Silicon Labs is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Silicon Labs will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "em_assert.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup emlib
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup ASSERT
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(DEBUG_EFM)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* EFM internal assert handling.
|
||||
*
|
||||
* This function is invoked through EFM_ASSERT() macro usage only, it should
|
||||
* not be used explicitly.
|
||||
*
|
||||
* This implementation simply enters an indefinite loop, allowing
|
||||
* the use of a debugger to determine cause of failure. By defining
|
||||
* DEBUG_EFM_USER to the preprocessor for all files, a user defined version
|
||||
* of this function must be defined and will be invoked instead, possibly
|
||||
* providing output of assertion location.
|
||||
*
|
||||
* @note
|
||||
* This function is not used unless @ref DEBUG_EFM is defined
|
||||
* during preprocessing of EFM_ASSERT() usage.
|
||||
*
|
||||
* @param[in] file
|
||||
* Name of source file where assertion failed.
|
||||
*
|
||||
* @param[in] line
|
||||
* Line number in source file where assertion failed.
|
||||
******************************************************************************/
|
||||
void assertEFM(const char *file, int line)
|
||||
{
|
||||
(void)file; /* Unused parameter */
|
||||
(void)line; /* Unused parameter */
|
||||
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG_EFM */
|
||||
|
||||
/** @} (end addtogroup ASSERT) */
|
||||
/** @} (end addtogroup emlib) */
|
File diff suppressed because it is too large
Load Diff
@ -1,61 +0,0 @@
|
||||
/***************************************************************************//**
|
||||
* @file em_cryotimer.c
|
||||
* @brief Ultra Low Energy Timer/Counter (CRYOTIMER) peripheral API
|
||||
* @version 5.2.2
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software.@n
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.@n
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
|
||||
* obligation to support this Software. Silicon Labs is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Silicon Labs will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "em_cryotimer.h"
|
||||
#include "em_bus.h"
|
||||
|
||||
#if defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT == 1)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize the CRYOTIMER.
|
||||
*
|
||||
* @details
|
||||
* Use this function to initialize the CRYOTIMER.
|
||||
* Select prescaler setting and select low frequency oscillator.
|
||||
* Refer to the configuration structure @ref CRYOTIMER_Init_TypeDef for more
|
||||
* details.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to initialization structure.
|
||||
******************************************************************************/
|
||||
void CRYOTIMER_Init(const CRYOTIMER_Init_TypeDef *init)
|
||||
{
|
||||
CRYOTIMER->PERIODSEL = (uint32_t)init->period & _CRYOTIMER_PERIODSEL_MASK;
|
||||
CRYOTIMER->CTRL = ((uint32_t)init->enable << _CRYOTIMER_CTRL_EN_SHIFT)
|
||||
| ((uint32_t)init->debugRun << _CRYOTIMER_CTRL_DEBUGRUN_SHIFT)
|
||||
| ((uint32_t)init->osc << _CRYOTIMER_CTRL_OSCSEL_SHIFT)
|
||||
| ((uint32_t)init->presc << _CRYOTIMER_CTRL_PRESC_SHIFT);
|
||||
CRYOTIMER_EM4WakeupEnable(init->em4Wakeup);
|
||||
}
|
||||
|
||||
#endif /* defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT > 0) */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,367 +0,0 @@
|
||||
/***************************************************************************//**
|
||||
* @file em_gpio.c
|
||||
* @brief General Purpose IO (GPIO) peripheral API
|
||||
* devices.
|
||||
* @version 5.2.2
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
|
||||
* obligation to support this Software. Silicon Labs is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Silicon Labs will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "em_gpio.h"
|
||||
|
||||
#if defined(GPIO_COUNT) && (GPIO_COUNT > 0)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup emlib
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup GPIO
|
||||
* @brief General Purpose Input/Output (GPIO) API
|
||||
* @details
|
||||
* This module contains functions to control the GPIO peripheral of Silicon
|
||||
* Labs 32-bit MCUs and SoCs. The GPIO peripheral is used for pin configuration
|
||||
* and direct pin manipulation and sensing as well as routing for peripheral
|
||||
* pin connections.
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Validation of pin typically usable in assert statements. */
|
||||
#define GPIO_DRIVEMODE_VALID(mode) ((mode) <= 3)
|
||||
#define GPIO_STRENGHT_VALID(strenght) (!((strenght) \
|
||||
& ~(_GPIO_P_CTRL_DRIVESTRENGTH_MASK \
|
||||
| _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK)))
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Sets the pin location of the debug pins (Serial Wire interface).
|
||||
*
|
||||
* @note
|
||||
* Changing the pins used for debugging uncontrolled, may result in a lockout.
|
||||
*
|
||||
* @param[in] location
|
||||
* The debug pin location to use (0-3).
|
||||
******************************************************************************/
|
||||
void GPIO_DbgLocationSet(unsigned int location)
|
||||
{
|
||||
#if defined (_GPIO_ROUTE_SWLOCATION_MASK)
|
||||
EFM_ASSERT(location < AFCHANLOC_MAX);
|
||||
|
||||
GPIO->ROUTE = (GPIO->ROUTE & ~_GPIO_ROUTE_SWLOCATION_MASK)
|
||||
| (location << _GPIO_ROUTE_SWLOCATION_SHIFT);
|
||||
#else
|
||||
(void)location;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined (_GPIO_P_CTRL_DRIVEMODE_MASK)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Sets the drive mode for a GPIO port.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] mode
|
||||
* Drive mode to use for port.
|
||||
******************************************************************************/
|
||||
void GPIO_DriveModeSet(GPIO_Port_TypeDef port, GPIO_DriveMode_TypeDef mode)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_DRIVEMODE_VALID(mode));
|
||||
|
||||
GPIO->P[port].CTRL = (GPIO->P[port].CTRL & ~(_GPIO_P_CTRL_DRIVEMODE_MASK))
|
||||
| (mode << _GPIO_P_CTRL_DRIVEMODE_SHIFT);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (_GPIO_P_CTRL_DRIVESTRENGTH_MASK)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Sets the drive strength for a GPIO port.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] strength
|
||||
* Drive strength to use for port.
|
||||
******************************************************************************/
|
||||
void GPIO_DriveStrengthSet(GPIO_Port_TypeDef port,
|
||||
GPIO_DriveStrength_TypeDef strength)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_VALID(port) && GPIO_STRENGHT_VALID(strength));
|
||||
BUS_RegMaskedWrite(&GPIO->P[port].CTRL,
|
||||
_GPIO_P_CTRL_DRIVESTRENGTH_MASK | _GPIO_P_CTRL_DRIVESTRENGTHALT_MASK,
|
||||
strength);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Configure GPIO external pin interrupt.
|
||||
*
|
||||
* @details
|
||||
* If reconfiguring a GPIO interrupt that is already enabled, it is generally
|
||||
* recommended to disable it first, see GPIO_Disable().
|
||||
*
|
||||
* The actual GPIO interrupt handler must be in place before enabling the
|
||||
* interrupt.
|
||||
*
|
||||
* Notice that any pending interrupt for the selected interrupt is cleared
|
||||
* by this function.
|
||||
*
|
||||
* @note
|
||||
* On series 0 devices the pin number parameter is not used. The
|
||||
* pin number used on these devices is hardwired to the interrupt with the
|
||||
* same number. @n
|
||||
* On series 1 devices, pin number can be selected freely within a group.
|
||||
* Interrupt numbers are divided into 4 groups (intNo / 4) and valid pin
|
||||
* number within the interrupt groups are:
|
||||
* 0: pins 0-3
|
||||
* 1: pins 4-7
|
||||
* 2: pins 8-11
|
||||
* 3: pins 12-15
|
||||
*
|
||||
* @param[in] port
|
||||
* The port to associate with @p pin.
|
||||
*
|
||||
* @param[in] pin
|
||||
* The pin number on the port.
|
||||
*
|
||||
* @param[in] intNo
|
||||
* The interrupt number to trigger.
|
||||
*
|
||||
* @param[in] risingEdge
|
||||
* Set to true if interrupts shall be enabled on rising edge, otherwise false.
|
||||
*
|
||||
* @param[in] fallingEdge
|
||||
* Set to true if interrupts shall be enabled on falling edge, otherwise false.
|
||||
*
|
||||
* @param[in] enable
|
||||
* Set to true if interrupt shall be enabled after configuration completed,
|
||||
* false to leave disabled. See GPIO_IntDisable() and GPIO_IntEnable().
|
||||
******************************************************************************/
|
||||
void GPIO_ExtIntConfig(GPIO_Port_TypeDef port,
|
||||
unsigned int pin,
|
||||
unsigned int intNo,
|
||||
bool risingEdge,
|
||||
bool fallingEdge,
|
||||
bool enable)
|
||||
{
|
||||
uint32_t tmp = 0;
|
||||
#if !defined(_GPIO_EXTIPINSELL_MASK)
|
||||
(void)pin;
|
||||
#endif
|
||||
|
||||
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
|
||||
#if defined(_GPIO_EXTIPINSELL_MASK)
|
||||
EFM_ASSERT(GPIO_INTNO_PIN_VALID(intNo, pin));
|
||||
#endif
|
||||
|
||||
/* There are two registers controlling the interrupt configuration:
|
||||
* The EXTIPSELL register controls pins 0-7 and EXTIPSELH controls
|
||||
* pins 8-15. */
|
||||
if (intNo < 8) {
|
||||
BUS_RegMaskedWrite(&GPIO->EXTIPSELL,
|
||||
_GPIO_EXTIPSELL_EXTIPSEL0_MASK
|
||||
<< (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * intNo),
|
||||
port << (_GPIO_EXTIPSELL_EXTIPSEL1_SHIFT * intNo));
|
||||
} else {
|
||||
tmp = intNo - 8;
|
||||
BUS_RegMaskedWrite(&GPIO->EXTIPSELH,
|
||||
_GPIO_EXTIPSELH_EXTIPSEL8_MASK
|
||||
<< (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp),
|
||||
port << (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp));
|
||||
}
|
||||
|
||||
#if defined(_GPIO_EXTIPINSELL_MASK)
|
||||
/* There are two registers controlling the interrupt/pin number mapping:
|
||||
* The EXTIPINSELL register controls interrupt 0-7 and EXTIPINSELH controls
|
||||
* interrupt 8-15. */
|
||||
if (intNo < 8) {
|
||||
BUS_RegMaskedWrite(&GPIO->EXTIPINSELL,
|
||||
_GPIO_EXTIPINSELL_EXTIPINSEL0_MASK
|
||||
<< (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * intNo),
|
||||
((pin % 4) & _GPIO_EXTIPINSELL_EXTIPINSEL0_MASK)
|
||||
<< (_GPIO_EXTIPINSELL_EXTIPINSEL1_SHIFT * intNo));
|
||||
} else {
|
||||
BUS_RegMaskedWrite(&GPIO->EXTIPINSELH,
|
||||
_GPIO_EXTIPINSELH_EXTIPINSEL8_MASK
|
||||
<< (_GPIO_EXTIPINSELH_EXTIPINSEL9_SHIFT * tmp),
|
||||
((pin % 4) & _GPIO_EXTIPINSELH_EXTIPINSEL8_MASK)
|
||||
<< (_GPIO_EXTIPSELH_EXTIPSEL9_SHIFT * tmp));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Enable/disable rising edge */
|
||||
BUS_RegBitWrite(&(GPIO->EXTIRISE), intNo, risingEdge);
|
||||
|
||||
/* Enable/disable falling edge */
|
||||
BUS_RegBitWrite(&(GPIO->EXTIFALL), intNo, fallingEdge);
|
||||
|
||||
/* Clear any pending interrupt */
|
||||
GPIO->IFC = 1 << intNo;
|
||||
|
||||
/* Finally enable/disable interrupt */
|
||||
BUS_RegBitWrite(&(GPIO->IEN), intNo, enable);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set the mode for a GPIO pin.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] pin
|
||||
* The pin number in the port.
|
||||
*
|
||||
* @param[in] mode
|
||||
* The desired pin mode.
|
||||
*
|
||||
* @param[in] out
|
||||
* Value to set for pin in DOUT register. The DOUT setting is important for
|
||||
* even some input mode configurations, determining pull-up/down direction.
|
||||
******************************************************************************/
|
||||
void GPIO_PinModeSet(GPIO_Port_TypeDef port,
|
||||
unsigned int pin,
|
||||
GPIO_Mode_TypeDef mode,
|
||||
unsigned int out)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
|
||||
|
||||
/* If disabling pin, do not modify DOUT in order to reduce chance for */
|
||||
/* glitch/spike (may not be sufficient precaution in all use cases) */
|
||||
if (mode != gpioModeDisabled) {
|
||||
if (out) {
|
||||
GPIO_PinOutSet(port, pin);
|
||||
} else {
|
||||
GPIO_PinOutClear(port, pin);
|
||||
}
|
||||
}
|
||||
|
||||
/* There are two registers controlling the pins for each port. The MODEL
|
||||
* register controls pins 0-7 and MODEH controls pins 8-15. */
|
||||
if (pin < 8) {
|
||||
GPIO->P[port].MODEL = (GPIO->P[port].MODEL & ~(0xFu << (pin * 4)))
|
||||
| (mode << (pin * 4));
|
||||
} else {
|
||||
GPIO->P[port].MODEH = (GPIO->P[port].MODEH & ~(0xFu << ((pin - 8) * 4)))
|
||||
| (mode << ((pin - 8) * 4));
|
||||
}
|
||||
|
||||
if (mode == gpioModeDisabled) {
|
||||
if (out) {
|
||||
GPIO_PinOutSet(port, pin);
|
||||
} else {
|
||||
GPIO_PinOutClear(port, pin);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the mode for a GPIO pin.
|
||||
*
|
||||
* @param[in] port
|
||||
* The GPIO port to access.
|
||||
*
|
||||
* @param[in] pin
|
||||
* The pin number in the port.
|
||||
*
|
||||
* @return
|
||||
* The pin mode.
|
||||
******************************************************************************/
|
||||
GPIO_Mode_TypeDef GPIO_PinModeGet(GPIO_Port_TypeDef port,
|
||||
unsigned int pin)
|
||||
{
|
||||
EFM_ASSERT(GPIO_PORT_PIN_VALID(port, pin));
|
||||
|
||||
if (pin < 8) {
|
||||
return (GPIO_Mode_TypeDef) ((GPIO->P[port].MODEL >> (pin * 4)) & 0xF);
|
||||
} else {
|
||||
return (GPIO_Mode_TypeDef) ((GPIO->P[port].MODEH >> ((pin - 8) * 4)) & 0xF);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(_GPIO_EM4WUEN_MASK)
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Enable GPIO pin wake-up from EM4. When the function exits,
|
||||
* EM4 mode can be safely entered.
|
||||
*
|
||||
* @note
|
||||
* It is assumed that the GPIO pin modes are set correctly.
|
||||
* Valid modes are @ref gpioModeInput and @ref gpioModeInputPull.
|
||||
*
|
||||
* @param[in] pinmask
|
||||
* Bitmask containing the bitwise logic OR of which GPIO pin(s) to enable.
|
||||
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
|
||||
* @param[in] polaritymask
|
||||
* Bitmask containing the bitwise logic OR of GPIO pin(s) wake-up polarity.
|
||||
* Refer to Reference Manuals for pinmask to GPIO port/pin mapping.
|
||||
*****************************************************************************/
|
||||
void GPIO_EM4EnablePinWakeup(uint32_t pinmask, uint32_t polaritymask)
|
||||
{
|
||||
EFM_ASSERT((pinmask & ~_GPIO_EM4WUEN_MASK) == 0);
|
||||
|
||||
#if defined(_GPIO_EM4WUPOL_MASK)
|
||||
EFM_ASSERT((polaritymask & ~_GPIO_EM4WUPOL_MASK) == 0);
|
||||
GPIO->EM4WUPOL &= ~pinmask; /* Set wakeup polarity */
|
||||
GPIO->EM4WUPOL |= pinmask & polaritymask;
|
||||
#elif defined(_GPIO_EXTILEVEL_MASK)
|
||||
EFM_ASSERT((polaritymask & ~_GPIO_EXTILEVEL_MASK) == 0);
|
||||
GPIO->EXTILEVEL &= ~pinmask;
|
||||
GPIO->EXTILEVEL |= pinmask & polaritymask;
|
||||
#endif
|
||||
GPIO->EM4WUEN |= pinmask; /* Enable wakeup */
|
||||
|
||||
GPIO_EM4SetPinRetention(true); /* Enable pin retention */
|
||||
|
||||
#if defined(_GPIO_CMD_EM4WUCLR_MASK)
|
||||
GPIO->CMD = GPIO_CMD_EM4WUCLR; /* Clear wake-up logic */
|
||||
#elif defined(_GPIO_IFC_EM4WU_MASK)
|
||||
GPIO_IntClear(pinmask);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} (end addtogroup GPIO) */
|
||||
/** @} (end addtogroup emlib) */
|
||||
|
||||
#endif /* defined(GPIO_COUNT) && (GPIO_COUNT > 0) */
|
@ -1,811 +0,0 @@
|
||||
/***************************************************************************//**
|
||||
* @file em_i2c.c
|
||||
* @brief Inter-integrated Circuit (I2C) Peripheral API
|
||||
* @version 5.2.2
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
|
||||
* obligation to support this Software. Silicon Labs is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Silicon Labs will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "em_i2c.h"
|
||||
#if defined(I2C_COUNT) && (I2C_COUNT > 0)
|
||||
|
||||
#include "em_cmu.h"
|
||||
#include "em_bus.h"
|
||||
#include "em_assert.h"
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup emlib
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup I2C
|
||||
* @brief Inter-integrated Circuit (I2C) Peripheral API
|
||||
* @details
|
||||
* This module contains functions to control the I2C peripheral of Silicon
|
||||
* Labs 32-bit MCUs and SoCs. The I2C interface allows communication on I2C
|
||||
* buses with the lowest energy consumption possible.
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* DEFINES ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Validation of I2C register block pointer reference for assert statements. */
|
||||
#if (I2C_COUNT == 1)
|
||||
#define I2C_REF_VALID(ref) ((ref) == I2C0)
|
||||
#elif (I2C_COUNT == 2)
|
||||
#define I2C_REF_VALID(ref) ((ref == I2C0) || (ref == I2C1))
|
||||
#elif (I2C_COUNT == 3)
|
||||
#define I2C_REF_VALID(ref) ((ref == I2C0) || (ref == I2C1) || (ref == I2C2))
|
||||
#endif
|
||||
|
||||
/** Error flags indicating I2C transfer has failed somehow. */
|
||||
/* Notice that I2C_IF_TXOF (transmit overflow) is not really possible with */
|
||||
/* this SW supporting master mode. Likewise for I2C_IF_RXUF (receive underflow) */
|
||||
/* RXUF is only likely to occur with this SW if using a debugger peeking into */
|
||||
/* RXDATA register. Thus, we ignore those types of fault. */
|
||||
#define I2C_IF_ERRORS (I2C_IF_BUSERR | I2C_IF_ARBLOST)
|
||||
|
||||
/* Max I2C transmission rate constant */
|
||||
#if defined(_SILICON_LABS_32B_SERIES_0)
|
||||
#define I2C_CR_MAX 4
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_1)
|
||||
#define I2C_CR_MAX 8
|
||||
#else
|
||||
#warning "Max I2C transmission rate constant is not defined"
|
||||
#endif
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** ENUMS ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Master mode transfer states. */
|
||||
typedef enum {
|
||||
i2cStateStartAddrSend, /**< Send start + (first part of) address. */
|
||||
i2cStateAddrWFAckNack, /**< Wait for ACK/NACK on (first part of) address. */
|
||||
i2cStateAddrWF2ndAckNack, /**< Wait for ACK/NACK on second part of 10 bit address. */
|
||||
i2cStateRStartAddrSend, /**< Send repeated start + (first part of) address. */
|
||||
i2cStateRAddrWFAckNack, /**< Wait for ACK/NACK on address sent after repeated start. */
|
||||
i2cStateDataSend, /**< Send data. */
|
||||
i2cStateDataWFAckNack, /**< Wait for ACK/NACK on data sent. */
|
||||
i2cStateWFData, /**< Wait for data. */
|
||||
i2cStateWFStopSent, /**< Wait for STOP to have been transmitted. */
|
||||
i2cStateDone /**< Transfer completed successfully. */
|
||||
} I2C_TransferState_TypeDef;
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/** Structure used to store state information on an ongoing master mode transfer. */
|
||||
typedef struct {
|
||||
/** Current state. */
|
||||
I2C_TransferState_TypeDef state;
|
||||
|
||||
/** Result return code. */
|
||||
I2C_TransferReturn_TypeDef result;
|
||||
|
||||
/** Offset in current sequence buffer. */
|
||||
uint16_t offset;
|
||||
|
||||
/* Index to current sequence buffer in use. */
|
||||
uint8_t bufIndx;
|
||||
|
||||
/** Reference to I2C transfer sequence definition provided by user. */
|
||||
I2C_TransferSeq_TypeDef *seq;
|
||||
} I2C_Transfer_TypeDef;
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** LOCAL DATA *******^**************************
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/**
|
||||
* Lookup table for Nlow + Nhigh setting defined by CLHR. Set undefined
|
||||
* index (0x3) to reflect default setting just in case.
|
||||
*/
|
||||
static const uint8_t i2cNSum[] = { 4 + 4, 6 + 3, 11 + 6, 4 + 4 };
|
||||
|
||||
/** Transfer state info for ongoing master mode transfer */
|
||||
static I2C_Transfer_TypeDef i2cTransfer[I2C_COUNT];
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get current configured I2C bus frequency.
|
||||
*
|
||||
* @details
|
||||
* This frequency is only of relevance when acting as master.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Current I2C frequency in Hz.
|
||||
******************************************************************************/
|
||||
uint32_t I2C_BusFreqGet(I2C_TypeDef *i2c)
|
||||
{
|
||||
uint32_t freqHfper;
|
||||
uint32_t n;
|
||||
|
||||
/* Max frequency is given by freqScl = freqHfper/((Nlow + Nhigh)(DIV + 1) + I2C_CR_MAX)
|
||||
* More details can be found in the reference manual,
|
||||
* I2C Clock Generation chapter. */
|
||||
freqHfper = CMU_ClockFreqGet(cmuClock_HFPER);
|
||||
/* n = Nlow + Nhigh */
|
||||
n = (uint32_t)(i2cNSum[(i2c->CTRL & _I2C_CTRL_CLHR_MASK) >> _I2C_CTRL_CLHR_SHIFT]);
|
||||
|
||||
return (freqHfper / ((n * (i2c->CLKDIV + 1)) + I2C_CR_MAX));
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Set I2C bus frequency.
|
||||
*
|
||||
* @details
|
||||
* The bus frequency is only of relevance when acting as a master. The bus
|
||||
* frequency should not be set higher than the max frequency accepted by the
|
||||
* slowest device on the bus.
|
||||
*
|
||||
* Notice that due to asymmetric requirements on low and high I2C clock
|
||||
* cycles by the I2C specification, the actual max frequency allowed in order
|
||||
* to comply with the specification may be somewhat lower than expected.
|
||||
*
|
||||
* Please refer to the reference manual, details on I2C clock generation,
|
||||
* for max allowed theoretical frequencies for different modes.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] freqRef
|
||||
* I2C reference clock frequency in Hz that will be used. If set to 0,
|
||||
* then HFPER clock is used. Setting it to a higher than actual configured
|
||||
* value only has the consequence of reducing the real I2C frequency.
|
||||
*
|
||||
* @param[in] freqScl
|
||||
* Bus frequency to set (actual bus speed may be lower due to integer
|
||||
* prescaling). Safe (according to I2C specification) max frequencies for
|
||||
* standard, fast and fast+ modes are available using I2C_FREQ_ defines.
|
||||
* (Using I2C_FREQ_ defines requires corresponding setting of @p type.)
|
||||
* Slowest slave device on bus must always be considered.
|
||||
*
|
||||
* @param[in] i2cMode
|
||||
* Clock low to high ratio type to use. If not using i2cClockHLRStandard,
|
||||
* make sure all devices on the bus support the specified mode. Using a
|
||||
* non-standard ratio is useful to achieve higher bus clock in fast and
|
||||
* fast+ modes.
|
||||
******************************************************************************/
|
||||
void I2C_BusFreqSet(I2C_TypeDef *i2c,
|
||||
uint32_t freqRef,
|
||||
uint32_t freqScl,
|
||||
I2C_ClockHLR_TypeDef i2cMode)
|
||||
{
|
||||
uint32_t n, minFreq;
|
||||
int32_t div;
|
||||
|
||||
/* Avoid divide by 0 */
|
||||
EFM_ASSERT(freqScl);
|
||||
if (!freqScl) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set the CLHR (clock low to high ratio). */
|
||||
i2c->CTRL &= ~_I2C_CTRL_CLHR_MASK;
|
||||
BUS_RegMaskedWrite(&i2c->CTRL,
|
||||
_I2C_CTRL_CLHR_MASK,
|
||||
i2cMode << _I2C_CTRL_CLHR_SHIFT);
|
||||
|
||||
if (!freqRef) {
|
||||
freqRef = CMU_ClockFreqGet(cmuClock_HFPER);
|
||||
}
|
||||
|
||||
/* Check minumum HF peripheral clock */
|
||||
minFreq = UINT_MAX;
|
||||
if (i2c->CTRL & I2C_CTRL_SLAVE) {
|
||||
switch (i2cMode) {
|
||||
case i2cClockHLRStandard:
|
||||
#if defined(_SILICON_LABS_32B_SERIES_0)
|
||||
minFreq = 4200000; break;
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_1)
|
||||
minFreq = 2000000; break;
|
||||
#endif
|
||||
case i2cClockHLRAsymetric:
|
||||
#if defined(_SILICON_LABS_32B_SERIES_0)
|
||||
minFreq = 11000000; break;
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_1)
|
||||
minFreq = 5000000; break;
|
||||
#endif
|
||||
case i2cClockHLRFast:
|
||||
#if defined(_SILICON_LABS_32B_SERIES_0)
|
||||
minFreq = 24400000; break;
|
||||
#elif defined(_SILICON_LABS_32B_SERIES_1)
|
||||
minFreq = 14000000; break;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
/* For master mode, platform 1 and 2 share the same
|
||||
min frequencies */
|
||||
switch (i2cMode) {
|
||||
case i2cClockHLRStandard:
|
||||
minFreq = 2000000; break;
|
||||
case i2cClockHLRAsymetric:
|
||||
minFreq = 9000000; break;
|
||||
case i2cClockHLRFast:
|
||||
minFreq = 20000000; break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Frequency most be larger-than */
|
||||
EFM_ASSERT(freqRef > minFreq);
|
||||
|
||||
/* SCL frequency is given by
|
||||
* freqScl = freqRef/((Nlow + Nhigh) * (DIV + 1) + I2C_CR_MAX)
|
||||
*
|
||||
* Thus
|
||||
* DIV = ((freqRef - (I2C_CR_MAX * freqScl))/((Nlow + Nhigh) * freqScl)) - 1
|
||||
*
|
||||
* More details can be found in the reference manual,
|
||||
* I2C Clock Generation chapter. */
|
||||
|
||||
/* n = Nlow + Nhigh */
|
||||
n = (uint32_t)(i2cNSum[i2cMode]);
|
||||
div = ((freqRef - (I2C_CR_MAX * freqScl)) / (n * freqScl)) - 1;
|
||||
EFM_ASSERT(div >= 0);
|
||||
EFM_ASSERT((uint32_t)div <= _I2C_CLKDIV_DIV_MASK);
|
||||
|
||||
/* Clock divisor must be at least 1 in slave mode according to reference */
|
||||
/* manual (in which case there is normally no need to set bus frequency). */
|
||||
if ((i2c->CTRL & I2C_CTRL_SLAVE) && !div) {
|
||||
div = 1;
|
||||
}
|
||||
i2c->CLKDIV = (uint32_t)div;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable/disable I2C.
|
||||
*
|
||||
* @note
|
||||
* After enabling the I2C (from being disabled), the I2C is in BUSY state.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] enable
|
||||
* true to enable counting, false to disable.
|
||||
******************************************************************************/
|
||||
void I2C_Enable(I2C_TypeDef *i2c, bool enable)
|
||||
{
|
||||
EFM_ASSERT(I2C_REF_VALID(i2c));
|
||||
|
||||
BUS_RegBitWrite(&(i2c->CTRL), _I2C_CTRL_EN_SHIFT, enable);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize I2C.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to I2C initialization structure.
|
||||
******************************************************************************/
|
||||
void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init)
|
||||
{
|
||||
EFM_ASSERT(I2C_REF_VALID(i2c));
|
||||
|
||||
i2c->IEN = 0;
|
||||
i2c->IFC = _I2C_IFC_MASK;
|
||||
|
||||
/* Set SLAVE select mode */
|
||||
BUS_RegBitWrite(&(i2c->CTRL), _I2C_CTRL_SLAVE_SHIFT, init->master ? 0 : 1);
|
||||
|
||||
I2C_BusFreqSet(i2c, init->refFreq, init->freq, init->clhr);
|
||||
|
||||
BUS_RegBitWrite(&(i2c->CTRL), _I2C_CTRL_EN_SHIFT, init->enable);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reset I2C to same state as after a HW reset.
|
||||
*
|
||||
* @note
|
||||
* The ROUTE register is NOT reset by this function, in order to allow for
|
||||
* centralized setup of this feature.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
******************************************************************************/
|
||||
void I2C_Reset(I2C_TypeDef *i2c)
|
||||
{
|
||||
i2c->CTRL = _I2C_CTRL_RESETVALUE;
|
||||
i2c->CLKDIV = _I2C_CLKDIV_RESETVALUE;
|
||||
i2c->SADDR = _I2C_SADDR_RESETVALUE;
|
||||
i2c->SADDRMASK = _I2C_SADDRMASK_RESETVALUE;
|
||||
i2c->IEN = _I2C_IEN_RESETVALUE;
|
||||
i2c->IFC = _I2C_IFC_MASK;
|
||||
/* Do not reset route register, setting should be done independently */
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Continue an initiated I2C transfer (single master mode only).
|
||||
*
|
||||
* @details
|
||||
* This function is used repeatedly after a I2C_TransferInit() in order to
|
||||
* complete a transfer. It may be used in polled mode as the below example
|
||||
* shows:
|
||||
* @verbatim
|
||||
* I2C_TransferReturn_TypeDef ret;
|
||||
*
|
||||
* // Do a polled transfer
|
||||
* ret = I2C_TransferInit(I2C0, seq);
|
||||
* while (ret == i2cTransferInProgress)
|
||||
* {
|
||||
* ret = I2C_Transfer(I2C0);
|
||||
* }
|
||||
* @endverbatim
|
||||
* It may also be used in interrupt driven mode, where this function is invoked
|
||||
* from the interrupt handler. Notice that if used in interrupt mode, NVIC
|
||||
* interrupts must be configured and enabled for the I2C bus used. I2C
|
||||
* peripheral specific interrupts are managed by this SW.
|
||||
*
|
||||
* @note
|
||||
* Only single master mode is supported.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @return
|
||||
* Returns status for ongoing transfer.
|
||||
* @li #i2cTransferInProgress - indicates that transfer not finished.
|
||||
* @li #i2cTransferDone - transfer completed successfully.
|
||||
* @li otherwise some sort of error has occurred.
|
||||
*
|
||||
******************************************************************************/
|
||||
I2C_TransferReturn_TypeDef I2C_Transfer(I2C_TypeDef *i2c)
|
||||
{
|
||||
uint32_t tmp;
|
||||
uint32_t pending;
|
||||
I2C_Transfer_TypeDef *transfer;
|
||||
I2C_TransferSeq_TypeDef *seq;
|
||||
|
||||
EFM_ASSERT(I2C_REF_VALID(i2c));
|
||||
|
||||
/* Support up to 2 I2C buses */
|
||||
if (i2c == I2C0) {
|
||||
transfer = i2cTransfer;
|
||||
}
|
||||
#if (I2C_COUNT > 1)
|
||||
else if (i2c == I2C1) {
|
||||
transfer = i2cTransfer + 1;
|
||||
}
|
||||
#endif
|
||||
#if (I2C_COUNT > 2)
|
||||
else if (i2c == I2C2) {
|
||||
transfer = i2cTransfer + 2;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
return i2cTransferUsageFault;
|
||||
}
|
||||
|
||||
seq = transfer->seq;
|
||||
for (;; ) {
|
||||
pending = i2c->IF;
|
||||
|
||||
/* If some sort of fault, abort transfer. */
|
||||
if (pending & I2C_IF_ERRORS) {
|
||||
if (pending & I2C_IF_ARBLOST) {
|
||||
/* If arbitration fault, it indicates either a slave device */
|
||||
/* not responding as expected, or other master which is not */
|
||||
/* supported by this SW. */
|
||||
transfer->result = i2cTransferArbLost;
|
||||
} else if (pending & I2C_IF_BUSERR) {
|
||||
/* A bus error indicates a misplaced start or stop, which should */
|
||||
/* not occur in master mode controlled by this SW. */
|
||||
transfer->result = i2cTransferBusErr;
|
||||
}
|
||||
|
||||
/* If error situation occurred, it is difficult to know */
|
||||
/* exact cause and how to resolve. It will be up to a wrapper */
|
||||
/* to determine how to handle a fault/recovery if possible. */
|
||||
transfer->state = i2cStateDone;
|
||||
goto done;
|
||||
}
|
||||
|
||||
switch (transfer->state) {
|
||||
/***************************************************/
|
||||
/* Send first start+address (first byte if 10 bit) */
|
||||
/***************************************************/
|
||||
case i2cStateStartAddrSend:
|
||||
if (seq->flags & I2C_FLAG_10BIT_ADDR) {
|
||||
tmp = (((uint32_t)(seq->addr) >> 8) & 0x06) | 0xf0;
|
||||
|
||||
/* In 10 bit address mode, the address following the first */
|
||||
/* start always indicate write. */
|
||||
} else {
|
||||
tmp = (uint32_t)(seq->addr) & 0xfe;
|
||||
|
||||
if (seq->flags & I2C_FLAG_READ) {
|
||||
/* Indicate read request */
|
||||
tmp |= 1;
|
||||
}
|
||||
}
|
||||
|
||||
transfer->state = i2cStateAddrWFAckNack;
|
||||
i2c->TXDATA = tmp;/* Data not transmitted until START sent */
|
||||
i2c->CMD = I2C_CMD_START;
|
||||
goto done;
|
||||
|
||||
/*******************************************************/
|
||||
/* Wait for ACK/NACK on address (first byte if 10 bit) */
|
||||
/*******************************************************/
|
||||
case i2cStateAddrWFAckNack:
|
||||
if (pending & I2C_IF_NACK) {
|
||||
i2c->IFC = I2C_IFC_NACK;
|
||||
transfer->result = i2cTransferNack;
|
||||
transfer->state = i2cStateWFStopSent;
|
||||
i2c->CMD = I2C_CMD_STOP;
|
||||
} else if (pending & I2C_IF_ACK) {
|
||||
i2c->IFC = I2C_IFC_ACK;
|
||||
|
||||
/* If 10 bit address, send 2nd byte of address. */
|
||||
if (seq->flags & I2C_FLAG_10BIT_ADDR) {
|
||||
transfer->state = i2cStateAddrWF2ndAckNack;
|
||||
i2c->TXDATA = (uint32_t)(seq->addr) & 0xff;
|
||||
} else {
|
||||
/* Determine whether receiving or sending data */
|
||||
if (seq->flags & I2C_FLAG_READ) {
|
||||
transfer->state = i2cStateWFData;
|
||||
if (seq->buf[transfer->bufIndx].len == 1) {
|
||||
i2c->CMD = I2C_CMD_NACK;
|
||||
}
|
||||
} else {
|
||||
transfer->state = i2cStateDataSend;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
|
||||
/******************************************************/
|
||||
/* Wait for ACK/NACK on second byte of 10 bit address */
|
||||
/******************************************************/
|
||||
case i2cStateAddrWF2ndAckNack:
|
||||
if (pending & I2C_IF_NACK) {
|
||||
i2c->IFC = I2C_IFC_NACK;
|
||||
transfer->result = i2cTransferNack;
|
||||
transfer->state = i2cStateWFStopSent;
|
||||
i2c->CMD = I2C_CMD_STOP;
|
||||
} else if (pending & I2C_IF_ACK) {
|
||||
i2c->IFC = I2C_IFC_ACK;
|
||||
|
||||
/* If using plain read sequence with 10 bit address, switch to send */
|
||||
/* repeated start. */
|
||||
if (seq->flags & I2C_FLAG_READ) {
|
||||
transfer->state = i2cStateRStartAddrSend;
|
||||
}
|
||||
/* Otherwise expected to write 0 or more bytes */
|
||||
else {
|
||||
transfer->state = i2cStateDataSend;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
goto done;
|
||||
|
||||
/*******************************/
|
||||
/* Send repeated start+address */
|
||||
/*******************************/
|
||||
case i2cStateRStartAddrSend:
|
||||
if (seq->flags & I2C_FLAG_10BIT_ADDR) {
|
||||
tmp = ((seq->addr >> 8) & 0x06) | 0xf0;
|
||||
} else {
|
||||
tmp = seq->addr & 0xfe;
|
||||
}
|
||||
|
||||
/* If this is a write+read combined sequence, then read is about to start */
|
||||
if (seq->flags & I2C_FLAG_WRITE_READ) {
|
||||
/* Indicate read request */
|
||||
tmp |= 1;
|
||||
}
|
||||
|
||||
transfer->state = i2cStateRAddrWFAckNack;
|
||||
/* We have to write START cmd first since repeated start, otherwise */
|
||||
/* data would be sent first. */
|
||||
i2c->CMD = I2C_CMD_START;
|
||||
i2c->TXDATA = tmp;
|
||||
goto done;
|
||||
|
||||
/**********************************************************************/
|
||||
/* Wait for ACK/NACK on repeated start+address (first byte if 10 bit) */
|
||||
/**********************************************************************/
|
||||
case i2cStateRAddrWFAckNack:
|
||||
if (pending & I2C_IF_NACK) {
|
||||
i2c->IFC = I2C_IFC_NACK;
|
||||
transfer->result = i2cTransferNack;
|
||||
transfer->state = i2cStateWFStopSent;
|
||||
i2c->CMD = I2C_CMD_STOP;
|
||||
} else if (pending & I2C_IF_ACK) {
|
||||
i2c->IFC = I2C_IFC_ACK;
|
||||
|
||||
/* Determine whether receiving or sending data */
|
||||
if (seq->flags & I2C_FLAG_WRITE_READ) {
|
||||
transfer->state = i2cStateWFData;
|
||||
} else {
|
||||
transfer->state = i2cStateDataSend;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
|
||||
/*****************************/
|
||||
/* Send a data byte to slave */
|
||||
/*****************************/
|
||||
case i2cStateDataSend:
|
||||
/* Reached end of data buffer? */
|
||||
if (transfer->offset >= seq->buf[transfer->bufIndx].len) {
|
||||
/* Move to next message part */
|
||||
transfer->offset = 0;
|
||||
transfer->bufIndx++;
|
||||
|
||||
/* Send repeated start when switching to read mode on 2nd buffer */
|
||||
if (seq->flags & I2C_FLAG_WRITE_READ) {
|
||||
transfer->state = i2cStateRStartAddrSend;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Only writing from one buffer, or finished both buffers */
|
||||
if ((seq->flags & I2C_FLAG_WRITE) || (transfer->bufIndx > 1)) {
|
||||
transfer->state = i2cStateWFStopSent;
|
||||
i2c->CMD = I2C_CMD_STOP;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Reprocess in case next buffer is empty */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Send byte */
|
||||
i2c->TXDATA = (uint32_t)(seq->buf[transfer->bufIndx].data[transfer->offset++]);
|
||||
transfer->state = i2cStateDataWFAckNack;
|
||||
goto done;
|
||||
|
||||
/*********************************************************/
|
||||
/* Wait for ACK/NACK from slave after sending data to it */
|
||||
/*********************************************************/
|
||||
case i2cStateDataWFAckNack:
|
||||
if (pending & I2C_IF_NACK) {
|
||||
i2c->IFC = I2C_IFC_NACK;
|
||||
transfer->result = i2cTransferNack;
|
||||
transfer->state = i2cStateWFStopSent;
|
||||
i2c->CMD = I2C_CMD_STOP;
|
||||
} else if (pending & I2C_IF_ACK) {
|
||||
i2c->IFC = I2C_IFC_ACK;
|
||||
transfer->state = i2cStateDataSend;
|
||||
continue;
|
||||
}
|
||||
goto done;
|
||||
|
||||
/****************************/
|
||||
/* Wait for data from slave */
|
||||
/****************************/
|
||||
case i2cStateWFData:
|
||||
if (pending & I2C_IF_RXDATAV) {
|
||||
uint8_t data;
|
||||
unsigned int rxLen = seq->buf[transfer->bufIndx].len;
|
||||
|
||||
/* Must read out data in order to not block further progress */
|
||||
data = (uint8_t)(i2c->RXDATA);
|
||||
|
||||
/* Make sure not storing beyond end of buffer just in case */
|
||||
if (transfer->offset < rxLen) {
|
||||
seq->buf[transfer->bufIndx].data[transfer->offset++] = data;
|
||||
}
|
||||
|
||||
/* If we have read all requested data, then the sequence should end */
|
||||
if (transfer->offset >= rxLen) {
|
||||
/* If there is only one byte to receive we need to transmit the
|
||||
NACK now, before the stop. */
|
||||
if (1 == rxLen) {
|
||||
i2c->CMD = I2C_CMD_NACK;
|
||||
}
|
||||
|
||||
transfer->state = i2cStateWFStopSent;
|
||||
i2c->CMD = I2C_CMD_STOP;
|
||||
} else {
|
||||
/* Send ACK and wait for next byte */
|
||||
i2c->CMD = I2C_CMD_ACK;
|
||||
|
||||
if ( (1 < rxLen) && (transfer->offset == (rxLen - 1)) ) {
|
||||
/* If there is more than one byte to receive and this is the next
|
||||
to last byte we need to transmit the NACK now, before receiving
|
||||
the last byte. */
|
||||
i2c->CMD = I2C_CMD_NACK;
|
||||
}
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
|
||||
/***********************************/
|
||||
/* Wait for STOP to have been sent */
|
||||
/***********************************/
|
||||
case i2cStateWFStopSent:
|
||||
if (pending & I2C_IF_MSTOP) {
|
||||
i2c->IFC = I2C_IFC_MSTOP;
|
||||
transfer->state = i2cStateDone;
|
||||
}
|
||||
goto done;
|
||||
|
||||
/******************************/
|
||||
/* Unexpected state, SW fault */
|
||||
/******************************/
|
||||
default:
|
||||
transfer->result = i2cTransferSwFault;
|
||||
transfer->state = i2cStateDone;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
if (transfer->state == i2cStateDone) {
|
||||
/* Disable interrupt sources when done */
|
||||
i2c->IEN = 0;
|
||||
|
||||
/* Update result unless some fault already occurred */
|
||||
if (transfer->result == i2cTransferInProgress) {
|
||||
transfer->result = i2cTransferDone;
|
||||
}
|
||||
}
|
||||
/* Until transfer is done keep returning i2cTransferInProgress */
|
||||
else {
|
||||
return i2cTransferInProgress;
|
||||
}
|
||||
|
||||
return transfer->result;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Prepare and start an I2C transfer (single master mode only).
|
||||
*
|
||||
* @details
|
||||
* This function must be invoked in order to start an I2C transfer
|
||||
* sequence. In order to actually complete the transfer, I2C_Transfer() must
|
||||
* be used either in polled mode or by adding a small driver wrapper utilizing
|
||||
* interrupts.
|
||||
*
|
||||
* @note
|
||||
* Only single master mode is supported.
|
||||
*
|
||||
* @param[in] i2c
|
||||
* Pointer to I2C peripheral register block.
|
||||
*
|
||||
* @param[in] seq
|
||||
* Pointer to sequence structure defining the I2C transfer to take place. The
|
||||
* referenced structure must exist until the transfer has fully completed.
|
||||
*
|
||||
* @return
|
||||
* Returns status for ongoing transfer:
|
||||
* @li #i2cTransferInProgress - indicates that transfer not finished.
|
||||
* @li otherwise some sort of error has occurred.
|
||||
******************************************************************************/
|
||||
I2C_TransferReturn_TypeDef I2C_TransferInit(I2C_TypeDef *i2c,
|
||||
I2C_TransferSeq_TypeDef *seq)
|
||||
{
|
||||
I2C_Transfer_TypeDef *transfer;
|
||||
|
||||
EFM_ASSERT(I2C_REF_VALID(i2c));
|
||||
EFM_ASSERT(seq);
|
||||
|
||||
/* Support up to 2 I2C buses */
|
||||
if (i2c == I2C0) {
|
||||
transfer = i2cTransfer;
|
||||
}
|
||||
#if (I2C_COUNT > 1)
|
||||
else if (i2c == I2C1) {
|
||||
transfer = i2cTransfer + 1;
|
||||
}
|
||||
#endif
|
||||
#if (I2C_COUNT > 2)
|
||||
else if (i2c == I2C2) {
|
||||
transfer = i2cTransfer + 2;
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
return i2cTransferUsageFault;
|
||||
}
|
||||
|
||||
/* Check if in busy state. Since this SW assumes single master, we can */
|
||||
/* just issue an abort. The BUSY state is normal after a reset. */
|
||||
if (i2c->STATE & I2C_STATE_BUSY) {
|
||||
i2c->CMD = I2C_CMD_ABORT;
|
||||
}
|
||||
|
||||
/* Make sure user is not trying to read 0 bytes, it is not */
|
||||
/* possible according to I2C spec, since slave will always start */
|
||||
/* sending first byte ACK on address. The read operation can */
|
||||
/* only be stopped by NACKing a received byte, ie minimum 1 byte. */
|
||||
if (((seq->flags & I2C_FLAG_READ) && !(seq->buf[0].len))
|
||||
|| ((seq->flags & I2C_FLAG_WRITE_READ) && !(seq->buf[1].len))
|
||||
) {
|
||||
return i2cTransferUsageFault;
|
||||
}
|
||||
|
||||
/* Prepare for a transfer */
|
||||
transfer->state = i2cStateStartAddrSend;
|
||||
transfer->result = i2cTransferInProgress;
|
||||
transfer->offset = 0;
|
||||
transfer->bufIndx = 0;
|
||||
transfer->seq = seq;
|
||||
|
||||
/* Ensure buffers are empty */
|
||||
i2c->CMD = I2C_CMD_CLEARPC | I2C_CMD_CLEARTX;
|
||||
if (i2c->IF & I2C_IF_RXDATAV) {
|
||||
(void)i2c->RXDATA;
|
||||
}
|
||||
|
||||
/* Clear all pending interrupts prior to starting transfer. */
|
||||
i2c->IFC = _I2C_IFC_MASK;
|
||||
|
||||
/* Enable those interrupts we are interested in throughout transfer. */
|
||||
/* Notice that the I2C interrupt must also be enabled in the NVIC, but */
|
||||
/* that is left for an additional driver wrapper. */
|
||||
i2c->IEN |= I2C_IF_NACK | I2C_IF_ACK | I2C_IF_MSTOP
|
||||
| I2C_IF_RXDATAV | I2C_IF_ERRORS;
|
||||
|
||||
/* Start transfer */
|
||||
return I2C_Transfer(i2c);
|
||||
}
|
||||
|
||||
/** @} (end addtogroup I2C) */
|
||||
/** @} (end addtogroup emlib) */
|
||||
#endif /* defined(I2C_COUNT) && (I2C_COUNT > 0) */
|
@ -1,355 +0,0 @@
|
||||
/***************************************************************************//**
|
||||
* @file em_ldma.c
|
||||
* @brief Direct memory access (LDMA) module peripheral API
|
||||
* @version 5.2.2
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software.@n
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.@n
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
|
||||
* obligation to support this Software. Silicon Labs is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Silicon Labs will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "em_ldma.h"
|
||||
|
||||
#if defined(LDMA_PRESENT) && (LDMA_COUNT == 1)
|
||||
|
||||
#include <stddef.h>
|
||||
#include "em_assert.h"
|
||||
#include "em_bus.h"
|
||||
#include "em_cmu.h"
|
||||
#include "em_core.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup emlib
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup LDMA
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(LDMA_IRQ_HANDLER_TEMPLATE)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Template for an LDMA IRQ handler.
|
||||
******************************************************************************/
|
||||
void LDMA_IRQHandler(void)
|
||||
{
|
||||
uint32_t ch;
|
||||
/* Get all pending and enabled interrupts. */
|
||||
uint32_t pending = LDMA_IntGetEnabled();
|
||||
|
||||
/* Loop here on an LDMA error to enable debugging. */
|
||||
while (pending & LDMA_IF_ERROR) {
|
||||
}
|
||||
|
||||
/* Iterate over all LDMA channels. */
|
||||
for (ch = 0; ch < DMA_CHAN_COUNT; ch++) {
|
||||
uint32_t mask = 0x1 << ch;
|
||||
if (pending & mask) {
|
||||
/* Clear interrupt flag. */
|
||||
LDMA->IFC = mask;
|
||||
|
||||
/* Do more stuff here, execute callbacks etc. */
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* De-initialize the LDMA controller.
|
||||
*
|
||||
* LDMA interrupts are disabled and the LDMA clock is stopped.
|
||||
******************************************************************************/
|
||||
void LDMA_DeInit(void)
|
||||
{
|
||||
NVIC_DisableIRQ(LDMA_IRQn);
|
||||
LDMA->IEN = 0;
|
||||
LDMA->CHEN = 0;
|
||||
CMU_ClockEnable(cmuClock_LDMA, false);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Enable or disable a LDMA channel request.
|
||||
*
|
||||
* @details
|
||||
* Use this function to enable or disable a LDMA channel request. This will
|
||||
* prevent the LDMA from proceeding after its current transaction if disabled.
|
||||
*
|
||||
* @param[in] channel
|
||||
* LDMA channel to enable or disable requests on.
|
||||
*
|
||||
* @param[in] enable
|
||||
* If 'true' request will be enabled. If 'false' request will be disabled.
|
||||
******************************************************************************/
|
||||
void LDMA_EnableChannelRequest(int ch, bool enable)
|
||||
{
|
||||
EFM_ASSERT(ch < DMA_CHAN_COUNT);
|
||||
|
||||
BUS_RegBitWrite(&LDMA->REQDIS, ch, !enable);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize the LDMA controller.
|
||||
*
|
||||
* @details
|
||||
* This function will disable all the LDMA channels and enable the LDMA bus
|
||||
* clock in the CMU. This function will also enable the LDMA IRQ in the NVIC
|
||||
* and set the LDMA IRQ priority to a user configurable priority. The LDMA
|
||||
* interrupt priority is configured using the @ref LDMA_Init_t structure.
|
||||
*
|
||||
* @note
|
||||
* Since this function enables the LDMA IRQ you should always add a custom
|
||||
* LDMA_IRQHandler to the application in order to handle any interrupts
|
||||
* from LDMA.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to initialization structure used to configure the LDMA.
|
||||
******************************************************************************/
|
||||
void LDMA_Init(const LDMA_Init_t *init)
|
||||
{
|
||||
EFM_ASSERT(init != NULL);
|
||||
EFM_ASSERT(!((init->ldmaInitCtrlNumFixed << _LDMA_CTRL_NUMFIXED_SHIFT)
|
||||
& ~_LDMA_CTRL_NUMFIXED_MASK));
|
||||
EFM_ASSERT(!((init->ldmaInitCtrlSyncPrsClrEn << _LDMA_CTRL_SYNCPRSCLREN_SHIFT)
|
||||
& ~_LDMA_CTRL_SYNCPRSCLREN_MASK));
|
||||
EFM_ASSERT(!((init->ldmaInitCtrlSyncPrsSetEn << _LDMA_CTRL_SYNCPRSSETEN_SHIFT)
|
||||
& ~_LDMA_CTRL_SYNCPRSSETEN_MASK));
|
||||
EFM_ASSERT(init->ldmaInitIrqPriority < (1 << __NVIC_PRIO_BITS));
|
||||
|
||||
CMU_ClockEnable(cmuClock_LDMA, true);
|
||||
|
||||
LDMA->CTRL = (init->ldmaInitCtrlNumFixed << _LDMA_CTRL_NUMFIXED_SHIFT)
|
||||
| (init->ldmaInitCtrlSyncPrsClrEn << _LDMA_CTRL_SYNCPRSCLREN_SHIFT)
|
||||
| (init->ldmaInitCtrlSyncPrsSetEn << _LDMA_CTRL_SYNCPRSSETEN_SHIFT);
|
||||
|
||||
LDMA->CHEN = 0;
|
||||
LDMA->DBGHALT = 0;
|
||||
LDMA->REQDIS = 0;
|
||||
|
||||
/* Enable LDMA error interrupt. */
|
||||
LDMA->IEN = LDMA_IEN_ERROR;
|
||||
LDMA->IFC = 0xFFFFFFFF;
|
||||
|
||||
NVIC_ClearPendingIRQ(LDMA_IRQn);
|
||||
|
||||
/* Range is 0..7, 0 is highest priority. */
|
||||
NVIC_SetPriority(LDMA_IRQn, init->ldmaInitIrqPriority);
|
||||
|
||||
NVIC_EnableIRQ(LDMA_IRQn);
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Start a DMA transfer.
|
||||
*
|
||||
* @param[in] ch
|
||||
* DMA channel.
|
||||
*
|
||||
* @param[in] transfer
|
||||
* Initialization structure used to configure the transfer.
|
||||
*
|
||||
* @param[in] descriptor
|
||||
* Transfer descriptor, can be an array of descriptors linked together.
|
||||
******************************************************************************/
|
||||
void LDMA_StartTransfer(int ch,
|
||||
const LDMA_TransferCfg_t *transfer,
|
||||
const LDMA_Descriptor_t *descriptor)
|
||||
{
|
||||
uint32_t tmp;
|
||||
CORE_DECLARE_IRQ_STATE;
|
||||
uint32_t chMask = 1 << ch;
|
||||
|
||||
EFM_ASSERT(ch < DMA_CHAN_COUNT);
|
||||
EFM_ASSERT(transfer != NULL);
|
||||
EFM_ASSERT(!(transfer->ldmaReqSel & ~_LDMA_CH_REQSEL_MASK));
|
||||
|
||||
EFM_ASSERT(!((transfer->ldmaCtrlSyncPrsClrOff << _LDMA_CTRL_SYNCPRSCLREN_SHIFT)
|
||||
& ~_LDMA_CTRL_SYNCPRSCLREN_MASK));
|
||||
EFM_ASSERT(!((transfer->ldmaCtrlSyncPrsClrOn << _LDMA_CTRL_SYNCPRSCLREN_SHIFT)
|
||||
& ~_LDMA_CTRL_SYNCPRSCLREN_MASK));
|
||||
EFM_ASSERT(!((transfer->ldmaCtrlSyncPrsSetOff << _LDMA_CTRL_SYNCPRSSETEN_SHIFT)
|
||||
& ~_LDMA_CTRL_SYNCPRSSETEN_MASK));
|
||||
EFM_ASSERT(!((transfer->ldmaCtrlSyncPrsSetOn << _LDMA_CTRL_SYNCPRSSETEN_SHIFT)
|
||||
& ~_LDMA_CTRL_SYNCPRSSETEN_MASK));
|
||||
|
||||
EFM_ASSERT(!((transfer->ldmaCfgArbSlots << _LDMA_CH_CFG_ARBSLOTS_SHIFT)
|
||||
& ~_LDMA_CH_CFG_ARBSLOTS_MASK));
|
||||
EFM_ASSERT(!((transfer->ldmaCfgSrcIncSign << _LDMA_CH_CFG_SRCINCSIGN_SHIFT)
|
||||
& ~_LDMA_CH_CFG_SRCINCSIGN_MASK) );
|
||||
EFM_ASSERT(!((transfer->ldmaCfgDstIncSign << _LDMA_CH_CFG_DSTINCSIGN_SHIFT)
|
||||
& ~_LDMA_CH_CFG_DSTINCSIGN_MASK));
|
||||
EFM_ASSERT(!((transfer->ldmaLoopCnt << _LDMA_CH_LOOP_LOOPCNT_SHIFT)
|
||||
& ~_LDMA_CH_LOOP_LOOPCNT_MASK));
|
||||
|
||||
LDMA->CH[ch].REQSEL = transfer->ldmaReqSel;
|
||||
LDMA->CH[ch].LOOP = (transfer->ldmaLoopCnt << _LDMA_CH_LOOP_LOOPCNT_SHIFT);
|
||||
LDMA->CH[ch].CFG = (transfer->ldmaCfgArbSlots << _LDMA_CH_CFG_ARBSLOTS_SHIFT)
|
||||
| (transfer->ldmaCfgSrcIncSign << _LDMA_CH_CFG_SRCINCSIGN_SHIFT)
|
||||
| (transfer->ldmaCfgDstIncSign << _LDMA_CH_CFG_DSTINCSIGN_SHIFT);
|
||||
|
||||
/* Set descriptor address. */
|
||||
LDMA->CH[ch].LINK = (uint32_t)descriptor & _LDMA_CH_LINK_LINKADDR_MASK;
|
||||
|
||||
/* Clear pending channel interrupt. */
|
||||
LDMA->IFC = chMask;
|
||||
|
||||
/* Critical region. */
|
||||
CORE_ENTER_ATOMIC();
|
||||
|
||||
/* Enable channel interrupt. */
|
||||
LDMA->IEN |= chMask;
|
||||
|
||||
if (transfer->ldmaReqDis) {
|
||||
LDMA->REQDIS |= chMask;
|
||||
}
|
||||
|
||||
if (transfer->ldmaDbgHalt) {
|
||||
LDMA->DBGHALT |= chMask;
|
||||
}
|
||||
|
||||
tmp = LDMA->CTRL;
|
||||
|
||||
if (transfer->ldmaCtrlSyncPrsClrOff) {
|
||||
tmp &= ~_LDMA_CTRL_SYNCPRSCLREN_MASK
|
||||
| (~transfer->ldmaCtrlSyncPrsClrOff << _LDMA_CTRL_SYNCPRSCLREN_SHIFT);
|
||||
}
|
||||
|
||||
if (transfer->ldmaCtrlSyncPrsClrOn) {
|
||||
tmp |= transfer->ldmaCtrlSyncPrsClrOn << _LDMA_CTRL_SYNCPRSCLREN_SHIFT;
|
||||
}
|
||||
|
||||
if (transfer->ldmaCtrlSyncPrsSetOff) {
|
||||
tmp &= ~_LDMA_CTRL_SYNCPRSSETEN_MASK
|
||||
| (~transfer->ldmaCtrlSyncPrsSetOff << _LDMA_CTRL_SYNCPRSSETEN_SHIFT);
|
||||
}
|
||||
|
||||
if (transfer->ldmaCtrlSyncPrsSetOn) {
|
||||
tmp |= transfer->ldmaCtrlSyncPrsSetOn << _LDMA_CTRL_SYNCPRSSETEN_SHIFT;
|
||||
}
|
||||
|
||||
LDMA->CTRL = tmp;
|
||||
|
||||
BUS_RegMaskedClear(&LDMA->CHDONE, chMask); /* Clear the done flag. */
|
||||
LDMA->LINKLOAD = chMask; /* Start transfer by loading descriptor. */
|
||||
|
||||
/* Critical region end. */
|
||||
CORE_EXIT_ATOMIC();
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Stop a DMA transfer.
|
||||
*
|
||||
* @note
|
||||
* The DMA will complete the current AHB burst transfer before stopping.
|
||||
*
|
||||
* @param[in] ch
|
||||
* DMA channel to stop.
|
||||
******************************************************************************/
|
||||
void LDMA_StopTransfer(int ch)
|
||||
{
|
||||
uint32_t chMask = 1 << ch;
|
||||
|
||||
EFM_ASSERT(ch < DMA_CHAN_COUNT);
|
||||
|
||||
CORE_ATOMIC_SECTION(
|
||||
LDMA->IEN &= ~chMask;
|
||||
BUS_RegMaskedClear(&LDMA->CHEN, chMask);
|
||||
)
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Check if a DMA transfer has completed.
|
||||
*
|
||||
* @param[in] ch
|
||||
* DMA channel to check.
|
||||
*
|
||||
* @return
|
||||
* True if transfer has completed, false if not.
|
||||
******************************************************************************/
|
||||
bool LDMA_TransferDone(int ch)
|
||||
{
|
||||
bool retVal = false;
|
||||
uint32_t chMask = 1 << ch;
|
||||
|
||||
EFM_ASSERT(ch < DMA_CHAN_COUNT);
|
||||
|
||||
CORE_ATOMIC_SECTION(
|
||||
if (((LDMA->CHEN & chMask) == 0)
|
||||
&& ((LDMA->CHDONE & chMask) == chMask)) {
|
||||
retVal = true;
|
||||
}
|
||||
)
|
||||
return retVal;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get number of items remaining in a transfer.
|
||||
*
|
||||
* @note
|
||||
* This function is does not take into account that a DMA transfers with
|
||||
* a chain of linked transfers might be ongoing. It will only check the
|
||||
* count for the current transfer.
|
||||
*
|
||||
* @param[in] ch
|
||||
* The channel number of the transfer to check.
|
||||
*
|
||||
* @return
|
||||
* Number of items remaining in the transfer.
|
||||
******************************************************************************/
|
||||
uint32_t LDMA_TransferRemainingCount(int ch)
|
||||
{
|
||||
uint32_t remaining, done, iflag;
|
||||
uint32_t chMask = 1 << ch;
|
||||
|
||||
EFM_ASSERT(ch < DMA_CHAN_COUNT);
|
||||
|
||||
CORE_ATOMIC_SECTION(
|
||||
iflag = LDMA->IF;
|
||||
done = LDMA->CHDONE;
|
||||
remaining = LDMA->CH[ch].CTRL;
|
||||
)
|
||||
|
||||
iflag &= chMask;
|
||||
done &= chMask;
|
||||
remaining = (remaining & _LDMA_CH_CTRL_XFERCNT_MASK)
|
||||
>> _LDMA_CH_CTRL_XFERCNT_SHIFT;
|
||||
|
||||
if (done || ((remaining == 0) && iflag)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return remaining + 1;
|
||||
}
|
||||
|
||||
/** @} (end addtogroup LDMA) */
|
||||
/** @} (end addtogroup emlib) */
|
||||
#endif /* defined( LDMA_PRESENT ) && ( LDMA_COUNT == 1 ) */
|
File diff suppressed because it is too large
Load Diff
@ -1,114 +0,0 @@
|
||||
/***************************************************************************//**
|
||||
* @file em_system.c
|
||||
* @brief System Peripheral API
|
||||
* @version 5.2.2
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
|
||||
* obligation to support this Software. Silicon Labs is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Silicon Labs will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "em_system.h"
|
||||
#include "em_assert.h"
|
||||
#include <stddef.h>
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup emlib
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup SYSTEM
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get chip major/minor revision.
|
||||
*
|
||||
* @param[out] rev
|
||||
* Location to place chip revision info.
|
||||
******************************************************************************/
|
||||
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev)
|
||||
{
|
||||
uint8_t tmp;
|
||||
|
||||
EFM_ASSERT(rev);
|
||||
|
||||
/* CHIP FAMILY bit [5:2] */
|
||||
tmp = (((ROMTABLE->PID1 & _ROMTABLE_PID1_FAMILYMSB_MASK) >> _ROMTABLE_PID1_FAMILYMSB_SHIFT) << 2);
|
||||
/* CHIP FAMILY bit [1:0] */
|
||||
tmp |= ((ROMTABLE->PID0 & _ROMTABLE_PID0_FAMILYLSB_MASK) >> _ROMTABLE_PID0_FAMILYLSB_SHIFT);
|
||||
rev->family = tmp;
|
||||
|
||||
/* CHIP MAJOR bit [3:0] */
|
||||
rev->major = (ROMTABLE->PID0 & _ROMTABLE_PID0_REVMAJOR_MASK) >> _ROMTABLE_PID0_REVMAJOR_SHIFT;
|
||||
|
||||
/* CHIP MINOR bit [7:4] */
|
||||
tmp = (((ROMTABLE->PID2 & _ROMTABLE_PID2_REVMINORMSB_MASK) >> _ROMTABLE_PID2_REVMINORMSB_SHIFT) << 4);
|
||||
/* CHIP MINOR bit [3:0] */
|
||||
tmp |= ((ROMTABLE->PID3 & _ROMTABLE_PID3_REVMINORLSB_MASK) >> _ROMTABLE_PID3_REVMINORLSB_SHIFT);
|
||||
rev->minor = tmp;
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get factory calibration value for a given peripheral register.
|
||||
*
|
||||
* @param[in] regAddress
|
||||
* Peripheral calibration register address to get calibration value for. If
|
||||
* a calibration value is found then this register is updated with the
|
||||
* calibration value.
|
||||
*
|
||||
* @return
|
||||
* True if a calibration value exists, false otherwise.
|
||||
******************************************************************************/
|
||||
bool SYSTEM_GetCalibrationValue(volatile uint32_t *regAddress)
|
||||
{
|
||||
SYSTEM_CalAddrVal_TypeDef * p, * end;
|
||||
|
||||
p = (SYSTEM_CalAddrVal_TypeDef *)(DEVINFO_BASE & 0xFFFFF000);
|
||||
end = (SYSTEM_CalAddrVal_TypeDef *)DEVINFO_BASE;
|
||||
|
||||
for (; p < end; p++) {
|
||||
if (p->address == 0xFFFFFFFF) {
|
||||
/* Found table terminator */
|
||||
return false;
|
||||
}
|
||||
if (p->address == (uint32_t)regAddress) {
|
||||
*regAddress = p->calValue;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/* Nothing found for regAddress */
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @} (end addtogroup SYSTEM) */
|
||||
/** @} (end addtogroup emlib) */
|
@ -1,253 +0,0 @@
|
||||
/***************************************************************************//**
|
||||
* @file em_timer.c
|
||||
* @brief Timer/counter (TIMER) Peripheral API
|
||||
* @version 5.2.2
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
|
||||
* obligation to support this Software. Silicon Labs is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Silicon Labs will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "em_timer.h"
|
||||
#if defined(TIMER_COUNT) && (TIMER_COUNT > 0)
|
||||
|
||||
#include "em_assert.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup emlib
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup TIMER
|
||||
* @brief Timer/Counter (TIMER) Peripheral API
|
||||
* @details
|
||||
* The timer module consists of three main parts:
|
||||
* @li General timer config and enable control.
|
||||
* @li Compare/capture control.
|
||||
* @li Dead time insertion control (may not be available for all timers).
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize TIMER.
|
||||
*
|
||||
* @details
|
||||
* Notice that counter top must be configured separately with for instance
|
||||
* TIMER_TopSet(). In addition, compare/capture and dead-time insertion
|
||||
* init must be initialized separately if used. That should probably
|
||||
* be done prior to the use of this function if configuring the TIMER to
|
||||
* start when initialization is completed.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to TIMER initialization structure.
|
||||
******************************************************************************/
|
||||
void TIMER_Init(TIMER_TypeDef *timer, const TIMER_Init_TypeDef *init)
|
||||
{
|
||||
EFM_ASSERT(TIMER_REF_VALID(timer));
|
||||
|
||||
/* Stop timer if specified to be disabled (dosn't hurt if already stopped) */
|
||||
if (!(init->enable)) {
|
||||
timer->CMD = TIMER_CMD_STOP;
|
||||
}
|
||||
|
||||
/* Reset counter */
|
||||
timer->CNT = _TIMER_CNT_RESETVALUE;
|
||||
|
||||
timer->CTRL = ((uint32_t)(init->prescale) << _TIMER_CTRL_PRESC_SHIFT)
|
||||
| ((uint32_t)(init->clkSel) << _TIMER_CTRL_CLKSEL_SHIFT)
|
||||
| ((uint32_t)(init->fallAction) << _TIMER_CTRL_FALLA_SHIFT)
|
||||
| ((uint32_t)(init->riseAction) << _TIMER_CTRL_RISEA_SHIFT)
|
||||
| ((uint32_t)(init->mode) << _TIMER_CTRL_MODE_SHIFT)
|
||||
| (init->debugRun ? TIMER_CTRL_DEBUGRUN : 0)
|
||||
| (init->dmaClrAct ? TIMER_CTRL_DMACLRACT : 0)
|
||||
| (init->quadModeX4 ? TIMER_CTRL_QDM_X4 : 0)
|
||||
| (init->oneShot ? TIMER_CTRL_OSMEN : 0)
|
||||
|
||||
#if defined(TIMER_CTRL_X2CNT) && defined(TIMER_CTRL_ATI)
|
||||
| (init->count2x ? TIMER_CTRL_X2CNT : 0)
|
||||
| (init->ati ? TIMER_CTRL_ATI : 0)
|
||||
#endif
|
||||
| (init->sync ? TIMER_CTRL_SYNC : 0);
|
||||
|
||||
/* Start timer if specified to be enabled (dosn't hurt if already started) */
|
||||
if (init->enable) {
|
||||
timer->CMD = TIMER_CMD_START;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize TIMER compare/capture channel.
|
||||
*
|
||||
* @details
|
||||
* Notice that if operating channel in compare mode, the CCV and CCVB register
|
||||
* must be set separately as required.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] ch
|
||||
* Compare/capture channel to init for.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to TIMER initialization structure.
|
||||
******************************************************************************/
|
||||
void TIMER_InitCC(TIMER_TypeDef *timer,
|
||||
unsigned int ch,
|
||||
const TIMER_InitCC_TypeDef *init)
|
||||
{
|
||||
EFM_ASSERT(TIMER_REF_VALID(timer));
|
||||
EFM_ASSERT(TIMER_CH_VALID(ch));
|
||||
|
||||
timer->CC[ch].CTRL =
|
||||
((uint32_t)(init->eventCtrl) << _TIMER_CC_CTRL_ICEVCTRL_SHIFT)
|
||||
| ((uint32_t)(init->edge) << _TIMER_CC_CTRL_ICEDGE_SHIFT)
|
||||
| ((uint32_t)(init->prsSel) << _TIMER_CC_CTRL_PRSSEL_SHIFT)
|
||||
| ((uint32_t)(init->cufoa) << _TIMER_CC_CTRL_CUFOA_SHIFT)
|
||||
| ((uint32_t)(init->cofoa) << _TIMER_CC_CTRL_COFOA_SHIFT)
|
||||
| ((uint32_t)(init->cmoa) << _TIMER_CC_CTRL_CMOA_SHIFT)
|
||||
| ((uint32_t)(init->mode) << _TIMER_CC_CTRL_MODE_SHIFT)
|
||||
| (init->filter ? TIMER_CC_CTRL_FILT_ENABLE : 0)
|
||||
| (init->prsInput ? TIMER_CC_CTRL_INSEL_PRS : 0)
|
||||
| (init->coist ? TIMER_CC_CTRL_COIST : 0)
|
||||
| (init->outInvert ? TIMER_CC_CTRL_OUTINV : 0);
|
||||
}
|
||||
|
||||
#if defined(_TIMER_DTCTRL_MASK)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize the TIMER DTI unit.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to TIMER DTI initialization structure.
|
||||
******************************************************************************/
|
||||
void TIMER_InitDTI(TIMER_TypeDef *timer, const TIMER_InitDTI_TypeDef *init)
|
||||
{
|
||||
EFM_ASSERT(TIMER0 == timer);
|
||||
|
||||
/* Make sure the DTI unit is disabled while initializing. */
|
||||
TIMER_EnableDTI(timer, false);
|
||||
|
||||
/* Setup the DTCTRL register.
|
||||
The enable bit will be set at the end of the function if specified. */
|
||||
timer->DTCTRL =
|
||||
(init->autoRestart ? TIMER_DTCTRL_DTDAS : 0)
|
||||
| (init->activeLowOut ? TIMER_DTCTRL_DTIPOL : 0)
|
||||
| (init->invertComplementaryOut ? TIMER_DTCTRL_DTCINV : 0)
|
||||
| (init->enablePrsSource ? TIMER_DTCTRL_DTPRSEN : 0)
|
||||
| ((uint32_t)(init->prsSel) << _TIMER_DTCTRL_DTPRSSEL_SHIFT);
|
||||
|
||||
/* Setup the DTTIME register. */
|
||||
timer->DTTIME =
|
||||
((uint32_t)(init->prescale) << _TIMER_DTTIME_DTPRESC_SHIFT)
|
||||
| ((uint32_t)(init->riseTime) << _TIMER_DTTIME_DTRISET_SHIFT)
|
||||
| ((uint32_t)(init->fallTime) << _TIMER_DTTIME_DTFALLT_SHIFT);
|
||||
|
||||
/* Setup the DTFC register. */
|
||||
timer->DTFC =
|
||||
(init->enableFaultSourceCoreLockup ? TIMER_DTFC_DTLOCKUPFEN : 0)
|
||||
| (init->enableFaultSourceDebugger ? TIMER_DTFC_DTDBGFEN : 0)
|
||||
| (init->enableFaultSourcePrsSel0 ? TIMER_DTFC_DTPRS0FEN : 0)
|
||||
| (init->enableFaultSourcePrsSel1 ? TIMER_DTFC_DTPRS1FEN : 0)
|
||||
| ((uint32_t)(init->faultAction) << _TIMER_DTFC_DTFA_SHIFT)
|
||||
| ((uint32_t)(init->faultSourcePrsSel0) << _TIMER_DTFC_DTPRS0FSEL_SHIFT)
|
||||
| ((uint32_t)(init->faultSourcePrsSel1) << _TIMER_DTFC_DTPRS1FSEL_SHIFT);
|
||||
|
||||
/* Setup the DTOGEN register. */
|
||||
timer->DTOGEN = init->outputsEnableMask;
|
||||
|
||||
/* Clear any previous DTI faults. */
|
||||
TIMER_ClearDTIFault(timer, TIMER_GetDTIFault(timer));
|
||||
|
||||
/* Enable/disable before returning. */
|
||||
TIMER_EnableDTI(timer, init->enable);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Reset TIMER to same state as after a HW reset.
|
||||
*
|
||||
* @note
|
||||
* The ROUTE register is NOT reset by this function, in order to allow for
|
||||
* centralized setup of this feature.
|
||||
*
|
||||
* @param[in] timer
|
||||
* Pointer to TIMER peripheral register block.
|
||||
******************************************************************************/
|
||||
void TIMER_Reset(TIMER_TypeDef *timer)
|
||||
{
|
||||
int i;
|
||||
|
||||
EFM_ASSERT(TIMER_REF_VALID(timer));
|
||||
|
||||
/* Make sure disabled first, before resetting other registers */
|
||||
timer->CMD = TIMER_CMD_STOP;
|
||||
|
||||
timer->CTRL = _TIMER_CTRL_RESETVALUE;
|
||||
timer->IEN = _TIMER_IEN_RESETVALUE;
|
||||
timer->IFC = _TIMER_IFC_MASK;
|
||||
timer->TOPB = _TIMER_TOPB_RESETVALUE;
|
||||
/* Write TOP after TOPB to invalidate TOPB (clear TIMER_STATUS_TOPBV) */
|
||||
timer->TOP = _TIMER_TOP_RESETVALUE;
|
||||
timer->CNT = _TIMER_CNT_RESETVALUE;
|
||||
/* Do not reset route register, setting should be done independently */
|
||||
/* (Note: ROUTE register may be locked by DTLOCK register.) */
|
||||
|
||||
for (i = 0; TIMER_CH_VALID(i); i++) {
|
||||
timer->CC[i].CTRL = _TIMER_CC_CTRL_RESETVALUE;
|
||||
timer->CC[i].CCV = _TIMER_CC_CCV_RESETVALUE;
|
||||
timer->CC[i].CCVB = _TIMER_CC_CCVB_RESETVALUE;
|
||||
}
|
||||
|
||||
/* Reset dead time insertion module, no effect on timers without DTI */
|
||||
|
||||
#if defined(TIMER_DTLOCK_LOCKKEY_UNLOCK)
|
||||
/* Unlock DTI registers first in case locked */
|
||||
timer->DTLOCK = TIMER_DTLOCK_LOCKKEY_UNLOCK;
|
||||
|
||||
timer->DTCTRL = _TIMER_DTCTRL_RESETVALUE;
|
||||
timer->DTTIME = _TIMER_DTTIME_RESETVALUE;
|
||||
timer->DTFC = _TIMER_DTFC_RESETVALUE;
|
||||
timer->DTOGEN = _TIMER_DTOGEN_RESETVALUE;
|
||||
timer->DTFAULTC = _TIMER_DTFAULTC_MASK;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @} (end addtogroup TIMER) */
|
||||
/** @} (end addtogroup emlib) */
|
||||
#endif /* defined(TIMER_COUNT) && (TIMER_COUNT > 0) */
|
File diff suppressed because it is too large
Load Diff
@ -1,48 +0,0 @@
|
||||
//=========================================================
|
||||
// inc/InitDevice.h: generated by Hardware Configurator
|
||||
//
|
||||
// This file will be regenerated when saving a document.
|
||||
// leave the sections inside the "$[...]" comment tags alone
|
||||
// or they will be overwritten!
|
||||
//=========================================================
|
||||
#ifndef __INIT_DEVICE_H__
|
||||
#define __INIT_DEVICE_H__
|
||||
|
||||
// USER CONSTANTS
|
||||
// USER PROTOTYPES
|
||||
|
||||
// $[Mode Transition Prototypes]
|
||||
extern void enter_DefaultMode_from_RESET(void);
|
||||
// [Mode Transition Prototypes]$
|
||||
|
||||
// $[Config(Per-Module Mode)Transition Prototypes]
|
||||
extern void EMU_enter_DefaultMode_from_RESET(void);
|
||||
extern void LFXO_enter_DefaultMode_from_RESET(void);
|
||||
extern void CMU_enter_DefaultMode_from_RESET(void);
|
||||
extern void ADC0_enter_DefaultMode_from_RESET(void);
|
||||
extern void ACMP0_enter_DefaultMode_from_RESET(void);
|
||||
extern void ACMP1_enter_DefaultMode_from_RESET(void);
|
||||
extern void IDAC0_enter_DefaultMode_from_RESET(void);
|
||||
extern void RTCC_enter_DefaultMode_from_RESET(void);
|
||||
extern void USART0_enter_DefaultMode_from_RESET(void);
|
||||
extern void USART1_enter_DefaultMode_from_RESET(void);
|
||||
extern void LEUART0_enter_DefaultMode_from_RESET(void);
|
||||
extern void WDOG0_enter_DefaultMode_from_RESET(void);
|
||||
extern void I2C0_enter_DefaultMode_from_RESET(void);
|
||||
extern void GPCRC_enter_DefaultMode_from_RESET(void);
|
||||
extern void LDMA_enter_DefaultMode_from_RESET(void);
|
||||
extern void TIMER0_enter_DefaultMode_from_RESET(void);
|
||||
extern void TIMER1_enter_DefaultMode_from_RESET(void);
|
||||
extern void LETIMER0_enter_DefaultMode_from_RESET(void);
|
||||
extern void CRYOTIMER_enter_DefaultMode_from_RESET(void);
|
||||
extern void PCNT0_enter_DefaultMode_from_RESET(void);
|
||||
extern void PRS_enter_DefaultMode_from_RESET(void);
|
||||
extern void PORTIO_enter_DefaultMode_from_RESET(void);
|
||||
// [Config(Per-Module Mode)Transition Prototypes]$
|
||||
|
||||
// $[User-defined pin name abstraction]
|
||||
|
||||
// [User-defined pin name abstraction]$
|
||||
|
||||
#endif
|
||||
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
/*
|
||||
* app.h
|
||||
*
|
||||
* Created on: Jun 26, 2018
|
||||
* Author: conor
|
||||
*/
|
||||
|
||||
#ifndef SRC_APP_H_
|
||||
#define SRC_APP_H_
|
||||
|
||||
#define DEBUG_LEVEL 1
|
||||
|
||||
//#define PRINTING_USE_VCOM
|
||||
|
||||
//#define USING_DEV_BOARD
|
||||
|
||||
//#define ENABLE_U2F_EXTENSIONS
|
||||
|
||||
#define ENABLE_U2F
|
||||
|
||||
//#define DISABLE_CTAPHID_PING
|
||||
//#define DISABLE_CTAPHID_WINK
|
||||
//#define DISABLE_CTAPHID_CBOR
|
||||
|
||||
void printing_init();
|
||||
|
||||
//#define TEST
|
||||
//#define TEST_POWER
|
||||
|
||||
// GPIO assignments
|
||||
#define NFC_DEV_SS gpioPortF,2
|
||||
|
||||
#define LED_INIT_VALUE 0x001000
|
||||
|
||||
#endif /* SRC_APP_H_ */
|
@ -1,278 +0,0 @@
|
||||
/*
|
||||
* Configuration for enabling CRYPTO hardware acceleration in all mbedtls
|
||||
* modules when running on SiliconLabs devices.
|
||||
*
|
||||
* Copyright (C) 2016, Silicon Labs, http://www.silabs.com
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup sl_crypto_config Silicon Labs CRYPTO Hardware Acceleration Configuration
|
||||
* @addtogroup sl_crypto_config
|
||||
*
|
||||
* @brief
|
||||
* mbed TLS configuration for Silicon Labs CRYPTO hardware acceleration
|
||||
*
|
||||
* @details
|
||||
* mbed TLS configuration is composed of settings in this Silicon Labs specific CRYPTO hardware acceleration file located in mbedtls/configs and the mbed TLS configuration file in mbedtls/include/mbedtls/config.h.
|
||||
* This configuration can be used as a starting point to evaluate hardware acceleration available on Silicon Labs devices.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef MBEDTLS_CONFIG_SL_CRYPTO_ALL_ACCELERATION_H
|
||||
#define MBEDTLS_CONFIG_SL_CRYPTO_ALL_ACCELERATION_H
|
||||
|
||||
#include "em_device.h"
|
||||
|
||||
#if !defined(NO_CRYPTO_ACCELERATION)
|
||||
/**
|
||||
* @name SECTION: Silicon Labs Acceleration settings
|
||||
*
|
||||
* This section sets Silicon Labs Acceleration settings.
|
||||
* @{
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_AES_ALT
|
||||
*
|
||||
* Enable hardware acceleration for the AES block cipher
|
||||
*
|
||||
* Module: sl_crypto/src/crypto_aes.c for devices with CRYPTO
|
||||
* sl_crypto/src/aes_aes.c for devices with AES
|
||||
*
|
||||
* See MBEDTLS_AES_C for more information.
|
||||
*/
|
||||
#define MBEDTLS_AES_ALT
|
||||
#define MBEDTLS_ECP_ALT
|
||||
/**
|
||||
* \def MBEDTLS_ECP_INTERNAL_ALT
|
||||
* \def ECP_SHORTWEIERSTRASS
|
||||
* \def MBEDTLS_ECP_ADD_MIXED_ALT
|
||||
* \def MBEDTLS_ECP_DOUBLE_JAC_ALT
|
||||
* \def MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
|
||||
* \def MBEDTLS_ECP_NORMALIZE_JAC_ALT
|
||||
*
|
||||
* Enable hardware acceleration for the elliptic curve over GF(p) library.
|
||||
*
|
||||
* Module: sl_crypto/src/crypto_ecp.c
|
||||
* Caller: library/ecp.c
|
||||
*
|
||||
* Requires: MBEDTLS_BIGNUM_C, MBEDTLS_ECP_C and at least one
|
||||
* MBEDTLS_ECP_DP_XXX_ENABLED and (CRYPTO_COUNT > 0)
|
||||
*/
|
||||
#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
|
||||
#define MBEDTLS_ECP_INTERNAL_ALT
|
||||
#define ECP_SHORTWEIERSTRASS
|
||||
#define MBEDTLS_ECP_ADD_MIXED_ALT
|
||||
#define MBEDTLS_ECP_DOUBLE_JAC_ALT
|
||||
#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
|
||||
#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
|
||||
#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SHA1_ALT
|
||||
*
|
||||
* Enable hardware acceleration for the SHA1 cryptographic hash algorithm.
|
||||
*
|
||||
* Module: sl_crypto/src/crypto_sha.c
|
||||
* Caller: library/mbedtls_md.c
|
||||
* library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
* library/ssl_tls.c
|
||||
* library/x509write_crt.c
|
||||
*
|
||||
* Requires: MBEDTLS_SHA1_C and (CRYPTO_COUNT > 0)
|
||||
* See MBEDTLS_SHA1_C for more information.
|
||||
*/
|
||||
#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
|
||||
#define MBEDTLS_SHA1_ALT
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_SHA256_ALT
|
||||
*
|
||||
* Enable hardware acceleration for the SHA-224 and SHA-256 cryptographic
|
||||
* hash algorithms.
|
||||
*
|
||||
* Module: sl_crypto/src/crypto_sha.c
|
||||
* Caller: library/entropy.c
|
||||
* library/mbedtls_md.c
|
||||
* library/ssl_cli.c
|
||||
* library/ssl_srv.c
|
||||
* library/ssl_tls.c
|
||||
*
|
||||
* Requires: MBEDTLS_SHA256_C and (CRYPTO_COUNT > 0)
|
||||
* See MBEDTLS_SHA256_C for more information.
|
||||
*/
|
||||
#if defined(CRYPTO_COUNT) && (CRYPTO_COUNT > 0)
|
||||
#define MBEDTLS_SHA256_ALT
|
||||
#endif
|
||||
|
||||
#endif /* #if !defined(NO_CRYPTO_ACCELERATION) */
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_TRNG_C
|
||||
*
|
||||
* Enable software support for the True Random Number Generator (TRNG)
|
||||
* incorporated from Series 1 Configuration 2 devices (EFR32MG12, etc.)
|
||||
* from Silicon Labs.
|
||||
*
|
||||
* TRNG is not supported by software for EFR32XG13 (SDID_89) and
|
||||
* EFR32XG14 (SDID_95).
|
||||
*
|
||||
* Requires TRNG_PRESENT &&
|
||||
* !(_SILICON_LABS_GECKO_INTERNAL_SDID_89 ||
|
||||
* _SILICON_LABS_GECKO_INTERNAL_SDID_95)
|
||||
*/
|
||||
#if defined(TRNG_PRESENT) && \
|
||||
!(defined(_SILICON_LABS_GECKO_INTERNAL_SDID_89) || \
|
||||
defined(_SILICON_LABS_GECKO_INTERNAL_SDID_95))
|
||||
#define MBEDTLS_TRNG_C
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ENTROPY_ADC_C
|
||||
*
|
||||
* Enable software support for the retrieving entropy data from the ADC
|
||||
* incorporated on devices from Silicon Labs.
|
||||
*
|
||||
* Requires ADC_PRESENT && _ADC_SINGLECTRLX_VREFSEL_VENTROPY
|
||||
*/
|
||||
#if defined(ADC_PRESENT) && defined(_ADC_SINGLECTRLX_VREFSEL_VENTROPY)
|
||||
#define MBEDTLS_ENTROPY_ADC_C
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ENTROPY_ADC_INSTANCE
|
||||
*
|
||||
* Specify which ADC instance shall be used as entropy source.
|
||||
*
|
||||
* Requires MBEDTLS_ENTROPY_ADC_C
|
||||
*/
|
||||
#if defined(MBEDTLS_ENTROPY_ADC_C)
|
||||
#define MBEDTLS_ENTROPY_ADC_INSTANCE (0)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ENTROPY_RAIL_C
|
||||
*
|
||||
* Enable software support for the retrieving entropy data from the RAIL
|
||||
* incorporated on devices from Silicon Labs.
|
||||
*
|
||||
* Requires _EFR_DEVICE
|
||||
*/
|
||||
#if defined(_EFR_DEVICE)
|
||||
#define MBEDTLS_ENTROPY_RAIL_C
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL
|
||||
*
|
||||
* Use the radio (RAIL) as default hardware entropy source.
|
||||
*
|
||||
* Requires MBEDTLS_ENTROPY_RAIL_C && _EFR_DEVICE && !MBEDTLS_TRNG_C
|
||||
*/
|
||||
#if defined(MBEDTLS_ENTROPY_RAIL_C) && \
|
||||
defined(_EFR_DEVICE) && !defined(MBEDTLS_TRNG_C)
|
||||
#define MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_ENTROPY_HARDWARE_ALT
|
||||
*
|
||||
* Integrate the provided default entropy source into the mbed
|
||||
* TLS entropy infrastructure.
|
||||
*
|
||||
* Requires MBEDTLS_TRNG_C || MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL
|
||||
*/
|
||||
#if defined(MBEDTLS_TRNG_C) || defined(MBEDTLS_ENTROPY_HARDWARE_ALT_RAIL)
|
||||
#define MBEDTLS_ENTROPY_HARDWARE_ALT
|
||||
#endif
|
||||
|
||||
/* Default ECC configuration for Silicon Labs devices: */
|
||||
|
||||
/* ECC curves supported by CRYPTO hardware module: */
|
||||
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
|
||||
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
|
||||
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
|
||||
|
||||
/* Save RAM by adjusting to our exact needs */
|
||||
#define MBEDTLS_ECP_MAX_BITS 256
|
||||
#ifndef MBEDTLS_MPI_MAX_SIZE
|
||||
#define MBEDTLS_MPI_MAX_SIZE 32 // 384 bits is 48 bytes
|
||||
#endif
|
||||
|
||||
/*
|
||||
Set MBEDTLS_ECP_WINDOW_SIZE to configure
|
||||
ECC point multiplication window size, see ecp.h:
|
||||
2 = Save RAM at the expense of speed
|
||||
3 = Improve speed at the expense of RAM
|
||||
4 = Optimize speed at the expense of RAM
|
||||
*/
|
||||
#define MBEDTLS_ECP_WINDOW_SIZE 3
|
||||
#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0
|
||||
|
||||
/* Significant speed benefit at the expense of some ROM */
|
||||
#define MBEDTLS_ECP_NIST_OPTIM
|
||||
|
||||
/* Include the default mbed TLS config file */
|
||||
#include "mbedtls/config.h"
|
||||
|
||||
#undef MBEDTLS_TIMING_C
|
||||
#undef MBEDTLS_FS_IO
|
||||
#undef MBEDTLS_SHA512_C
|
||||
#undef MBEDTLS_ENTROPY_SHA512_ACCUMULATOR
|
||||
|
||||
#undef MBEDTLS_NET_C
|
||||
|
||||
#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
|
||||
#define MBEDTLS_ECP_DEVICE_ALT
|
||||
#define MBEDTLS_MPI_MODULAR_DIVISION_ALT
|
||||
|
||||
#define MBEDTLS_ECP_INTERNAL_ALT
|
||||
#define ECP_SHORTWEIERSTRASS
|
||||
#define MBEDTLS_ECP_ADD_MIXED_ALT
|
||||
#define MBEDTLS_ECP_DOUBLE_JAC_ALT
|
||||
#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT
|
||||
#define MBEDTLS_ECP_NORMALIZE_JAC_ALT
|
||||
#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT
|
||||
#define MBEDTLS_ECP_DEVICE_ADD_MIXED_ALT
|
||||
|
||||
//#define MBEDTLS_ENTROPY_ALT
|
||||
|
||||
//#define MBEDTLS_MPI_MUL_MPI_ALT // doesnt seem to be implemented
|
||||
//#define MBEDTLS_MPI_MUL_INT_ALT // makes no difference or slightly slower
|
||||
|
||||
#define MBEDTLS_NO_PLATFORM_ENTROPY
|
||||
/* Hardware entropy source is not yet supported. Uncomment this macro to
|
||||
provide your own implementation of an entropy collector. */
|
||||
//#define MBEDTLS_ENTROPY_HARDWARE_ALT
|
||||
|
||||
/* Exclude and/or change default config here. E.g.: */
|
||||
//#undef MBEDTLS_ECP_DP_SECP384R1_ENABLED
|
||||
//#undef MBEDTLS_ECP_DP_SECP521R1_ENABLED
|
||||
//#undef MBEDTLS_ECP_DP_BP384R1_ENABLED
|
||||
//#undef MBEDTLS_ECP_DP_BP512R1_ENABLED
|
||||
//#undef MBEDTLS_SHA512_C
|
||||
|
||||
#include "mbedtls/check_config.h"
|
||||
|
||||
/** @} (end section sl_crypto_config) */
|
||||
/** @} (end addtogroup sl_crypto_config) */
|
||||
|
||||
#endif /* MBEDTLS_CONFIG_SL_CRYPTO_ALL_ACCELERATION_H */
|
@ -1,752 +0,0 @@
|
||||
//=========================================================
|
||||
// src/InitDevice.c: generated by Hardware Configurator
|
||||
//
|
||||
// This file will be regenerated when saving a document.
|
||||
// leave the sections inside the "$[...]" comment tags alone
|
||||
// or they will be overwritten!
|
||||
//=========================================================
|
||||
|
||||
// USER INCLUDES
|
||||
#include "InitDevice.h"
|
||||
|
||||
// USER PROTOTYPES
|
||||
// USER FUNCTIONS
|
||||
|
||||
// $[Library includes]
|
||||
#include "em_system.h"
|
||||
#include "em_emu.h"
|
||||
#include "em_cmu.h"
|
||||
#include "em_device.h"
|
||||
#include "em_chip.h"
|
||||
#include "em_assert.h"
|
||||
#include "em_adc.h"
|
||||
#include "em_cryotimer.h"
|
||||
#include "em_crypto.h"
|
||||
#include "em_gpio.h"
|
||||
#include "em_timer.h"
|
||||
#include "em_usart.h"
|
||||
// [Library includes]$
|
||||
|
||||
//==============================================================================
|
||||
// enter_DefaultMode_from_RESET
|
||||
//==============================================================================
|
||||
extern void enter_DefaultMode_from_RESET(void) {
|
||||
// $[Config Calls]
|
||||
CHIP_Init();
|
||||
|
||||
EMU_enter_DefaultMode_from_RESET();
|
||||
CMU_enter_DefaultMode_from_RESET();
|
||||
ADC0_enter_DefaultMode_from_RESET();
|
||||
USART0_enter_DefaultMode_from_RESET();
|
||||
USART1_enter_DefaultMode_from_RESET();
|
||||
TIMER0_enter_DefaultMode_from_RESET();
|
||||
CRYOTIMER_enter_DefaultMode_from_RESET();
|
||||
PORTIO_enter_DefaultMode_from_RESET();
|
||||
// [Config Calls]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// EMU_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void EMU_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[EMU Initialization]
|
||||
/* External power circuit not wired for DCDC; shut down regulator */
|
||||
EMU_DCDCPowerOff();
|
||||
/* Initialize EM2/EM3 mode */
|
||||
EMU_EM23Init_TypeDef em23Init = EMU_EM23INIT_DEFAULT;
|
||||
|
||||
em23Init.em23VregFullEn = 0;
|
||||
|
||||
EMU_EM23Init(&em23Init);
|
||||
/* Initialize EM4H/S mode */
|
||||
EMU_EM4Init_TypeDef em4Init = EMU_EM4INIT_DEFAULT;
|
||||
|
||||
em4Init.retainLfrco = 0;
|
||||
em4Init.retainLfxo = 0;
|
||||
em4Init.retainUlfrco = 0;
|
||||
em4Init.em4State = emuEM4Shutoff;
|
||||
em4Init.pinRetentionMode = emuPinRetentionDisable;
|
||||
|
||||
EMU_EM4Init(&em4Init);
|
||||
// [EMU Initialization]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// LFXO_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void LFXO_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// CMU_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void CMU_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[High Frequency Clock Setup]
|
||||
/* Initializing HFXO */
|
||||
CMU_HFXOInit_TypeDef hfxoInit = CMU_HFXOINIT_DEFAULT;
|
||||
|
||||
CMU_HFXOInit(&hfxoInit);
|
||||
|
||||
/* Setting system HFRCO frequency */
|
||||
CMU_HFRCOFreqSet (cmuHFRCOFreq_38M0Hz);
|
||||
|
||||
/* Using HFRCO as high frequency clock, HFCLK */
|
||||
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFRCO);
|
||||
// [High Frequency Clock Setup]$
|
||||
|
||||
// $[LE clocks enable]
|
||||
/* Enable ULFRCO oscillator, and wait for it to be stable */
|
||||
CMU_OscillatorEnable(cmuOsc_ULFRCO, true, true);
|
||||
|
||||
// [LE clocks enable]$
|
||||
|
||||
// $[LFACLK Setup]
|
||||
/* LFACLK is disabled */
|
||||
// [LFACLK Setup]$
|
||||
// $[LFBCLK Setup]
|
||||
/* LFBCLK is disabled */
|
||||
// [LFBCLK Setup]$
|
||||
// $[LFECLK Setup]
|
||||
/* LFECLK is disabled */
|
||||
// [LFECLK Setup]$
|
||||
// $[Peripheral Clock enables]
|
||||
/* Enable clock for HF peripherals */
|
||||
CMU_ClockEnable(cmuClock_HFPER, true);
|
||||
|
||||
/* Enable clock for ADC0 */
|
||||
CMU_ClockEnable(cmuClock_ADC0, true);
|
||||
|
||||
/* Enable clock for CRYOTIMER */
|
||||
CMU_ClockEnable(cmuClock_CRYOTIMER, true);
|
||||
|
||||
/* Enable clock for TIMER0 */
|
||||
CMU_ClockEnable(cmuClock_TIMER0, true);
|
||||
|
||||
/* Enable clock for USART0 */
|
||||
CMU_ClockEnable(cmuClock_USART0, true);
|
||||
|
||||
/* Enable clock for USART1 */
|
||||
CMU_ClockEnable(cmuClock_USART1, true);
|
||||
|
||||
/* Enable clock for GPIO by default */
|
||||
CMU_ClockEnable(cmuClock_GPIO, true);
|
||||
|
||||
// [Peripheral Clock enables]$
|
||||
|
||||
// $[Clock output]
|
||||
/* Disable CLKOUT0 output */
|
||||
CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_CLKOUTSEL0_MASK)
|
||||
| CMU_CTRL_CLKOUTSEL0_DISABLED;
|
||||
/* Disable CLKOUT1 output */
|
||||
CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_CLKOUTSEL1_MASK)
|
||||
| CMU_CTRL_CLKOUTSEL1_DISABLED;
|
||||
|
||||
// [Clock output]$
|
||||
|
||||
// $[CMU_IO]
|
||||
/* Disable CLKOUT0 pin */
|
||||
CMU->ROUTEPEN &= ~CMU_ROUTEPEN_CLKOUT0PEN;
|
||||
|
||||
/* Disable CLKOUT1 pin */
|
||||
CMU->ROUTEPEN &= ~CMU_ROUTEPEN_CLKOUT1PEN;
|
||||
|
||||
// [CMU_IO]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// ADC0_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void ADC0_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[ADC0_Init]
|
||||
ADC_Init_TypeDef ADC0_init = ADC_INIT_DEFAULT;
|
||||
|
||||
ADC0_init.ovsRateSel = adcOvsRateSel2;
|
||||
ADC0_init.warmUpMode = adcWarmupNormal;
|
||||
ADC0_init.timebase = ADC_TimebaseCalc(0);
|
||||
ADC0_init.prescale = ADC_PrescaleCalc(7000000, 0);
|
||||
ADC0_init.tailgate = 0;
|
||||
ADC0_init.em2ClockConfig = adcEm2Disabled;
|
||||
|
||||
ADC_Init(ADC0, &ADC0_init);
|
||||
// [ADC0_Init]$
|
||||
|
||||
// $[ADC0_InputConfiguration]
|
||||
// [ADC0_InputConfiguration]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// ACMP0_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void ACMP0_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[ACMP0_Init]
|
||||
// [ACMP0_Init]$
|
||||
|
||||
// $[ACMP0_IO]
|
||||
// [ACMP0_IO]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// ACMP1_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void ACMP1_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[ACMP1_Init]
|
||||
// [ACMP1_Init]$
|
||||
|
||||
// $[ACMP1_IO]
|
||||
// [ACMP1_IO]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// IDAC0_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void IDAC0_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// RTCC_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void RTCC_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[Compare/Capture Channel 0 init]
|
||||
// [Compare/Capture Channel 0 init]$
|
||||
|
||||
// $[Compare/Capture Channel 1 init]
|
||||
// [Compare/Capture Channel 1 init]$
|
||||
|
||||
// $[Compare/Capture Channel 2 init]
|
||||
// [Compare/Capture Channel 2 init]$
|
||||
|
||||
// $[RTCC init]
|
||||
// [RTCC init]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// USART0_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void USART0_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[USART_InitAsync]
|
||||
USART_InitAsync_TypeDef initasync = USART_INITASYNC_DEFAULT;
|
||||
|
||||
initasync.enable = usartDisable;
|
||||
initasync.baudrate = 115200;
|
||||
initasync.databits = usartDatabits8;
|
||||
initasync.parity = usartNoParity;
|
||||
initasync.stopbits = usartStopbits1;
|
||||
initasync.oversampling = usartOVS16;
|
||||
#if defined( USART_INPUT_RXPRS ) && defined( USART_CTRL_MVDIS )
|
||||
initasync.mvdis = 0;
|
||||
initasync.prsRxEnable = 0;
|
||||
initasync.prsRxCh = 0;
|
||||
#endif
|
||||
|
||||
USART_InitAsync(USART0, &initasync);
|
||||
// [USART_InitAsync]$
|
||||
|
||||
// $[USART_InitSync]
|
||||
// [USART_InitSync]$
|
||||
|
||||
// $[USART_InitPrsTrigger]
|
||||
USART_PrsTriggerInit_TypeDef initprs = USART_INITPRSTRIGGER_DEFAULT;
|
||||
|
||||
initprs.rxTriggerEnable = 0;
|
||||
initprs.txTriggerEnable = 0;
|
||||
initprs.prsTriggerChannel = usartPrsTriggerCh0;
|
||||
|
||||
USART_InitPrsTrigger(USART0, &initprs);
|
||||
// [USART_InitPrsTrigger]$
|
||||
|
||||
// $[USART_InitIO]
|
||||
/* Disable CLK pin */
|
||||
USART0->ROUTELOC0 = (USART0->ROUTELOC0 & (~_USART_ROUTELOC0_CLKLOC_MASK))
|
||||
| USART_ROUTELOC0_CLKLOC_LOC4;
|
||||
USART0->ROUTEPEN = USART0->ROUTEPEN & (~USART_ROUTEPEN_CLKPEN);
|
||||
|
||||
/* Disable CS pin */
|
||||
USART0->ROUTELOC0 = (USART0->ROUTELOC0 & (~_USART_ROUTELOC0_CSLOC_MASK))
|
||||
| USART_ROUTELOC0_CSLOC_LOC3;
|
||||
USART0->ROUTEPEN = USART0->ROUTEPEN & (~USART_ROUTEPEN_CSPEN);
|
||||
|
||||
/* Disable CTS pin */
|
||||
USART0->ROUTELOC1 = (USART0->ROUTELOC1 & (~_USART_ROUTELOC1_CTSLOC_MASK))
|
||||
| USART_ROUTELOC1_CTSLOC_LOC2;
|
||||
USART0->ROUTEPEN = USART0->ROUTEPEN & (~USART_ROUTEPEN_CTSPEN);
|
||||
|
||||
/* Disable RTS pin */
|
||||
USART0->ROUTELOC1 = (USART0->ROUTELOC1 & (~_USART_ROUTELOC1_RTSLOC_MASK))
|
||||
| USART_ROUTELOC1_RTSLOC_LOC1;
|
||||
USART0->ROUTEPEN = USART0->ROUTEPEN & (~USART_ROUTEPEN_RTSPEN);
|
||||
|
||||
/* Set up RX pin */
|
||||
USART0->ROUTELOC0 = (USART0->ROUTELOC0 & (~_USART_ROUTELOC0_RXLOC_MASK))
|
||||
| USART_ROUTELOC0_RXLOC_LOC0;
|
||||
USART0->ROUTEPEN = USART0->ROUTEPEN | USART_ROUTEPEN_RXPEN;
|
||||
|
||||
/* Set up TX pin */
|
||||
USART0->ROUTELOC0 = (USART0->ROUTELOC0 & (~_USART_ROUTELOC0_TXLOC_MASK))
|
||||
| USART_ROUTELOC0_TXLOC_LOC20;
|
||||
USART0->ROUTEPEN = USART0->ROUTEPEN | USART_ROUTEPEN_TXPEN;
|
||||
|
||||
// [USART_InitIO]$
|
||||
|
||||
// $[USART_Misc]
|
||||
/* Disable CTS */
|
||||
USART0->CTRLX = USART0->CTRLX & (~USART_CTRLX_CTSEN);
|
||||
/* Set CTS active low */
|
||||
USART0->CTRLX = USART0->CTRLX & (~USART_CTRLX_CTSINV);
|
||||
/* Set RTS active low */
|
||||
USART0->CTRLX = USART0->CTRLX & (~USART_CTRLX_RTSINV);
|
||||
/* Set CS active low */
|
||||
USART0->CTRL = USART0->CTRL & (~USART_CTRL_CSINV);
|
||||
/* Set TX active high */
|
||||
USART0->CTRL = USART0->CTRL & (~USART_CTRL_TXINV);
|
||||
/* Set RX active high */
|
||||
USART0->CTRL = USART0->CTRL & (~USART_CTRL_RXINV);
|
||||
// [USART_Misc]$
|
||||
|
||||
// $[USART_Enable]
|
||||
|
||||
/* Enable USART if opted by user */
|
||||
USART_Enable(USART0, usartEnable);
|
||||
// [USART_Enable]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// USART1_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void USART1_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[USART_InitAsync]
|
||||
// [USART_InitAsync]$
|
||||
|
||||
// $[USART_InitSync]
|
||||
USART_InitSync_TypeDef initsync = USART_INITSYNC_DEFAULT;
|
||||
|
||||
initsync.enable = usartDisable;
|
||||
initsync.baudrate = 130000;
|
||||
initsync.databits = usartDatabits8;
|
||||
initsync.master = 1;
|
||||
initsync.msbf = 1;
|
||||
initsync.clockMode = usartClockMode0;
|
||||
#if defined( USART_INPUT_RXPRS ) && defined( USART_TRIGCTRL_AUTOTXTEN )
|
||||
initsync.prsRxEnable = 0;
|
||||
initsync.prsRxCh = 0;
|
||||
initsync.autoTx = 0;
|
||||
#endif
|
||||
|
||||
USART_InitSync(USART1, &initsync);
|
||||
// [USART_InitSync]$
|
||||
|
||||
// $[USART_InitPrsTrigger]
|
||||
USART_PrsTriggerInit_TypeDef initprs = USART_INITPRSTRIGGER_DEFAULT;
|
||||
|
||||
initprs.rxTriggerEnable = 0;
|
||||
initprs.txTriggerEnable = 0;
|
||||
initprs.prsTriggerChannel = usartPrsTriggerCh0;
|
||||
|
||||
USART_InitPrsTrigger(USART1, &initprs);
|
||||
// [USART_InitPrsTrigger]$
|
||||
|
||||
// $[USART_InitIO]
|
||||
/* Set up CLK pin */
|
||||
USART1->ROUTELOC0 = (USART1->ROUTELOC0 & (~_USART_ROUTELOC0_CLKLOC_MASK))
|
||||
| USART_ROUTELOC0_CLKLOC_LOC4;
|
||||
USART1->ROUTEPEN = USART1->ROUTEPEN | USART_ROUTEPEN_CLKPEN;
|
||||
|
||||
/* Disable CS pin */
|
||||
USART1->ROUTELOC0 = (USART1->ROUTELOC0 & (~_USART_ROUTELOC0_CSLOC_MASK))
|
||||
| USART_ROUTELOC0_CSLOC_LOC3;
|
||||
USART1->ROUTEPEN = USART1->ROUTEPEN & (~USART_ROUTEPEN_CSPEN);
|
||||
|
||||
/* Disable CTS pin */
|
||||
USART1->ROUTELOC1 = (USART1->ROUTELOC1 & (~_USART_ROUTELOC1_CTSLOC_MASK))
|
||||
| USART_ROUTELOC1_CTSLOC_LOC2;
|
||||
USART1->ROUTEPEN = USART1->ROUTEPEN & (~USART_ROUTEPEN_CTSPEN);
|
||||
|
||||
/* Disable RTS pin */
|
||||
USART1->ROUTELOC1 = (USART1->ROUTELOC1 & (~_USART_ROUTELOC1_RTSLOC_MASK))
|
||||
| USART_ROUTELOC1_RTSLOC_LOC1;
|
||||
USART1->ROUTEPEN = USART1->ROUTEPEN & (~USART_ROUTEPEN_RTSPEN);
|
||||
|
||||
/* Set up RX pin */
|
||||
USART1->ROUTELOC0 = (USART1->ROUTELOC0 & (~_USART_ROUTELOC0_RXLOC_MASK))
|
||||
| USART_ROUTELOC0_RXLOC_LOC6;
|
||||
USART1->ROUTEPEN = USART1->ROUTEPEN | USART_ROUTEPEN_RXPEN;
|
||||
|
||||
/* Set up TX pin */
|
||||
USART1->ROUTELOC0 = (USART1->ROUTELOC0 & (~_USART_ROUTELOC0_TXLOC_MASK))
|
||||
| USART_ROUTELOC0_TXLOC_LOC8;
|
||||
USART1->ROUTEPEN = USART1->ROUTEPEN | USART_ROUTEPEN_TXPEN;
|
||||
|
||||
// [USART_InitIO]$
|
||||
|
||||
// $[USART_Misc]
|
||||
/* Disable CTS */
|
||||
USART1->CTRLX = USART1->CTRLX & (~USART_CTRLX_CTSEN);
|
||||
/* Set CTS active low */
|
||||
USART1->CTRLX = USART1->CTRLX & (~USART_CTRLX_CTSINV);
|
||||
/* Set RTS active low */
|
||||
USART1->CTRLX = USART1->CTRLX & (~USART_CTRLX_RTSINV);
|
||||
/* Set CS active low */
|
||||
USART1->CTRL = USART1->CTRL & (~USART_CTRL_CSINV);
|
||||
/* Set TX active high */
|
||||
USART1->CTRL = USART1->CTRL & (~USART_CTRL_TXINV);
|
||||
/* Set RX active high */
|
||||
USART1->CTRL = USART1->CTRL & (~USART_CTRL_RXINV);
|
||||
// [USART_Misc]$
|
||||
|
||||
// $[USART_Enable]
|
||||
|
||||
/* Enable USART if opted by user */
|
||||
USART_Enable(USART1, usartEnable);
|
||||
// [USART_Enable]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// LEUART0_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void LEUART0_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[LEUART0 initialization]
|
||||
// [LEUART0 initialization]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// WDOG0_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void WDOG0_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[WDOG Initialization]
|
||||
// [WDOG Initialization]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// I2C0_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void I2C0_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[I2C0 I/O setup]
|
||||
// [I2C0 I/O setup]$
|
||||
|
||||
// $[I2C0 initialization]
|
||||
// [I2C0 initialization]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// GPCRC_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void GPCRC_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// LDMA_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void LDMA_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// TIMER0_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void TIMER0_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[TIMER0 I/O setup]
|
||||
/* Set up CC0 */
|
||||
TIMER0->ROUTELOC0 = (TIMER0->ROUTELOC0 & (~_TIMER_ROUTELOC0_CC0LOC_MASK))
|
||||
| TIMER_ROUTELOC0_CC0LOC_LOC18;
|
||||
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN | TIMER_ROUTEPEN_CC0PEN;
|
||||
/* Set up CC1 */
|
||||
TIMER0->ROUTELOC0 = (TIMER0->ROUTELOC0 & (~_TIMER_ROUTELOC0_CC1LOC_MASK))
|
||||
| TIMER_ROUTELOC0_CC1LOC_LOC16;
|
||||
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN | TIMER_ROUTEPEN_CC1PEN;
|
||||
/* Set up CC2 */
|
||||
TIMER0->ROUTELOC0 = (TIMER0->ROUTELOC0 & (~_TIMER_ROUTELOC0_CC2LOC_MASK))
|
||||
| TIMER_ROUTELOC0_CC2LOC_LOC20;
|
||||
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN | TIMER_ROUTEPEN_CC2PEN;
|
||||
/* Set up CDTI0 */
|
||||
TIMER0->ROUTELOC2 = (TIMER0->ROUTELOC2 & (~_TIMER_ROUTELOC2_CDTI0LOC_MASK))
|
||||
| TIMER_ROUTELOC2_CDTI0LOC_LOC3;
|
||||
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN & (~TIMER_ROUTEPEN_CDTI0PEN);
|
||||
/* Set up CDTI1 */
|
||||
TIMER0->ROUTELOC2 = (TIMER0->ROUTELOC2 & (~_TIMER_ROUTELOC2_CDTI1LOC_MASK))
|
||||
| TIMER_ROUTELOC2_CDTI1LOC_LOC2;
|
||||
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN & (~TIMER_ROUTEPEN_CDTI1PEN);
|
||||
/* Set up CDTI2 */
|
||||
TIMER0->ROUTELOC2 = (TIMER0->ROUTELOC2 & (~_TIMER_ROUTELOC2_CDTI2LOC_MASK))
|
||||
| TIMER_ROUTELOC2_CDTI2LOC_LOC1;
|
||||
TIMER0->ROUTEPEN = TIMER0->ROUTEPEN & (~TIMER_ROUTEPEN_CDTI2PEN);
|
||||
// [TIMER0 I/O setup]$
|
||||
|
||||
// $[TIMER0 initialization]
|
||||
TIMER_Init_TypeDef init = TIMER_INIT_DEFAULT;
|
||||
|
||||
init.enable = 1;
|
||||
init.debugRun = 0;
|
||||
init.dmaClrAct = 0;
|
||||
init.sync = 0;
|
||||
init.clkSel = timerClkSelHFPerClk;
|
||||
init.prescale = timerPrescale512;
|
||||
init.fallAction = timerInputActionNone;
|
||||
init.riseAction = timerInputActionNone;
|
||||
init.mode = timerModeUp;
|
||||
init.quadModeX4 = 0;
|
||||
init.oneShot = 0;
|
||||
init.count2x = 0;
|
||||
init.ati = 0;
|
||||
TIMER_Init(TIMER0, &init);
|
||||
// [TIMER0 initialization]$
|
||||
|
||||
// $[TIMER0 CC0 init]
|
||||
TIMER_InitCC_TypeDef initCC0 = TIMER_INITCC_DEFAULT;
|
||||
|
||||
initCC0.prsInput = false;
|
||||
initCC0.prsSel = timerPRSSELCh0;
|
||||
initCC0.edge = timerEdgeRising;
|
||||
initCC0.mode = timerCCModePWM;
|
||||
initCC0.eventCtrl = timerEventEveryEdge;
|
||||
initCC0.filter = 0;
|
||||
initCC0.cofoa = timerOutputActionNone;
|
||||
initCC0.cufoa = timerOutputActionNone;
|
||||
initCC0.cmoa = timerOutputActionToggle;
|
||||
initCC0.coist = 0;
|
||||
initCC0.outInvert = 0;
|
||||
TIMER_InitCC(TIMER0, 0, &initCC0);
|
||||
// [TIMER0 CC0 init]$
|
||||
|
||||
// $[TIMER0 CC1 init]
|
||||
TIMER_InitCC_TypeDef initCC1 = TIMER_INITCC_DEFAULT;
|
||||
|
||||
initCC1.prsInput = false;
|
||||
initCC1.prsSel = timerPRSSELCh0;
|
||||
initCC1.edge = timerEdgeRising;
|
||||
initCC1.mode = timerCCModePWM;
|
||||
initCC1.eventCtrl = timerEventEveryEdge;
|
||||
initCC1.filter = 0;
|
||||
initCC1.cofoa = timerOutputActionNone;
|
||||
initCC1.cufoa = timerOutputActionNone;
|
||||
initCC1.cmoa = timerOutputActionToggle;
|
||||
initCC1.coist = 0;
|
||||
initCC1.outInvert = 0;
|
||||
TIMER_InitCC(TIMER0, 1, &initCC1);
|
||||
// [TIMER0 CC1 init]$
|
||||
|
||||
// $[TIMER0 CC2 init]
|
||||
TIMER_InitCC_TypeDef initCC2 = TIMER_INITCC_DEFAULT;
|
||||
|
||||
initCC2.prsInput = false;
|
||||
initCC2.prsSel = timerPRSSELCh0;
|
||||
initCC2.edge = timerEdgeRising;
|
||||
initCC2.mode = timerCCModePWM;
|
||||
initCC2.eventCtrl = timerEventEveryEdge;
|
||||
initCC2.filter = 0;
|
||||
initCC2.cofoa = timerOutputActionNone;
|
||||
initCC2.cufoa = timerOutputActionNone;
|
||||
initCC2.cmoa = timerOutputActionToggle;
|
||||
initCC2.coist = 0;
|
||||
initCC2.outInvert = 0;
|
||||
TIMER_InitCC(TIMER0, 2, &initCC2);
|
||||
// [TIMER0 CC2 init]$
|
||||
|
||||
// $[TIMER0 DTI init]
|
||||
TIMER_InitDTI_TypeDef initDTI = TIMER_INITDTI_DEFAULT;
|
||||
|
||||
initDTI.enable = 0;
|
||||
initDTI.activeLowOut = 0;
|
||||
initDTI.invertComplementaryOut = 0;
|
||||
initDTI.autoRestart = 0;
|
||||
initDTI.enablePrsSource = 0;
|
||||
initDTI.prsSel = timerPRSSELCh0;
|
||||
initDTI.prescale = timerPrescale1;
|
||||
initDTI.riseTime = 1;
|
||||
initDTI.fallTime = 1;
|
||||
initDTI.enableFaultSourceCoreLockup = 1;
|
||||
initDTI.enableFaultSourceDebugger = 1;
|
||||
initDTI.faultSourcePrsSel0 = 0;
|
||||
initDTI.faultSourcePrsSel0 = timerPRSSELCh0;
|
||||
initDTI.faultSourcePrsSel1 = 0;
|
||||
initDTI.faultSourcePrsSel1 = timerPRSSELCh0;
|
||||
initDTI.faultAction = timerDtiFaultActionInactive;
|
||||
initDTI.outputsEnableMask = 0 | TIMER_DTOGEN_DTOGCC0EN
|
||||
| TIMER_DTOGEN_DTOGCC1EN | TIMER_DTOGEN_DTOGCC2EN;
|
||||
TIMER_InitDTI(TIMER0, &initDTI);
|
||||
// [TIMER0 DTI init]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// TIMER1_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void TIMER1_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[TIMER1 I/O setup]
|
||||
// [TIMER1 I/O setup]$
|
||||
|
||||
// $[TIMER1 initialization]
|
||||
// [TIMER1 initialization]$
|
||||
|
||||
// $[TIMER1 CC0 init]
|
||||
// [TIMER1 CC0 init]$
|
||||
|
||||
// $[TIMER1 CC1 init]
|
||||
// [TIMER1 CC1 init]$
|
||||
|
||||
// $[TIMER1 CC2 init]
|
||||
// [TIMER1 CC2 init]$
|
||||
|
||||
// $[TIMER1 CC3 init]
|
||||
// [TIMER1 CC3 init]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// LETIMER0_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void LETIMER0_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[LETIMER0 Compare Values]
|
||||
// [LETIMER0 Compare Values]$
|
||||
|
||||
// $[LETIMER0 Repeat Values]
|
||||
// [LETIMER0 Repeat Values]$
|
||||
|
||||
// $[LETIMER0 Initialization]
|
||||
// [LETIMER0 Initialization]$
|
||||
|
||||
// $[LETIMER0 PRS Input Triggers]
|
||||
// [LETIMER0 PRS Input Triggers]$
|
||||
|
||||
// $[LETIMER0 I/O setup]
|
||||
// [LETIMER0 I/O setup]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// CRYOTIMER_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void CRYOTIMER_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[CRYOTIMER_Init]
|
||||
CRYOTIMER_Init_TypeDef cryoInit = CRYOTIMER_INIT_DEFAULT;
|
||||
|
||||
/* General settings */
|
||||
cryoInit.enable = 1;
|
||||
cryoInit.debugRun = 0;
|
||||
cryoInit.em4Wakeup = 0;
|
||||
|
||||
/* Clocking settings */
|
||||
/* With a frequency of 1000Hz on ULFRCO, this will result in a 1.00 ms timeout */
|
||||
cryoInit.osc = cryotimerOscULFRCO;
|
||||
cryoInit.presc = cryotimerPresc_1;
|
||||
cryoInit.period = cryotimerPeriod_1;
|
||||
CRYOTIMER_Init(&cryoInit);
|
||||
// [CRYOTIMER_Init]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// PCNT0_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void PCNT0_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[PCNT0 I/O setup]
|
||||
// [PCNT0 I/O setup]$
|
||||
|
||||
// $[PCNT0 initialization]
|
||||
// [PCNT0 initialization]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// PRS_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void PRS_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[PRS initialization]
|
||||
// [PRS initialization]$
|
||||
|
||||
}
|
||||
|
||||
//================================================================================
|
||||
// PORTIO_enter_DefaultMode_from_RESET
|
||||
//================================================================================
|
||||
extern void PORTIO_enter_DefaultMode_from_RESET(void) {
|
||||
|
||||
// $[Port A Configuration]
|
||||
|
||||
/* Pin PA0 is configured to Input enabled */
|
||||
GPIO_PinModeSet(gpioPortA, 0, gpioModeInput, 0);
|
||||
|
||||
/* Pin PA1 is configured to Input enabled */
|
||||
GPIO_PinModeSet(gpioPortA, 1, gpioModeInput, 0);
|
||||
// [Port A Configuration]$
|
||||
|
||||
// $[Port B Configuration]
|
||||
|
||||
/* Pin PB11 is configured to Push-pull */
|
||||
GPIO_PinModeSet(gpioPortB, 11, gpioModePushPull, 1);
|
||||
|
||||
/* Pin PB12 is configured to Input enabled with pull-up */
|
||||
GPIO_PinModeSet(gpioPortB, 12, gpioModeInputPull, 1);
|
||||
|
||||
/* Pin PB13 is configured to Push-pull */
|
||||
GPIO_PinModeSet(gpioPortB, 13, gpioModePushPull, 1);
|
||||
|
||||
/* Pin PB15 is configured to Push-pull */
|
||||
GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 1);
|
||||
// [Port B Configuration]$
|
||||
|
||||
// $[Port C Configuration]
|
||||
// [Port C Configuration]$
|
||||
|
||||
// $[Port D Configuration]
|
||||
|
||||
/* Pin PD9 is configured to Push-pull */
|
||||
GPIO_PinModeSet(gpioPortD, 9, gpioModePushPull, 1);
|
||||
|
||||
/* Pin PD10 is configured to Push-pull */
|
||||
GPIO_PinModeSet(gpioPortD, 10, gpioModePushPull, 1);
|
||||
|
||||
/* Pin PD11 is configured to Input enabled with pull-up */
|
||||
GPIO_PinModeSet(gpioPortD, 11, gpioModeInputPull, 1);
|
||||
|
||||
/* Pin PD12 is configured to Push-pull */
|
||||
GPIO_PinModeSet(gpioPortD, 12, gpioModePushPull, 1);
|
||||
|
||||
/* Pin PD13 is configured to Input enabled with pull-up */
|
||||
GPIO_PinModeSet(gpioPortD, 13, gpioModeInputPull, 1);
|
||||
|
||||
/* Pin PD14 is configured to Push-pull */
|
||||
GPIO_PinModeSet(gpioPortD, 14, gpioModePushPull, 1);
|
||||
|
||||
/* Pin PD15 is configured to Push-pull */
|
||||
GPIO_PinModeSet(gpioPortD, 15, gpioModePushPull, 1);
|
||||
// [Port D Configuration]$
|
||||
|
||||
// $[Port E Configuration]
|
||||
// [Port E Configuration]$
|
||||
|
||||
// $[Port F Configuration]
|
||||
// [Port F Configuration]$
|
||||
|
||||
}
|
||||
|
@ -1,689 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
/*
|
||||
* Wrapper for crypto implementation on device
|
||||
*
|
||||
* */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "em_adc.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "crypto.h"
|
||||
#include "device.h"
|
||||
|
||||
|
||||
#include "sha256.h"
|
||||
#include "uECC.h"
|
||||
#include "aes.h"
|
||||
#include "ctap.h"
|
||||
#include "log.h"
|
||||
|
||||
#include MBEDTLS_CONFIG_FILE
|
||||
#include "sha256_alt.h"
|
||||
#include "mbedtls/ctr_drbg.h"
|
||||
#include "mbedtls/ecdsa.h"
|
||||
|
||||
const uint8_t attestation_cert_der[];
|
||||
const uint16_t attestation_cert_der_size;
|
||||
const uint8_t attestation_key[];
|
||||
const uint16_t attestation_key_size;
|
||||
|
||||
|
||||
static mbedtls_sha256_context embed_sha256_ctx;
|
||||
static mbedtls_ctr_drbg_context ctr_drbg;
|
||||
|
||||
static const struct uECC_Curve_t * _es256_curve = NULL;
|
||||
static const uint8_t * _signing_key = NULL;
|
||||
static int _key_len = 0;
|
||||
|
||||
// Secrets for testing only
|
||||
static uint8_t master_secret[32] = "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff"
|
||||
"\xff\xee\xdd\xcc\xbb\xaa\x99\x88\x77\x66\x55\x44\x33\x22\x11\x00";
|
||||
|
||||
static uint8_t transport_secret[32] = "\x10\x01\x22\x33\x44\x55\x66\x77\x87\x90\x0a\xbb\x3c\xd8\xee\xff"
|
||||
"\xff\xee\x8d\x1c\x3b\xfa\x99\x88\x77\x86\x55\x44\xd3\xff\x33\x00";
|
||||
|
||||
|
||||
|
||||
void crypto_sha256_init()
|
||||
{
|
||||
mbedtls_sha256_init( &embed_sha256_ctx );
|
||||
mbedtls_sha256_starts(&embed_sha256_ctx,0);
|
||||
// sha256_init(&sha256_ctx);
|
||||
}
|
||||
|
||||
void crypto_reset_master_secret()
|
||||
{
|
||||
ctap_generate_rng(master_secret, 32);
|
||||
}
|
||||
|
||||
|
||||
void crypto_sha256_update(uint8_t * data, size_t len)
|
||||
{
|
||||
mbedtls_sha256_update(&embed_sha256_ctx,data,len);
|
||||
// sha256_update(&sha256_ctx, data, len);
|
||||
}
|
||||
|
||||
void crypto_sha256_update_secret()
|
||||
{
|
||||
mbedtls_sha256_update(&embed_sha256_ctx,master_secret,32);
|
||||
// sha256_update(&sha256_ctx, master_secret, 32);
|
||||
}
|
||||
|
||||
void crypto_sha256_final(uint8_t * hash)
|
||||
{
|
||||
mbedtls_sha256_finish( &embed_sha256_ctx, hash );
|
||||
// sha256_final(&sha256_ctx, hash);
|
||||
}
|
||||
|
||||
void crypto_sha256_hmac_init(uint8_t * key, uint32_t klen, uint8_t * hmac)
|
||||
{
|
||||
uint8_t buf[64];
|
||||
int i;
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
if (key == CRYPTO_MASTER_KEY)
|
||||
{
|
||||
key = master_secret;
|
||||
klen = sizeof(master_secret);
|
||||
}
|
||||
|
||||
if(klen > 64)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, key size must be <= 64\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memmove(buf, key, klen);
|
||||
|
||||
for (i = 0; i < sizeof(buf); i++)
|
||||
{
|
||||
buf[i] = buf[i] ^ 0x36;
|
||||
}
|
||||
|
||||
crypto_sha256_init();
|
||||
crypto_sha256_update(buf, 64);
|
||||
}
|
||||
|
||||
void crypto_sha256_hmac_final(uint8_t * key, uint32_t klen, uint8_t * hmac)
|
||||
{
|
||||
uint8_t buf[64];
|
||||
int i;
|
||||
crypto_sha256_final(hmac);
|
||||
memset(buf, 0, sizeof(buf));
|
||||
if (key == CRYPTO_MASTER_KEY)
|
||||
{
|
||||
key = master_secret;
|
||||
klen = sizeof(master_secret);
|
||||
}
|
||||
|
||||
|
||||
if(klen > 64)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, key size must be <= 64\n");
|
||||
exit(1);
|
||||
}
|
||||
memmove(buf, key, klen);
|
||||
|
||||
for (i = 0; i < sizeof(buf); i++)
|
||||
{
|
||||
buf[i] = buf[i] ^ 0x5c;
|
||||
}
|
||||
|
||||
crypto_sha256_init();
|
||||
crypto_sha256_update(buf, 64);
|
||||
crypto_sha256_update(hmac, 32);
|
||||
crypto_sha256_final(hmac);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
uint8_t adc_rng(void)
|
||||
{
|
||||
int i;
|
||||
uint8_t random = 0;
|
||||
|
||||
/* Random number generation */
|
||||
for (i=0; i<3; i++)
|
||||
{
|
||||
ADC_Start(ADC0, adcStartSingle);
|
||||
while ((ADC0->IF & ADC_IF_SINGLE) == 0);
|
||||
random |= ((ADC_DataSingleGet(ADC0) & 0x07) << (i * 3));
|
||||
}
|
||||
|
||||
return random;
|
||||
}
|
||||
|
||||
// Generate @num bytes of random numbers to @dest
|
||||
// return 1 if success, error otherwise
|
||||
int ctap_generate_rng(uint8_t * dst, size_t num)
|
||||
{
|
||||
return mbedtls_ctr_drbg_random(&ctr_drbg,dst,num) == 0;
|
||||
}
|
||||
|
||||
int adc_entropy_func( void *data, unsigned char *output, size_t len )
|
||||
{
|
||||
while(len--)
|
||||
*output++ = adc_rng();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void crypto_ecc256_init()
|
||||
{
|
||||
uECC_set_rng((uECC_RNG_Function)ctap_generate_rng);
|
||||
_es256_curve = uECC_secp256r1();
|
||||
mbedtls_ctr_drbg_init(&ctr_drbg);
|
||||
|
||||
if ( mbedtls_ctr_drbg_seed(&ctr_drbg, adc_entropy_func, NULL,
|
||||
master_secret,32 ) != 0 ) {
|
||||
printf2(TAG_ERR, "mbedtls_ctr_drbg_seed failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void crypto_load_external_key(uint8_t * key, int len)
|
||||
{
|
||||
_signing_key = key;
|
||||
_key_len = len;
|
||||
}
|
||||
void crypto_ecc256_load_attestation_key()
|
||||
{
|
||||
_signing_key = attestation_key;
|
||||
_key_len = 32;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* \brief Import a point from unsigned binary data
|
||||
*
|
||||
* \param grp Group to which the point should belong
|
||||
* \param P Point to import
|
||||
* \param buf Input buffer
|
||||
* \param ilen Actual length of input
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* MBEDTLS_ERR_ECP_BAD_INPUT_DATA if input is invalid,
|
||||
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed,
|
||||
* MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE if the point format
|
||||
* is not implemented.
|
||||
*
|
||||
* \note This function does NOT check that the point actually
|
||||
* belongs to the given group, see mbedtls_ecp_check_pubkey() for
|
||||
* that.
|
||||
*/
|
||||
//int mbedtls_ecp_point_read_binary( const mbedtls_ecp_group *grp, mbedtls_ecp_point *P,
|
||||
// const unsigned char *buf, size_t ilen );
|
||||
|
||||
/**
|
||||
* \brief Import X from unsigned binary data, big endian
|
||||
*
|
||||
* \param X Destination MPI
|
||||
* \param buf Input buffer
|
||||
* \param buflen Input buffer size
|
||||
*
|
||||
* \return 0 if successful,
|
||||
* MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed
|
||||
*/
|
||||
//int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen );
|
||||
|
||||
/*
|
||||
* Set context from an mbedtls_ecp_keypair
|
||||
*/
|
||||
//int mbedtls_ecdsa_from_keypair( mbedtls_ecdsa_context *ctx, const mbedtls_ecp_keypair *key );
|
||||
|
||||
|
||||
|
||||
void crypto_ecc256_sign(uint8_t * data, int len, uint8_t * sig)
|
||||
{
|
||||
mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
|
||||
mbedtls_mpi d; /*!< our secret value */
|
||||
//#define CRYPTO_ENABLE CMU->HFBUSCLKEN0 |= CMU_HFBUSCLKEN0_CRYPTO; \
|
||||
// CRYPTO->IFC = _CRYPTO_IFC_MASK; \
|
||||
// CRYPTO->CMD = CRYPTO_CMD_SEQSTOP; \
|
||||
// CRYPTO->CTRL = CRYPTO_CTRL_DMA0RSEL_DDATA0; \
|
||||
// CRYPTO->SEQCTRL = 0; \
|
||||
// CRYPTO->SEQCTRLB = 0
|
||||
//
|
||||
//#define CRYPTO_DISABLE \
|
||||
// CRYPTO->IEN = 0; \
|
||||
// CMU->HFBUSCLKEN0 &= ~CMU_HFBUSCLKEN0_CRYPTO;
|
||||
// CRYPTO_DISABLE;
|
||||
// CRYPTO_ENABLE;
|
||||
// mbedtls_ecp_group_init( &grp );
|
||||
// mbedtls_mpi_init( &d );
|
||||
// mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
|
||||
// mbedtls_mpi_read_binary(&d, _signing_key, 32);
|
||||
//
|
||||
// mbedtls_mpi r,s;
|
||||
// mbedtls_mpi_init(&r);
|
||||
// mbedtls_mpi_init(&s);
|
||||
//
|
||||
// printf("signing..\n");
|
||||
// dump_hex(data,len);
|
||||
// mbedtls_ecdsa_sign_det( &grp, &r, &s, &d,
|
||||
// data, 32, MBEDTLS_MD_SHA256 );// Issue: this will freeze on 13th iteration..
|
||||
// printf("signed\n");
|
||||
//
|
||||
// mbedtls_mpi_write_binary(&r,sig,32);
|
||||
// mbedtls_mpi_write_binary(&s,sig+32,32);
|
||||
|
||||
if ( uECC_sign(_signing_key, data, len, sig, _es256_curve) == 0)
|
||||
{
|
||||
printf2(TAG_ERR,"error, uECC failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if 1
|
||||
void crypto_ecdsa_sign(uint8_t * data, int len, uint8_t * sig, int MBEDTLS_ECP_ID)
|
||||
{
|
||||
|
||||
const struct uECC_Curve_t * curve = NULL;
|
||||
|
||||
switch(MBEDTLS_ECP_ID)
|
||||
{
|
||||
case MBEDTLS_ECP_DP_SECP192R1:
|
||||
curve = uECC_secp192r1();
|
||||
if (_key_len != 24) goto fail;
|
||||
break;
|
||||
case MBEDTLS_ECP_DP_SECP224R1:
|
||||
curve = uECC_secp224r1();
|
||||
if (_key_len != 28) goto fail;
|
||||
break;
|
||||
case MBEDTLS_ECP_DP_SECP256R1:
|
||||
curve = uECC_secp256r1();
|
||||
if (_key_len != 32) goto fail;
|
||||
break;
|
||||
case MBEDTLS_ECP_DP_SECP256K1:
|
||||
curve = uECC_secp256k1();
|
||||
if (_key_len != 32) goto fail;
|
||||
break;
|
||||
default:
|
||||
printf2(TAG_ERR,"error, invalid ECDSA alg specifier\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( uECC_sign(_signing_key, data, len, sig, curve) == 0)
|
||||
{
|
||||
printf2(TAG_ERR,"error, uECC failed\n");
|
||||
exit(1);
|
||||
}
|
||||
return;
|
||||
|
||||
fail:
|
||||
printf2(TAG_ERR,"error, invalid key length: %d\n", _key_len);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#else
|
||||
void crypto_ecdsa_sign(uint8_t * data, int len, uint8_t * sig, int MBEDTLS_ECP_ID)
|
||||
{
|
||||
mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
|
||||
mbedtls_mpi d; /*!< our secret value */
|
||||
|
||||
mbedtls_ecp_group_init( &grp );
|
||||
mbedtls_mpi_init( &d );
|
||||
mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_ID);
|
||||
mbedtls_mpi_read_binary(&d, _signing_key, 32);
|
||||
|
||||
mbedtls_mpi r,s;
|
||||
mbedtls_mpi_init(&r);
|
||||
mbedtls_mpi_init(&s);
|
||||
|
||||
printf("signing..\n");
|
||||
dump_hex(data,len);
|
||||
mbedtls_ecdsa_sign_det( &grp, &r, &s, &d,
|
||||
data, 32, MBEDTLS_MD_SHA256 );// Issue: this will freeze on 13th iteration..
|
||||
printf("signed\n");
|
||||
|
||||
mbedtls_mpi_write_binary(&r,sig,32);
|
||||
mbedtls_mpi_write_binary(&s,sig+32,32);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
* Generate a keypair with configurable base point
|
||||
*/
|
||||
// mbedtls_ecp_gen_keypair( &ctx->grp, &ctx->d, &ctx->Q, f_rng, p_rng )
|
||||
// mbedtls_ecp_gen_keypair_base( grp, &grp->G, d, Q, f_rng, p_rng )
|
||||
/*
|
||||
* Curve types: internal for now, might be exposed later
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECP_TYPE_NONE = 0,
|
||||
ECP_TYPE_SHORT_WEIERSTRASS, /* y^2 = x^3 + a x + b */
|
||||
ECP_TYPE_MONTGOMERY, /* y^2 = x^3 + a x^2 + x */
|
||||
} ecp_curve_type;
|
||||
/*
|
||||
* Get the type of a curve
|
||||
*/
|
||||
static inline ecp_curve_type ecp_get_type( const mbedtls_ecp_group *grp )
|
||||
{
|
||||
if( grp->G.X.p == NULL )
|
||||
return( ECP_TYPE_NONE );
|
||||
|
||||
if( grp->G.Y.p == NULL )
|
||||
return( ECP_TYPE_MONTGOMERY );
|
||||
else
|
||||
return( ECP_TYPE_SHORT_WEIERSTRASS );
|
||||
}
|
||||
static int mbedtls_ecp_gen_privkey( mbedtls_ecp_group *grp,
|
||||
const mbedtls_ecp_point *G,
|
||||
mbedtls_mpi *d, mbedtls_ecp_point *Q,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
int ret;
|
||||
size_t n_size = ( grp->nbits + 7 ) / 8;
|
||||
|
||||
#if defined(ECP_MONTGOMERY)
|
||||
if( ecp_get_type( grp ) == ECP_TYPE_MONTGOMERY )
|
||||
{
|
||||
/* [M225] page 5 */
|
||||
size_t b;
|
||||
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( d, n_size, f_rng, p_rng ) );
|
||||
|
||||
/* Make sure the most significant bit is nbits */
|
||||
b = mbedtls_mpi_bitlen( d ) - 1; /* mbedtls_mpi_bitlen is one-based */
|
||||
if( b > grp->nbits )
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, b - grp->nbits ) );
|
||||
else
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, grp->nbits, 1 ) );
|
||||
|
||||
/* Make sure the last three bits are unset */
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 0, 0 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 1, 0 ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_set_bit( d, 2, 0 ) );
|
||||
}
|
||||
else
|
||||
#endif /* ECP_MONTGOMERY */
|
||||
#if defined(ECP_SHORTWEIERSTRASS)
|
||||
if( ecp_get_type( grp ) == ECP_TYPE_SHORT_WEIERSTRASS )
|
||||
{
|
||||
/* SEC1 3.2.1: Generate d such that 1 <= n < N */
|
||||
int count = 0;
|
||||
unsigned char rnd[MBEDTLS_ECP_MAX_BYTES];
|
||||
|
||||
/*
|
||||
* Match the procedure given in RFC 6979 (deterministic ECDSA):
|
||||
* - use the same byte ordering;
|
||||
* - keep the leftmost nbits bits of the generated octet string;
|
||||
* - try until result is in the desired range.
|
||||
* This also avoids any biais, which is especially important for ECDSA.
|
||||
*/
|
||||
do
|
||||
{
|
||||
MBEDTLS_MPI_CHK( f_rng( p_rng, rnd, n_size ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( d, rnd, n_size ) );
|
||||
MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( d, 8 * n_size - grp->nbits ) );
|
||||
|
||||
/*
|
||||
* Each try has at worst a probability 1/2 of failing (the msb has
|
||||
* a probability 1/2 of being 0, and then the result will be < N),
|
||||
* so after 30 tries failure probability is a most 2**(-30).
|
||||
*
|
||||
* For most curves, 1 try is enough with overwhelming probability,
|
||||
* since N starts with a lot of 1s in binary, but some curves
|
||||
* such as secp224k1 are actually very close to the worst case.
|
||||
*/
|
||||
if( ++count > 30 )
|
||||
return( MBEDTLS_ERR_ECP_RANDOM_FAILED );
|
||||
}
|
||||
while( mbedtls_mpi_cmp_int( d, 1 ) < 0 ||
|
||||
mbedtls_mpi_cmp_mpi( d, &grp->N ) >= 0 );
|
||||
}
|
||||
else
|
||||
#endif /* ECP_SHORTWEIERSTRASS */
|
||||
return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA );
|
||||
|
||||
cleanup:
|
||||
if( ret != 0 )
|
||||
return( ret );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mbedtls_ecp_derive_pubkey( mbedtls_ecp_group *grp,
|
||||
const mbedtls_ecp_point *G,
|
||||
mbedtls_mpi *d, mbedtls_ecp_point *Q,
|
||||
int (*f_rng)(void *, unsigned char *, size_t),
|
||||
void *p_rng )
|
||||
{
|
||||
return( mbedtls_ecp_mul( grp, Q, d, G, f_rng, p_rng ) );
|
||||
}
|
||||
|
||||
|
||||
static int hmac_vector_func(uint8_t * hmac, uint8_t * dst, int len)
|
||||
{
|
||||
static int hmac_ptr = 0;
|
||||
if (hmac==NULL)
|
||||
{
|
||||
hmac_ptr = 0;
|
||||
return 0;
|
||||
}
|
||||
int i;
|
||||
while(len--)
|
||||
{
|
||||
*dst++ = hmac[hmac_ptr++ % 32];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void generate_private_key(uint8_t * data, int len, uint8_t * data2, int len2, uint8_t * privkey)
|
||||
{
|
||||
crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey);
|
||||
crypto_sha256_update(data, len);
|
||||
crypto_sha256_update(data2, len2);
|
||||
crypto_sha256_update(master_secret, 32);
|
||||
crypto_sha256_hmac_final(CRYPTO_MASTER_KEY, 0, privkey);
|
||||
|
||||
// mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
|
||||
// mbedtls_mpi d; /*!< our secret value */
|
||||
// mbedtls_ecp_point Q;
|
||||
//
|
||||
// mbedtls_ecp_group_init( &grp );
|
||||
// mbedtls_mpi_init( &d );
|
||||
// mbedtls_ecp_point_init(&Q);
|
||||
//
|
||||
// mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
|
||||
//
|
||||
//// mbedtls_mpi_read_binary(&d, _signing_key, 32);
|
||||
// hmac_vector_func(NULL, NULL, 0);
|
||||
// mbedtls_ecp_gen_privkey(&grp, &grp.G, &d, &Q, hmac_vector_func, privkey);
|
||||
// mbedtls_mpi_write_binary(&d,privkey,32);
|
||||
}
|
||||
|
||||
|
||||
/*int uECC_compute_public_key(const uint8_t *private_key, uint8_t *public_key, uECC_Curve curve);*/
|
||||
void crypto_ecc256_derive_public_key(uint8_t * data, int len, uint8_t * x, uint8_t * y)
|
||||
{
|
||||
int ret;
|
||||
uint8_t privkey[32];
|
||||
uint8_t pubkey[64];
|
||||
|
||||
// generate_private_key(data,len,NULL,0,privkey);
|
||||
|
||||
crypto_sha256_hmac_init(CRYPTO_MASTER_KEY, 0, privkey);
|
||||
crypto_sha256_update(data, len);
|
||||
crypto_sha256_update(NULL, 0);
|
||||
crypto_sha256_update(master_secret, 32);
|
||||
crypto_sha256_hmac_final(CRYPTO_MASTER_KEY, 0, privkey);
|
||||
|
||||
// mbedtls_ecp_group grp; /*!< Elliptic curve and base point */
|
||||
// mbedtls_mpi d; /*!< our secret value */
|
||||
// mbedtls_ecp_point Q;
|
||||
//
|
||||
// mbedtls_ecp_group_init( &grp );
|
||||
// mbedtls_mpi_init( &d );
|
||||
// mbedtls_ecp_point_init(&Q);
|
||||
//
|
||||
// mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);
|
||||
//
|
||||
//// mbedtls_mpi_read_binary(&d, _signing_key, 32);
|
||||
// hmac_vector_func(NULL, NULL, 0);
|
||||
// ret= mbedtls_ecp_gen_privkey(&grp, &grp.G, &d, &Q, hmac_vector_func, privkey);
|
||||
// if (ret != 0)
|
||||
// {
|
||||
// printf("error with priv key -0x04%x\n", -ret);
|
||||
// }
|
||||
//// mbedtls_mpi_write_binary(&d,privkey,32);
|
||||
//
|
||||
// memset(pubkey,0,sizeof(pubkey));
|
||||
//
|
||||
// ret = mbedtls_ecp_derive_pubkey( &grp, &grp.G,
|
||||
// &d, &Q, hmac_vector_func, privkey);
|
||||
//
|
||||
// if (ret != 0)
|
||||
// {
|
||||
// printf("error with public key\n");
|
||||
// }
|
||||
//
|
||||
// mbedtls_mpi_write_binary(&Q.X,x,32);
|
||||
// mbedtls_mpi_write_binary(&Q.Y,y,32);
|
||||
|
||||
uECC_compute_public_key(privkey, pubkey, _es256_curve);
|
||||
memmove(x,pubkey,32);
|
||||
memmove(y,pubkey+32,32);
|
||||
}
|
||||
|
||||
void crypto_ecc256_load_key(uint8_t * data, int len, uint8_t * data2, int len2)
|
||||
{
|
||||
static uint8_t privkey[32];
|
||||
generate_private_key(data,len,data2,len2,privkey);
|
||||
_signing_key = privkey;
|
||||
_key_len = 32;
|
||||
}
|
||||
|
||||
void crypto_ecc256_make_key_pair(uint8_t * pubkey, uint8_t * privkey)
|
||||
{
|
||||
if (uECC_make_key(pubkey, privkey, _es256_curve) != 1)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, uECC_make_key failed\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void crypto_ecc256_shared_secret(const uint8_t * pubkey, const uint8_t * privkey, uint8_t * shared_secret)
|
||||
{
|
||||
if (uECC_shared_secret(pubkey, privkey, shared_secret, _es256_curve) != 1)
|
||||
{
|
||||
printf2(TAG_ERR,"Error, uECC_shared_secret failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct AES_ctx aes_ctx;
|
||||
void crypto_aes256_init(uint8_t * key, uint8_t * nonce)
|
||||
{
|
||||
if (key == CRYPTO_TRANSPORT_KEY)
|
||||
{
|
||||
AES_init_ctx(&aes_ctx, transport_secret);
|
||||
}
|
||||
else
|
||||
{
|
||||
AES_init_ctx(&aes_ctx, key);
|
||||
}
|
||||
if (nonce == NULL)
|
||||
{
|
||||
memset(aes_ctx.Iv, 0, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(aes_ctx.Iv, nonce, 16);
|
||||
}
|
||||
}
|
||||
|
||||
// prevent round key recomputation
|
||||
void crypto_aes256_reset_iv(uint8_t * nonce)
|
||||
{
|
||||
if (nonce == NULL)
|
||||
{
|
||||
memset(aes_ctx.Iv, 0, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
memmove(aes_ctx.Iv, nonce, 16);
|
||||
}
|
||||
}
|
||||
|
||||
void crypto_aes256_decrypt(uint8_t * buf, int length)
|
||||
{
|
||||
AES_CBC_decrypt_buffer(&aes_ctx, buf, length);
|
||||
}
|
||||
|
||||
void crypto_aes256_encrypt(uint8_t * buf, int length)
|
||||
{
|
||||
AES_CBC_encrypt_buffer(&aes_ctx, buf, length);
|
||||
}
|
||||
|
||||
|
||||
|
||||
const uint8_t attestation_cert_der[] =
|
||||
"\x30\x82\x01\xfb\x30\x82\x01\xa1\xa0\x03\x02\x01\x02\x02\x01\x00\x30\x0a\x06\x08"
|
||||
"\x2a\x86\x48\xce\x3d\x04\x03\x02\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
|
||||
"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e"
|
||||
"\x06\x03\x55\x04\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x30\x20\x17\x0d\x31\x38"
|
||||
"\x30\x35\x31\x30\x30\x33\x30\x36\x32\x30\x5a\x18\x0f\x32\x30\x36\x38\x30\x34\x32"
|
||||
"\x37\x30\x33\x30\x36\x32\x30\x5a\x30\x7c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13"
|
||||
"\x02\x55\x53\x31\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x0f\x30\x0d"
|
||||
"\x06\x03\x55\x04\x07\x0c\x06\x4c\x61\x75\x72\x65\x6c\x31\x15\x30\x13\x06\x03\x55"
|
||||
"\x04\x0a\x0c\x0c\x54\x45\x53\x54\x20\x43\x4f\x4d\x50\x41\x4e\x59\x31\x22\x30\x20"
|
||||
"\x06\x03\x55\x04\x0b\x0c\x19\x41\x75\x74\x68\x65\x6e\x74\x69\x63\x61\x74\x6f\x72"
|
||||
"\x20\x41\x74\x74\x65\x73\x74\x61\x74\x69\x6f\x6e\x31\x14\x30\x12\x06\x03\x55\x04"
|
||||
"\x03\x0c\x0b\x63\x6f\x6e\x6f\x72\x70\x70\x2e\x63\x6f\x6d\x30\x59\x30\x13\x06\x07"
|
||||
"\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00"
|
||||
"\x04\x45\xa9\x02\xc1\x2e\x9c\x0a\x33\xfa\x3e\x84\x50\x4a\xb8\x02\xdc\x4d\xb9\xaf"
|
||||
"\x15\xb1\xb6\x3a\xea\x8d\x3f\x03\x03\x55\x65\x7d\x70\x3f\xb4\x02\xa4\x97\xf4\x83"
|
||||
"\xb8\xa6\xf9\x3c\xd0\x18\xad\x92\x0c\xb7\x8a\x5a\x3e\x14\x48\x92\xef\x08\xf8\xca"
|
||||
"\xea\xfb\x32\xab\x20\xa3\x62\x30\x60\x30\x46\x06\x03\x55\x1d\x23\x04\x3f\x30\x3d"
|
||||
"\xa1\x30\xa4\x2e\x30\x2c\x31\x0b\x30\x09\x06\x03\x55\x04\x06\x13\x02\x55\x53\x31"
|
||||
"\x0b\x30\x09\x06\x03\x55\x04\x08\x0c\x02\x4d\x44\x31\x10\x30\x0e\x06\x03\x55\x04"
|
||||
"\x0a\x0c\x07\x54\x45\x53\x54\x20\x43\x41\x82\x09\x00\xf7\xc9\xec\x89\xf2\x63\x94"
|
||||
"\xd9\x30\x09\x06\x03\x55\x1d\x13\x04\x02\x30\x00\x30\x0b\x06\x03\x55\x1d\x0f\x04"
|
||||
"\x04\x03\x02\x04\xf0\x30\x0a\x06\x08\x2a\x86\x48\xce\x3d\x04\x03\x02\x03\x48\x00"
|
||||
"\x30\x45\x02\x20\x18\x38\xb0\x45\x03\x69\xaa\xa7\xb7\x38\x62\x01\xaf\x24\x97\x5e"
|
||||
"\x7e\x74\x64\x1b\xa3\x7b\xf7\xe6\xd3\xaf\x79\x28\xdb\xdc\xa5\x88\x02\x21\x00\xcd"
|
||||
"\x06\xf1\xe3\xab\x16\x21\x8e\xd8\xc0\x14\xaf\x09\x4f\x5b\x73\xef\x5e\x9e\x4b\xe7"
|
||||
"\x35\xeb\xdd\x9b\x6d\x8f\x7d\xf3\xc4\x3a\xd7";
|
||||
|
||||
|
||||
const uint16_t attestation_cert_der_size = sizeof(attestation_cert_der)-1;
|
||||
|
||||
|
||||
const uint8_t attestation_key[] = "\xcd\x67\xaa\x31\x0d\x09\x1e\xd1\x6e\x7e\x98\x92\xaa\x07\x0e\x19\x94\xfc\xd7\x14\xae\x7c\x40\x8f\xb9\x46\xb7\x2e\x5f\xe7\x5d\x30";
|
||||
const uint16_t attestation_key_size = sizeof(attestation_key)-1;
|
||||
|
||||
|
||||
|
@ -1,713 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
/*
|
||||
* device.c
|
||||
*
|
||||
* Created on: Jun 27, 2018
|
||||
* Author: conor
|
||||
*/
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "em_chip.h"
|
||||
#include "em_gpio.h"
|
||||
#include "em_usart.h"
|
||||
#include "em_adc.h"
|
||||
#include "em_cmu.h"
|
||||
#include "em_msc.h"
|
||||
#include "em_i2c.h"
|
||||
#include "em_timer.h"
|
||||
|
||||
#include "InitDevice.h"
|
||||
#include "cbor.h"
|
||||
#include "log.h"
|
||||
#include "ctaphid.h"
|
||||
#include "util.h"
|
||||
#include "app.h"
|
||||
#include "uECC.h"
|
||||
#include "crypto.h"
|
||||
#include "nfc.h"
|
||||
|
||||
#ifdef USING_DEV_BOARD
|
||||
|
||||
#define MSG_AVAIL_PIN gpioPortC,9
|
||||
#define RDY_PIN gpioPortC,10
|
||||
#define RW_PIN gpioPortD,11
|
||||
#define RESET_PIN gpioPortB,13
|
||||
#define LED_RED_PIN gpioPortF,4
|
||||
#define LED_GREEN_PIN gpioPortF,5
|
||||
|
||||
#else
|
||||
|
||||
#define MSG_AVAIL_PIN gpioPortA,1
|
||||
#define RDY_PIN gpioPortA,0
|
||||
#define RW_PIN gpioPortD,15
|
||||
#define RESET_PIN gpioPortB,15
|
||||
#define LED_RED_PIN gpioPortD,10
|
||||
#define LED_GREEN_PIN gpioPortD,14
|
||||
#define LED_BLUE_PIN gpioPortD,9
|
||||
#define BUTTON_PIN gpioPortD,13
|
||||
|
||||
#define RED_CHANNEL 0
|
||||
#define GREEN_CHANNEL 2
|
||||
#define BLUE_CHANNEL 1
|
||||
|
||||
#endif
|
||||
|
||||
#define PAGE_SIZE 2048
|
||||
#define PAGES 64
|
||||
#define COUNTER_PAGE (PAGES - 3)
|
||||
#define STATE1_PAGE (PAGES - 2)
|
||||
#define STATE2_PAGE (PAGES - 1)
|
||||
|
||||
#define APPLICATION_START_ADDR 0x4000
|
||||
#define APPLICATION_START_PAGE (0x4000/PAGE_SIZE)
|
||||
|
||||
#define APPLICATION_END_ADDR (PAGE_SIZE*(PAGES - 3)-4) // NOT included in application
|
||||
#define APPLICATION_END_PAGE ((PAGES - 3)) // 125 is NOT included in application
|
||||
|
||||
#define AUTH_WORD_ADDR (PAGE_SIZE*(PAGES - 3)-4)
|
||||
|
||||
|
||||
|
||||
static void init_atomic_counter()
|
||||
{
|
||||
int offset = 0;
|
||||
uint32_t count;
|
||||
uint32_t one = 1;
|
||||
uint32_t * ptr = PAGE_SIZE * COUNTER_PAGE;
|
||||
|
||||
for (offset = 0; offset < PAGE_SIZE/4; offset += 1)
|
||||
{
|
||||
count = *(ptr+offset);
|
||||
if (count != 0xffffffff)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
MSC_WriteWordFast(ptr,&one,4);
|
||||
}
|
||||
|
||||
|
||||
uint32_t ctap_atomic_count(int sel)
|
||||
{
|
||||
int offset = 0;
|
||||
uint32_t count;
|
||||
uint32_t zero = 0;
|
||||
uint32_t * ptr = PAGE_SIZE * COUNTER_PAGE;
|
||||
|
||||
if (sel != 0)
|
||||
{
|
||||
printf2(TAG_ERR,"counter2 not imple\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (offset = 0; offset < PAGE_SIZE/4; offset += 1) // wear-level the flash
|
||||
{
|
||||
count = *(ptr+offset);
|
||||
if (count != 0)
|
||||
{
|
||||
count++;
|
||||
offset++;
|
||||
if (offset == PAGE_SIZE/4)
|
||||
{
|
||||
offset = 0;
|
||||
MSC_ErasePage(ptr);
|
||||
/*printf("RESET page counter\n");*/
|
||||
}
|
||||
else
|
||||
{
|
||||
MSC_WriteWordFast(ptr+offset-1,&zero,4);
|
||||
}
|
||||
MSC_WriteWordFast(ptr+offset,&count,4);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static uint32_t _color;
|
||||
uint32_t get_RBG()
|
||||
{
|
||||
return _color;
|
||||
}
|
||||
|
||||
void RGB(uint32_t hex)
|
||||
{
|
||||
uint16_t r = 256 - ((hex & 0xff0000) >> 16);
|
||||
uint16_t g = 256 - ((hex & 0xff00) >> 8);
|
||||
uint16_t b = 256 - ((hex & 0xff) >> 0);
|
||||
|
||||
TIMER_CompareBufSet(TIMER0, GREEN_CHANNEL, g); // green
|
||||
TIMER_CompareBufSet(TIMER0, RED_CHANNEL, r); // red
|
||||
TIMER_CompareBufSet(TIMER0, BLUE_CHANNEL, b); // blue
|
||||
_color = hex;
|
||||
}
|
||||
|
||||
|
||||
#define IS_BUTTON_PRESSED() (GPIO_PinInGet(BUTTON_PIN) == 0)
|
||||
|
||||
// Verify the user
|
||||
// return 1 if user is verified, 0 if not
|
||||
int ctap_user_verification(uint8_t arg)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Test for user presence
|
||||
// Return 1 for user is present, 0 user not present
|
||||
int ctap_user_presence_test()
|
||||
{
|
||||
#ifdef SKIP_BUTTON_CHECK
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
|
||||
uint32_t t1 = millis();
|
||||
RGB(0x304010);
|
||||
|
||||
#ifdef USE_BUTTON_DELAY
|
||||
delay(3000);
|
||||
RGB(0x001040);
|
||||
delay(50);
|
||||
return 1;
|
||||
#endif
|
||||
while (IS_BUTTON_PRESSED())
|
||||
{
|
||||
if (t1 + 5000 < millis())
|
||||
{
|
||||
printf1(TAG_GEN,"Button not pressed\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
t1 = millis();
|
||||
|
||||
do
|
||||
{
|
||||
if (t1 + 5000 < millis())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (! IS_BUTTON_PRESSED())
|
||||
continue;
|
||||
delay(1);
|
||||
}
|
||||
while (! IS_BUTTON_PRESSED());
|
||||
|
||||
RGB(0x001040);
|
||||
|
||||
delay(50);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Must be implemented by application
|
||||
// data is HID_MESSAGE_SIZE long in bytes
|
||||
#ifndef TEST_POWER
|
||||
void ctaphid_write_block(uint8_t * data)
|
||||
{
|
||||
printf1(TAG_DUMP,"<< "); dump_hex1(TAG_DUMP, data, HID_MESSAGE_SIZE);
|
||||
usbhid_send(data);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef IS_BOOTLOADER // two different colors between bootloader and app
|
||||
void heartbeat()
|
||||
{
|
||||
static int state = 0;
|
||||
static uint32_t val = (LED_INIT_VALUE >> 8) & 0xff;
|
||||
int but = IS_BUTTON_PRESSED();
|
||||
|
||||
|
||||
if (state)
|
||||
{
|
||||
val--;
|
||||
}
|
||||
else
|
||||
{
|
||||
val++;
|
||||
}
|
||||
|
||||
if (val > 30 || val < 1)
|
||||
{
|
||||
state = !state;
|
||||
}
|
||||
|
||||
// if (but) RGB(val * 2);
|
||||
// else
|
||||
RGB((val << 16) | (val*2 << 8));
|
||||
|
||||
}
|
||||
#else
|
||||
void heartbeat()
|
||||
{
|
||||
static int state = 0;
|
||||
static uint32_t val = (LED_INIT_VALUE >> 8) & 0xff;
|
||||
int but = IS_BUTTON_PRESSED();
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
RGB(0x100000); // bright ass light
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (state)
|
||||
{
|
||||
val--;
|
||||
}
|
||||
else
|
||||
{
|
||||
val++;
|
||||
}
|
||||
|
||||
if (val >120/3 || val < 1)
|
||||
{
|
||||
state = !state;
|
||||
}
|
||||
|
||||
if (but) RGB(val * 2);
|
||||
else RGB(val*3 | ((val*3) << 8) | (val << 16) );
|
||||
// else RGB((val*3) << 8);
|
||||
|
||||
}
|
||||
#endif
|
||||
uint32_t millis()
|
||||
{
|
||||
return CRYOTIMER->CNT;
|
||||
}
|
||||
|
||||
|
||||
void usbhid_init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static int msgs_to_recv = 0;
|
||||
|
||||
static void wait_for_efm8_ready()
|
||||
{
|
||||
// Wait for efm8 to be ready
|
||||
while (GPIO_PinInGet(RDY_PIN) == 0)
|
||||
;
|
||||
}
|
||||
|
||||
static void wait_for_efm8_busy()
|
||||
{
|
||||
// Wait for efm8 to be ready
|
||||
while (GPIO_PinInGet(RDY_PIN) != 0)
|
||||
;
|
||||
}
|
||||
|
||||
#ifndef TEST_POWER
|
||||
int usbhid_recv(uint8_t * msg)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (GPIO_PinInGet(MSG_AVAIL_PIN) == 0)
|
||||
{
|
||||
GPIO_PinOutClear(RW_PIN); // Drive low to indicate READ
|
||||
wait_for_efm8_ready();
|
||||
|
||||
|
||||
for (i = 0; i < 64; i++)
|
||||
{
|
||||
msg[i] = USART_SpiTransfer(USART1, 'A');
|
||||
// delay(1);
|
||||
}
|
||||
|
||||
GPIO_PinOutSet(RW_PIN);
|
||||
|
||||
wait_for_efm8_busy();
|
||||
|
||||
|
||||
// // msgs_to_recv--;
|
||||
// printf(">> ");
|
||||
// dump_hex(msg,64);
|
||||
return 64;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void usbhid_send(uint8_t * msg)
|
||||
{
|
||||
int i;
|
||||
// uint32_t t1 = millis();
|
||||
USART_SpiTransfer(USART1, *msg++); // Send 1 byte
|
||||
wait_for_efm8_ready();
|
||||
|
||||
for (i = 1; i < HID_MESSAGE_SIZE; i++)
|
||||
{
|
||||
USART_SpiTransfer(USART1, *msg++);
|
||||
}
|
||||
wait_for_efm8_busy();
|
||||
|
||||
delay(10);
|
||||
// uint32_t t2 = millis();
|
||||
// printf("wait time: %u\n", (uint32_t)(t2-t1));
|
||||
|
||||
}
|
||||
|
||||
void usbhid_close()
|
||||
{
|
||||
}
|
||||
|
||||
void main_loop_delay()
|
||||
{
|
||||
}
|
||||
|
||||
void delay(int ms)
|
||||
{
|
||||
int t1 = millis();
|
||||
while(millis() - t1 < ms)
|
||||
;
|
||||
}
|
||||
|
||||
void GPIO_ODD_IRQHandler()
|
||||
{
|
||||
uint32_t flag = GPIO->IF;
|
||||
GPIO->IFC = flag;
|
||||
if (flag & (1<<9))
|
||||
{
|
||||
// printf("pin 9 interrupt\r\n");
|
||||
msgs_to_recv++;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf1(TAG_ERR,"wrong pin int %x\r\n",flag);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void init_adc()
|
||||
{
|
||||
/* Enable ADC Clock */
|
||||
CMU_ClockEnable(cmuClock_ADC0, true);
|
||||
ADC_Init_TypeDef init = ADC_INIT_DEFAULT;
|
||||
ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT;
|
||||
|
||||
/* Initialize the ADC with the required values */
|
||||
init.timebase = ADC_TimebaseCalc(0);
|
||||
init.prescale = ADC_PrescaleCalc(7000000, 0);
|
||||
ADC_Init(ADC0, &init);
|
||||
|
||||
/* Initialize for single conversion specific to RNG */
|
||||
singleInit.reference = adcRefVEntropy;
|
||||
singleInit.diff = true;
|
||||
singleInit.posSel = adcPosSelVSS;
|
||||
singleInit.negSel = adcNegSelVSS;
|
||||
ADC_InitSingle(ADC0, &singleInit);
|
||||
|
||||
/* Set VINATT to maximum value and clear FIFO */
|
||||
ADC0->SINGLECTRLX |= _ADC_SINGLECTRLX_VINATT_MASK;
|
||||
ADC0->SINGLEFIFOCLEAR = ADC_SINGLEFIFOCLEAR_SINGLEFIFOCLEAR;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void authenticator_read_state(AuthenticatorState * state)
|
||||
{
|
||||
uint32_t * ptr = PAGE_SIZE*STATE1_PAGE;
|
||||
memmove(state,ptr,sizeof(AuthenticatorState));
|
||||
}
|
||||
|
||||
void authenticator_read_backup_state(AuthenticatorState * state )
|
||||
{
|
||||
uint32_t * ptr = PAGE_SIZE*STATE2_PAGE;
|
||||
memmove(state,ptr,sizeof(AuthenticatorState));
|
||||
}
|
||||
|
||||
void authenticator_write_state(AuthenticatorState * state, int backup)
|
||||
{
|
||||
uint32_t * ptr;
|
||||
if (! backup)
|
||||
{
|
||||
ptr = PAGE_SIZE*STATE1_PAGE;
|
||||
MSC_ErasePage(ptr);
|
||||
// for (i = 0; i < sizeof(AuthenticatorState)/4; i++ )
|
||||
MSC_WriteWordFast(ptr,state,sizeof(AuthenticatorState) + (sizeof(AuthenticatorState)%4));
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr = PAGE_SIZE*STATE2_PAGE;
|
||||
MSC_ErasePage(ptr);
|
||||
// for (i = 0; i < sizeof(AuthenticatorState)/4; i++ )
|
||||
MSC_WriteWordFast(ptr,state,sizeof(AuthenticatorState) + (sizeof(AuthenticatorState)%4));
|
||||
}
|
||||
}
|
||||
|
||||
// Return 1 yes backup is init'd, else 0
|
||||
int authenticator_is_backup_initialized()
|
||||
{
|
||||
uint8_t header[16];
|
||||
uint32_t * ptr = PAGE_SIZE*STATE2_PAGE;
|
||||
memmove(header,ptr,16);
|
||||
AuthenticatorState * state = (AuthenticatorState*)header;
|
||||
return state->is_initialized == INITIALIZED_MARKER;
|
||||
}
|
||||
|
||||
|
||||
uint8_t adc_rng(void);
|
||||
|
||||
void reset_efm8()
|
||||
{
|
||||
// Reset EFM8
|
||||
GPIO_PinOutClear(RESET_PIN);
|
||||
delay(2);
|
||||
GPIO_PinOutSet(RESET_PIN);
|
||||
}
|
||||
|
||||
void bootloader_init(void)
|
||||
{
|
||||
/* Chip errata */
|
||||
|
||||
// Reset EFM8
|
||||
GPIO_PinModeSet(RESET_PIN, gpioModePushPull, 1);
|
||||
|
||||
// status LEDS
|
||||
GPIO_PinModeSet(LED_RED_PIN,
|
||||
gpioModePushPull,
|
||||
1); // red
|
||||
|
||||
GPIO_PinModeSet(LED_GREEN_PIN,
|
||||
gpioModePushPull,
|
||||
1); // green
|
||||
GPIO_PinModeSet(LED_BLUE_PIN,
|
||||
gpioModePushPull,
|
||||
1); // blue
|
||||
|
||||
// EFM8 RDY/BUSY
|
||||
GPIO_PinModeSet(RDY_PIN, gpioModeInput, 0);
|
||||
|
||||
// EFM8 MSG Available
|
||||
GPIO_PinModeSet(MSG_AVAIL_PIN, gpioModeInput, 0);
|
||||
|
||||
// SPI R/w Indicator
|
||||
GPIO_PinModeSet(RW_PIN, gpioModePushPull, 1);
|
||||
|
||||
|
||||
printing_init();
|
||||
|
||||
|
||||
MSC_Init();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void device_init(void)
|
||||
{
|
||||
/* Chip errata */
|
||||
|
||||
CHIP_Init();
|
||||
enter_DefaultMode_from_RESET();
|
||||
|
||||
// status LEDS
|
||||
GPIO_PinModeSet(LED_RED_PIN,
|
||||
gpioModePushPull,
|
||||
1); // red
|
||||
|
||||
GPIO_PinModeSet(LED_GREEN_PIN,
|
||||
gpioModePushPull,
|
||||
1); // green
|
||||
GPIO_PinModeSet(LED_BLUE_PIN,
|
||||
gpioModePushPull,
|
||||
1); // blue
|
||||
|
||||
// EFM8 RDY/BUSY
|
||||
GPIO_PinModeSet(RDY_PIN, gpioModeInput, 0);
|
||||
|
||||
// EFM8 MSG Available
|
||||
GPIO_PinModeSet(MSG_AVAIL_PIN, gpioModeInput, 0);
|
||||
|
||||
// SPI R/w Indicator
|
||||
GPIO_PinModeSet(RW_PIN, gpioModePushPull, 1);
|
||||
|
||||
// Reset EFM8
|
||||
GPIO_PinModeSet(RESET_PIN, gpioModePushPull, 1);
|
||||
|
||||
TIMER_TopSet(TIMER0, 255);
|
||||
|
||||
RGB(LED_INIT_VALUE);
|
||||
|
||||
printing_init();
|
||||
|
||||
init_adc();
|
||||
|
||||
MSC_Init();
|
||||
|
||||
init_atomic_counter();
|
||||
if (sizeof(AuthenticatorState) > PAGE_SIZE)
|
||||
{
|
||||
printf2(TAG_ERR, "not enough room in page\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
CborEncoder test;
|
||||
uint8_t buf[64];
|
||||
cbor_encoder_init(&test, buf, 20, 0);
|
||||
|
||||
reset_efm8();
|
||||
|
||||
printf1(TAG_GEN,"Device init\r\n");
|
||||
int i=0;
|
||||
|
||||
for (i = 0; i < sizeof(buf); i++)
|
||||
{
|
||||
buf[i] = adc_rng();
|
||||
}
|
||||
|
||||
}
|
||||
#ifdef IS_BOOTLOADER
|
||||
typedef enum
|
||||
{
|
||||
BootWrite = 0x40,
|
||||
BootDone = 0x41,
|
||||
BootCheck = 0x42,
|
||||
BootErase = 0x43,
|
||||
} WalletOperation;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t op;
|
||||
uint8_t addr[3];
|
||||
uint8_t tag[4];
|
||||
uint8_t len;
|
||||
uint8_t payload[255 - 9];
|
||||
} __attribute__((packed)) BootloaderReq;
|
||||
|
||||
//#define APPLICATION_START_ADDR 0x8000
|
||||
//#define APPLICATION_START_PAGE (0x8000/PAGE_SIZE)
|
||||
|
||||
//#define APPLICATION_END_ADDR (PAGE_SIZE*125-4) // NOT included in application
|
||||
|
||||
static void erase_application()
|
||||
{
|
||||
int page;
|
||||
uint32_t * ptrpage;
|
||||
for(page = APPLICATION_START_PAGE; page < APPLICATION_END_PAGE; page++)
|
||||
{
|
||||
ptrpage = page * PAGE_SIZE;
|
||||
MSC_ErasePage(ptrpage);
|
||||
}
|
||||
}
|
||||
|
||||
static void authorize_application()
|
||||
{
|
||||
uint32_t zero = 0;
|
||||
uint32_t * ptr;
|
||||
ptr = AUTH_WORD_ADDR;
|
||||
MSC_WriteWordFast(ptr,&zero, 4);
|
||||
}
|
||||
int bootloader_bridge(uint8_t klen, uint8_t * keyh)
|
||||
{
|
||||
static int has_erased = 0;
|
||||
BootloaderReq * req = (BootloaderReq * )keyh;
|
||||
uint8_t payload[256];
|
||||
uint8_t hash[32];
|
||||
uint8_t * pubkey = (uint8_t*)"\x57\xe6\x80\x39\x56\x46\x2f\x0c\x95\xac\x72\x71\xf0\xbc\xe8\x2d\x67\xd0\x59\x29\x2e\x15\x22\x89\x6a\xbd\x3f\x7f\x27\xf3\xc0\xc6\xe2\xd7\x7d\x8a\x9f\xcc\x53\xc5\x91\xb2\x0c\x9c\x3b\x4e\xa4\x87\x31\x67\xb4\xa9\x4b\x0e\x8d\x06\x67\xd8\xc5\xef\x2c\x50\x4a\x55";
|
||||
const struct uECC_Curve_t * curve = NULL;
|
||||
|
||||
/*printf("bootloader_bridge\n");*/
|
||||
if (req->len > 255-9)
|
||||
{
|
||||
return CTAP1_ERR_INVALID_LENGTH;
|
||||
}
|
||||
|
||||
memset(payload, 0xff, sizeof(payload));
|
||||
memmove(payload, req->payload, req->len);
|
||||
|
||||
uint32_t addr = (*((uint32_t*)req->addr)) & 0xffffff;
|
||||
|
||||
uint32_t * ptr = addr;
|
||||
|
||||
switch(req->op){
|
||||
case BootWrite:
|
||||
/*printf("BootWrite 0x%08x\n", addr);*/
|
||||
if (ptr < APPLICATION_START_ADDR || ptr >= APPLICATION_END_ADDR)
|
||||
{
|
||||
return CTAP2_ERR_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
if (!has_erased)
|
||||
{
|
||||
erase_application();
|
||||
has_erased = 1;
|
||||
}
|
||||
if (is_authorized_to_boot())
|
||||
{
|
||||
printf2(TAG_ERR, "Error, boot check bypassed\n");
|
||||
exit(1);
|
||||
}
|
||||
MSC_WriteWordFast(ptr,payload, req->len + (req->len%4));
|
||||
break;
|
||||
case BootDone:
|
||||
// printf("BootDone\n");
|
||||
ptr = APPLICATION_START_ADDR;
|
||||
crypto_sha256_init();
|
||||
crypto_sha256_update(ptr, APPLICATION_END_ADDR-APPLICATION_START_ADDR);
|
||||
crypto_sha256_final(hash);
|
||||
// printf("hash: "); dump_hex(hash, 32);
|
||||
// printf("sig: "); dump_hex(payload, 64);
|
||||
curve = uECC_secp256r1();
|
||||
|
||||
if (! uECC_verify(pubkey,
|
||||
hash,
|
||||
32,
|
||||
payload,
|
||||
curve))
|
||||
{
|
||||
return CTAP2_ERR_OPERATION_DENIED;
|
||||
}
|
||||
authorize_application();
|
||||
REBOOT_FLAG = 1;
|
||||
break;
|
||||
case BootCheck:
|
||||
/*printf("BootCheck\n");*/
|
||||
return 0;
|
||||
break;
|
||||
case BootErase:
|
||||
/*printf("BootErase\n");*/
|
||||
erase_application();
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return CTAP1_ERR_INVALID_COMMAND;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int is_authorized_to_boot()
|
||||
{
|
||||
uint32_t * auth = AUTH_WORD_ADDR;
|
||||
return *auth == 0;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "em_chip.h"
|
||||
#include "em_cmu.h"
|
||||
#include "em_emu.h"
|
||||
#include "em_core.h"
|
||||
#include "em_gpio.h"
|
||||
|
||||
#include "InitDevice.h"
|
||||
|
||||
#include "app.h"
|
||||
#include "cbor.h"
|
@ -1,382 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
/*
|
||||
* nfc.c
|
||||
*
|
||||
* Created on: Jul 22, 2018
|
||||
* Author: conor
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "em_chip.h"
|
||||
#include "em_gpio.h"
|
||||
#include "em_i2c.h"
|
||||
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
#include "nfc.h"
|
||||
#include "app.h"
|
||||
|
||||
#define NFC_DEV_ADDR (0xa0|(0x0<<1))
|
||||
#define NFC_DEV_USART USART1
|
||||
#ifndef IS_BOOTLOADER
|
||||
I2C_TransferReturn_TypeDef I2CSPM_Transfer(I2C_TypeDef *i2c, I2C_TransferSeq_TypeDef *seq)
|
||||
{
|
||||
I2C_TransferReturn_TypeDef ret;
|
||||
uint32_t timeout = 10000;
|
||||
/* Do a polled transfer */
|
||||
ret = I2C_TransferInit(i2c, seq);
|
||||
|
||||
while (ret == i2cTransferInProgress && timeout--)
|
||||
{
|
||||
ret = I2C_Transfer(i2c);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// data must be 16 bytes
|
||||
void read_block(uint8_t block, uint8_t * data)
|
||||
{
|
||||
uint8_t addr = NFC_DEV_ADDR;
|
||||
I2C_TransferSeq_TypeDef seq;
|
||||
I2C_TransferReturn_TypeDef ret;
|
||||
uint8_t i2c_read_data[16];
|
||||
uint8_t i2c_write_data[1];
|
||||
|
||||
seq.addr = addr;
|
||||
seq.flags = I2C_FLAG_WRITE_READ;
|
||||
/* Select command to issue */
|
||||
i2c_write_data[0] = block;
|
||||
seq.buf[0].data = i2c_write_data;
|
||||
seq.buf[0].len = 1;
|
||||
/* Select location/length of data to be read */
|
||||
seq.buf[1].data = i2c_read_data;
|
||||
seq.buf[1].len = 16;
|
||||
|
||||
ret = I2CSPM_Transfer(I2C0, &seq);
|
||||
|
||||
if (ret != i2cTransferDone) {
|
||||
printf("I2C fail %04x\r\n",ret);
|
||||
exit(1);
|
||||
}
|
||||
memmove(data, i2c_read_data, 16);
|
||||
}
|
||||
|
||||
// data must be 16 bytes
|
||||
void write_block(uint8_t block, uint8_t * data)
|
||||
{
|
||||
uint8_t addr = NFC_DEV_ADDR;
|
||||
I2C_TransferSeq_TypeDef seq;
|
||||
I2C_TransferReturn_TypeDef ret;
|
||||
uint8_t i2c_write_data[1 + 16];
|
||||
|
||||
seq.addr = addr;
|
||||
seq.flags = I2C_FLAG_WRITE;
|
||||
/* Select command to issue */
|
||||
i2c_write_data[0] = block;
|
||||
memmove(i2c_write_data + 1, data, 16);
|
||||
seq.buf[0].data = i2c_write_data;
|
||||
seq.buf[0].len = 17;
|
||||
/* Select location/length of data to be read */
|
||||
seq.buf[1].data = NULL;
|
||||
seq.buf[1].len = 0;
|
||||
|
||||
ret = I2CSPM_Transfer(I2C0, &seq);
|
||||
|
||||
if (ret != i2cTransferDone) {
|
||||
printf("I2C fail %04x\r\n",ret);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void write_reg_flash(uint8_t reg_addr, uint8_t mask,uint8_t data)
|
||||
{
|
||||
uint8_t addr = NFC_DEV_ADDR;
|
||||
I2C_TransferSeq_TypeDef seq;
|
||||
I2C_TransferReturn_TypeDef ret;
|
||||
uint8_t i2c_write_data[4];
|
||||
|
||||
seq.addr = addr;
|
||||
seq.flags = I2C_FLAG_WRITE;
|
||||
i2c_write_data[0] = 0x3a;
|
||||
i2c_write_data[1] = reg_addr;
|
||||
i2c_write_data[2] = mask;
|
||||
i2c_write_data[3] = data;
|
||||
|
||||
seq.buf[0].data = i2c_write_data;
|
||||
seq.buf[0].len = 4;
|
||||
seq.buf[1].data = NULL;
|
||||
seq.buf[1].len = 0;
|
||||
|
||||
ret = I2CSPM_Transfer(I2C0, &seq);
|
||||
|
||||
if (ret != i2cTransferDone) {
|
||||
printf("I2C fail %04x\r\n",ret);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void write_reg(uint8_t reg_addr, uint8_t data)
|
||||
{
|
||||
|
||||
uint8_t mode = 0x00 | (reg_addr & 0x1f);
|
||||
// delay(10);
|
||||
|
||||
// delay(10);
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
delay(1);
|
||||
USART_SpiTransfer(NFC_DEV_USART, mode);
|
||||
mode = USART_SpiTransfer(NFC_DEV_USART, data);
|
||||
GPIO_PinOutSet(NFC_DEV_SS);
|
||||
}
|
||||
|
||||
void write_command(uint8_t cmd)
|
||||
{
|
||||
|
||||
uint8_t mode = cmd;
|
||||
// delay(10);
|
||||
|
||||
// delay(10);
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
delay(1);
|
||||
USART_SpiTransfer(NFC_DEV_USART, mode);
|
||||
GPIO_PinOutSet(NFC_DEV_SS);
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
|
||||
}
|
||||
|
||||
void write_eeprom(uint8_t block, uint8_t * data)
|
||||
{
|
||||
|
||||
uint8_t mode = 0x40;
|
||||
// delay(10);
|
||||
|
||||
// delay(10);
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
delay(1);
|
||||
USART_SpiTransfer(NFC_DEV_USART, mode);
|
||||
mode = block << 1;
|
||||
USART_SpiTransfer(NFC_DEV_USART, mode);
|
||||
USART_SpiTransfer(NFC_DEV_USART, *data++);
|
||||
USART_SpiTransfer(NFC_DEV_USART, *data++);
|
||||
USART_SpiTransfer(NFC_DEV_USART, *data++);
|
||||
USART_SpiTransfer(NFC_DEV_USART, *data++);
|
||||
|
||||
GPIO_PinOutSet(NFC_DEV_SS);
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
|
||||
}
|
||||
|
||||
void read_eeprom(uint8_t block, uint8_t * data)
|
||||
{
|
||||
|
||||
uint8_t mode = 0x7f;
|
||||
// delay(10);
|
||||
|
||||
// delay(10);
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
delay(1);
|
||||
USART_SpiTransfer(NFC_DEV_USART, mode);
|
||||
mode = block << 1;
|
||||
USART_SpiTransfer(NFC_DEV_USART, mode);
|
||||
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
|
||||
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
|
||||
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
|
||||
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
|
||||
|
||||
|
||||
GPIO_PinOutSet(NFC_DEV_SS);
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
|
||||
}
|
||||
|
||||
uint8_t read_reg(uint8_t reg_addr)
|
||||
{
|
||||
|
||||
uint8_t mode = 0x20 | (reg_addr & 0x1f);
|
||||
// delay(10);
|
||||
|
||||
// delay(10);
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
delay(1);
|
||||
USART_SpiTransfer(NFC_DEV_USART, mode);
|
||||
mode = USART_SpiTransfer(NFC_DEV_USART, 0);
|
||||
GPIO_PinOutSet(NFC_DEV_SS);
|
||||
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
|
||||
// printf("%02x: %x\n",(reg_addr),(int)mode);
|
||||
return mode;
|
||||
}
|
||||
|
||||
void read_buffer(uint8_t * data, int len)
|
||||
{
|
||||
|
||||
uint8_t mode = 0xC0;
|
||||
int i;
|
||||
if (len > 32)
|
||||
{
|
||||
printf("warning, max len is 32\n");
|
||||
len = 32;
|
||||
}
|
||||
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
delay(1);
|
||||
USART_SpiTransfer(NFC_DEV_USART, mode);
|
||||
for(i = 0; i < len; i++)
|
||||
{
|
||||
*data++ = USART_SpiTransfer(NFC_DEV_USART, 0);
|
||||
}
|
||||
GPIO_PinOutSet(NFC_DEV_SS);
|
||||
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
|
||||
}
|
||||
|
||||
// data must be 14 bytes long
|
||||
void read_reg_block(uint8_t * data)
|
||||
{
|
||||
int i;
|
||||
uint8_t mode = 0x20 | (0 & 0x1f);
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
delay(1);
|
||||
USART_SpiTransfer(NFC_DEV_USART, mode);
|
||||
for (i = 0; i < 0x20; i++)
|
||||
{
|
||||
mode = USART_SpiTransfer(NFC_DEV_USART, 0);
|
||||
if (i < 6 || (i >=8 && i < 0x0f) || (i >= 0x1e))
|
||||
{
|
||||
*data = mode;
|
||||
data++;
|
||||
}
|
||||
}
|
||||
|
||||
GPIO_PinOutSet(NFC_DEV_SS);
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t header;
|
||||
uint8_t tlen;
|
||||
uint8_t plen;
|
||||
uint8_t ilen;
|
||||
uint8_t rtype;
|
||||
} NDEF;
|
||||
|
||||
typedef struct {
|
||||
uint8_t io;
|
||||
uint8_t conf0;
|
||||
uint8_t conf1;
|
||||
uint8_t conf2;
|
||||
uint8_t rfid_status;
|
||||
uint8_t ic_status;
|
||||
uint8_t mask0;
|
||||
uint8_t mask1;
|
||||
uint8_t int0;
|
||||
uint8_t int1;
|
||||
uint8_t buf_status2;
|
||||
uint8_t buf_status1;
|
||||
uint8_t last_nfc_address;
|
||||
uint8_t maj;
|
||||
uint8_t minor;
|
||||
} __attribute__((packed)) AMS_REGS;
|
||||
|
||||
void nfc_test()
|
||||
{
|
||||
uint8_t data[32];
|
||||
uint8_t ns_reg;
|
||||
uint8_t last_ns_reg;
|
||||
// magic-number,
|
||||
uint8_t cc[] = {0xE1,0x10,0x08, 0x00};
|
||||
|
||||
uint8_t ndef[32] = "\x03\x11\xD1\x01\x0D\x55\x01adafruit.com";
|
||||
|
||||
AMS_REGS * regs;
|
||||
|
||||
return ;
|
||||
|
||||
|
||||
|
||||
delay(10);
|
||||
GPIO_PinOutSet(NFC_DEV_SS);
|
||||
delay(10);
|
||||
GPIO_PinOutClear(NFC_DEV_SS);
|
||||
delay(10);
|
||||
|
||||
// uint8_t reg = read_reg(0);
|
||||
write_command(0xC2); // Set to default state
|
||||
write_command(0xC4); // Clear buffer
|
||||
|
||||
write_reg(0x3, 0x80 | 0x40); // enable tunneling mode and RF configuration
|
||||
|
||||
|
||||
|
||||
read_reg_block(data);
|
||||
|
||||
printf("regs: "); dump_hex(data,15);
|
||||
|
||||
delay(100);
|
||||
|
||||
|
||||
read_reg_block(data);
|
||||
|
||||
printf("regs: "); dump_hex(data,15);
|
||||
|
||||
|
||||
|
||||
if (0)
|
||||
{
|
||||
read_eeprom(0x7F, data);
|
||||
printf("initial config: "); dump_hex(data,4);
|
||||
|
||||
data[0] = (1<<2) | 0x03; // save cfg1 setting for energy harvesting
|
||||
data[1] = 0x80 | 0x40; // save cfg2 setting for tunneling
|
||||
write_eeprom(0x7F, data);
|
||||
|
||||
printf("updated config: "); dump_hex(data,4);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
// delay(100);
|
||||
// read_reg_block(data);
|
||||
// regs = (AMS_REGS *)data;
|
||||
//
|
||||
// if ((regs->buf_status2 & 0x3f) && !(regs->buf_status2 & 0x80))
|
||||
// {
|
||||
// read_buffer(data, regs->buf_status2 & 0x3f);
|
||||
// printf("data: ");
|
||||
//
|
||||
// dump_hex(data, regs->buf_status2 & 0x3f);
|
||||
// }
|
||||
|
||||
// dump_hex(data,15);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2018 SoloKeys, Inc. <https://solokeys.com/>
|
||||
*
|
||||
* This file is part of Solo.
|
||||
*
|
||||
* Solo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Solo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Solo. If not, see <https://www.gnu.org/licenses/>
|
||||
*
|
||||
* This code is available under licenses for commercial use.
|
||||
* Please contact SoloKeys for more information.
|
||||
*/
|
||||
#include "em_chip.h"
|
||||
#include "em_cmu.h"
|
||||
#include "em_emu.h"
|
||||
#include "em_core.h"
|
||||
#include "em_usart.h"
|
||||
#include "em_gpio.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "app.h"
|
||||
#ifndef PRINTING_USE_VCOM
|
||||
int RETARGET_WriteChar(char c)
|
||||
{
|
||||
return ITM_SendChar(c);
|
||||
}
|
||||
|
||||
int RETARGET_ReadChar(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void setupSWOForPrint(void)
|
||||
{
|
||||
/* Enable GPIO clock. */
|
||||
CMU_ClockEnable(cmuClock_GPIO, true);
|
||||
|
||||
/* Enable Serial wire output pin */
|
||||
GPIO->ROUTEPEN |= GPIO_ROUTEPEN_SWVPEN;
|
||||
|
||||
/* Set location 0 */
|
||||
GPIO->ROUTELOC0 = GPIO_ROUTELOC0_SWVLOC_LOC0;
|
||||
|
||||
/* Enable output on pin - GPIO Port F, Pin 2 */
|
||||
GPIO->P[5].MODEL &= ~(_GPIO_P_MODEL_MODE2_MASK);
|
||||
GPIO->P[5].MODEL |= GPIO_P_MODEL_MODE2_PUSHPULL;
|
||||
|
||||
/* Enable debug clock AUXHFRCO */
|
||||
CMU_OscillatorEnable(cmuOsc_AUXHFRCO, true, true);
|
||||
CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
|
||||
|
||||
/* Wait until clock is ready */
|
||||
while (!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY));
|
||||
|
||||
/* Enable trace in core debug */
|
||||
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
|
||||
ITM->LAR = 0xC5ACCE55;
|
||||
ITM->TER = 0x0;
|
||||
ITM->TCR = 0x0;
|
||||
TPI->SPPR = 2;
|
||||
TPI->ACPR = 0x15; // changed from 0x0F on Giant, etc. to account for 19 MHz default AUXHFRCO frequency
|
||||
ITM->TPR = 0x0;
|
||||
DWT->CTRL = 0x400003FE;
|
||||
ITM->TCR = 0x0001000D;
|
||||
TPI->FFCR = 0x00000100;
|
||||
ITM->TER = 0x1;
|
||||
}
|
||||
|
||||
|
||||
void printing_init()
|
||||
{
|
||||
setupSWOForPrint();
|
||||
}
|
||||
#else
|
||||
|
||||
int RETARGET_WriteChar(char c)
|
||||
{
|
||||
USART_Tx(USART0,c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RETARGET_ReadChar(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void printing_init()
|
||||
{
|
||||
#ifdef USING_DEV_BOARD
|
||||
// GPIO_PinModeSet(gpioPortA,5,gpioModePushPull,1); // VCOM enable
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
@ -1,475 +0,0 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Provide stdio retargeting for all supported toolchains.
|
||||
* @version 5.5.0
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2015 Silicon Labs, Inc. http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* This file is licensed under the Silabs License Agreement. See the file
|
||||
* "Silabs_License_Agreement.txt" for details. Before using this software for
|
||||
* any purpose, you must agree to the terms of that agreement.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup RetargetIo
|
||||
* @{ This module provide low-level stubs for retargetting stdio for all
|
||||
* supported toolchains.
|
||||
* The stubs are minimal yet sufficient implementations.
|
||||
* Refer to chapter 12 in the reference manual for newlib 1.17.0
|
||||
* for details on implementing newlib stubs.
|
||||
******************************************************************************/
|
||||
|
||||
extern int RETARGET_ReadChar(void);
|
||||
extern int RETARGET_WriteChar(char c);
|
||||
|
||||
#if !defined(__CROSSWORKS_ARM) && defined(__GNUC__)
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "em_device.h"
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
int fileno(FILE *);
|
||||
/** @endcond */
|
||||
|
||||
int _close(int file);
|
||||
int _fstat(int file, struct stat *st);
|
||||
int _isatty(int file);
|
||||
int _lseek(int file, int ptr, int dir);
|
||||
int _read(int file, char *ptr, int len);
|
||||
caddr_t _sbrk(int incr);
|
||||
int _write(int file, const char *ptr, int len);
|
||||
|
||||
extern char _end; /**< Defined by the linker */
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Close a file.
|
||||
*
|
||||
* @param[in] file
|
||||
* File you want to close.
|
||||
*
|
||||
* @return
|
||||
* Returns 0 when the file is closed.
|
||||
*****************************************************************************/
|
||||
int _close(int file)
|
||||
{
|
||||
(void) file;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief Exit the program.
|
||||
* @param[in] status The value to return to the parent process as the
|
||||
* exit status (not used).
|
||||
*****************************************************************************/
|
||||
void _exit(int status)
|
||||
{
|
||||
(void) status;
|
||||
while (1) {
|
||||
} /* Hang here forever... */
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Status of an open file.
|
||||
*
|
||||
* @param[in] file
|
||||
* Check status for this file.
|
||||
*
|
||||
* @param[in] st
|
||||
* Status information.
|
||||
*
|
||||
* @return
|
||||
* Returns 0 when st_mode is set to character special.
|
||||
*****************************************************************************/
|
||||
int _fstat(int file, struct stat *st)
|
||||
{
|
||||
(void) file;
|
||||
st->st_mode = S_IFCHR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief Get process ID.
|
||||
*****************************************************************************/
|
||||
int _getpid(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Query whether output stream is a terminal.
|
||||
*
|
||||
* @param[in] file
|
||||
* Descriptor for the file.
|
||||
*
|
||||
* @return
|
||||
* Returns 1 when query is done.
|
||||
*****************************************************************************/
|
||||
int _isatty(int file)
|
||||
{
|
||||
(void) file;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief Send signal to process.
|
||||
* @param[in] pid Process id (not used).
|
||||
* @param[in] sig Signal to send (not used).
|
||||
*****************************************************************************/
|
||||
int _kill(int pid, int sig)
|
||||
{
|
||||
(void)pid;
|
||||
(void)sig;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Set position in a file.
|
||||
*
|
||||
* @param[in] file
|
||||
* Descriptor for the file.
|
||||
*
|
||||
* @param[in] ptr
|
||||
* Poiter to the argument offset.
|
||||
*
|
||||
* @param[in] dir
|
||||
* Directory whence.
|
||||
*
|
||||
* @return
|
||||
* Returns 0 when position is set.
|
||||
*****************************************************************************/
|
||||
int _lseek(int file, int ptr, int dir)
|
||||
{
|
||||
(void) file;
|
||||
(void) ptr;
|
||||
(void) dir;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Read from a file.
|
||||
*
|
||||
* @param[in] file
|
||||
* Descriptor for the file you want to read from.
|
||||
*
|
||||
* @param[in] ptr
|
||||
* Pointer to the chacaters that are beeing read.
|
||||
*
|
||||
* @param[in] len
|
||||
* Number of characters to be read.
|
||||
*
|
||||
* @return
|
||||
* Number of characters that have been read.
|
||||
*****************************************************************************/
|
||||
int _read(int file, char *ptr, int len)
|
||||
{
|
||||
int c, rxCount = 0;
|
||||
|
||||
(void) file;
|
||||
|
||||
while (len--) {
|
||||
if ((c = RETARGET_ReadChar()) != -1) {
|
||||
*ptr++ = c;
|
||||
rxCount++;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (rxCount <= 0) {
|
||||
return -1; /* Error exit */
|
||||
}
|
||||
|
||||
return rxCount;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Increase heap.
|
||||
*
|
||||
* @param[in] incr
|
||||
* Number of bytes you want increment the program's data space.
|
||||
*
|
||||
* @return
|
||||
* Rsturns a pointer to the start of the new area.
|
||||
*****************************************************************************/
|
||||
caddr_t _sbrk(int incr)
|
||||
{
|
||||
static char *heap_end;
|
||||
char *prev_heap_end;
|
||||
|
||||
if (heap_end == 0) {
|
||||
heap_end = &_end;
|
||||
}
|
||||
|
||||
prev_heap_end = heap_end;
|
||||
heap_end += incr;
|
||||
|
||||
return (caddr_t) prev_heap_end;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Write to a file.
|
||||
*
|
||||
* @param[in] file
|
||||
* Descriptor for the file you want to write to.
|
||||
*
|
||||
* @param[in] ptr
|
||||
* Pointer to the text you want to write
|
||||
*
|
||||
* @param[in] len
|
||||
* Number of characters to be written.
|
||||
*
|
||||
* @return
|
||||
* Number of characters that have been written.
|
||||
*****************************************************************************/
|
||||
int _write(int file, const char *ptr, int len)
|
||||
{
|
||||
int txCount;
|
||||
|
||||
(void) file;
|
||||
|
||||
for (txCount = 0; txCount < len; txCount++) {
|
||||
RETARGET_WriteChar(*ptr++);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
#endif /* !defined( __CROSSWORKS_ARM ) && defined( __GNUC__ ) */
|
||||
|
||||
#if defined(__ICCARM__)
|
||||
/*******************
|
||||
*
|
||||
* Copyright 1998-2003 IAR Systems. All rights reserved.
|
||||
*
|
||||
* $Revision: 38614 $
|
||||
*
|
||||
* This is a template implementation of the "__write" function used by
|
||||
* the standard library. Replace it with a system-specific
|
||||
* implementation.
|
||||
*
|
||||
* The "__write" function should output "size" number of bytes from
|
||||
* "buffer" in some application-specific way. It should return the
|
||||
* number of characters written, or _LLIO_ERROR on failure.
|
||||
*
|
||||
* If "buffer" is zero then __write should perform flushing of
|
||||
* internal buffers, if any. In this case "handle" can be -1 to
|
||||
* indicate that all handles should be flushed.
|
||||
*
|
||||
* The template implementation below assumes that the application
|
||||
* provides the function "MyLowLevelPutchar". It should return the
|
||||
* character written, or -1 on failure.
|
||||
*
|
||||
********************/
|
||||
|
||||
#include <yfuns.h>
|
||||
#include <stdint.h>
|
||||
#include "em_common.h"
|
||||
|
||||
_STD_BEGIN
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief Transmit buffer to USART1
|
||||
* @param buffer Array of characters to send
|
||||
* @param nbytes Number of bytes to transmit
|
||||
* @return Number of bytes sent
|
||||
*****************************************************************************/
|
||||
static int TxBuf(uint8_t *buffer, int nbytes)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nbytes; i++) {
|
||||
RETARGET_WriteChar(*buffer++);
|
||||
}
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the __write implementation uses internal buffering, uncomment
|
||||
* the following line to ensure that we are called with "buffer" as 0
|
||||
* (i.e. flush) when the application terminates.
|
||||
*/
|
||||
size_t __write(int handle, const unsigned char * buffer, size_t size)
|
||||
{
|
||||
/* Remove the #if #endif pair to enable the implementation */
|
||||
|
||||
size_t nChars = 0;
|
||||
|
||||
if (buffer == 0) {
|
||||
/*
|
||||
* This means that we should flush internal buffers. Since we
|
||||
* don't we just return. (Remember, "handle" == -1 means that all
|
||||
* handles should be flushed.)
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This template only writes to "standard out" and "standard err",
|
||||
* for all other file handles it returns failure. */
|
||||
if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) {
|
||||
return _LLIO_ERROR;
|
||||
}
|
||||
|
||||
/* Hook into USART1 transmit function here */
|
||||
if (TxBuf((uint8_t *) buffer, size) != size) {
|
||||
return _LLIO_ERROR;
|
||||
} else {
|
||||
nChars = size;
|
||||
}
|
||||
|
||||
return nChars;
|
||||
}
|
||||
|
||||
size_t __read(int handle, unsigned char * buffer, size_t size)
|
||||
{
|
||||
/* Remove the #if #endif pair to enable the implementation */
|
||||
int nChars = 0;
|
||||
|
||||
/* This template only reads from "standard in", for all other file
|
||||
* handles it returns failure. */
|
||||
if (handle != _LLIO_STDIN) {
|
||||
return _LLIO_ERROR;
|
||||
}
|
||||
|
||||
for (/* Empty */; size > 0; --size) {
|
||||
int c = RETARGET_ReadChar();
|
||||
if (c < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
*buffer++ = c;
|
||||
++nChars;
|
||||
}
|
||||
|
||||
return nChars;
|
||||
}
|
||||
|
||||
_STD_END
|
||||
|
||||
#endif /* defined( __ICCARM__ ) */
|
||||
|
||||
#if defined(__CROSSWORKS_ARM)
|
||||
|
||||
/* Pass each of these function straight to the USART */
|
||||
int __putchar(int ch)
|
||||
{
|
||||
return(RETARGET_WriteChar(ch));
|
||||
}
|
||||
|
||||
int __getchar(void)
|
||||
{
|
||||
return(RETARGET_ReadChar());
|
||||
}
|
||||
|
||||
#endif /* defined( __CROSSWORKS_ARM ) */
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
/******************************************************************************/
|
||||
/* RETARGET.C: 'Retarget' layer for target-dependent low level functions */
|
||||
/******************************************************************************/
|
||||
/* This file is part of the uVision/ARM development tools. */
|
||||
/* Copyright (c) 2005-2006 Keil Software. All rights reserved. */
|
||||
/* This software may only be used under the terms of a valid, current, */
|
||||
/* end user licence from KEIL for a compatible version of KEIL software */
|
||||
/* development tools. Nothing else gives you the right to use this software. */
|
||||
/******************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* #pragma import(__use_no_semihosting_swi) */
|
||||
|
||||
struct __FILE{
|
||||
int handle;
|
||||
};
|
||||
|
||||
/**Standard output stream*/
|
||||
FILE __stdout;
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Writes character to file
|
||||
*
|
||||
* @param[in] f
|
||||
* File
|
||||
*
|
||||
* @param[in] ch
|
||||
* Character
|
||||
*
|
||||
* @return
|
||||
* Written character
|
||||
*****************************************************************************/
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
return(RETARGET_WriteChar(ch));
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Reads character from file
|
||||
*
|
||||
* @param[in] f
|
||||
* File
|
||||
*
|
||||
* @return
|
||||
* Character
|
||||
*****************************************************************************/
|
||||
int fgetc(FILE *f)
|
||||
{
|
||||
return(RETARGET_ReadChar());
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Tests the error indicator for the stream pointed
|
||||
* to by file
|
||||
*
|
||||
* @param[in] f
|
||||
* File
|
||||
*
|
||||
* @return
|
||||
* Returns non-zero if it is set
|
||||
*****************************************************************************/
|
||||
int ferror(FILE *f)
|
||||
{
|
||||
/* Your implementation of ferror */
|
||||
return EOF;
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Writes a character to the console
|
||||
*
|
||||
* @param[in] ch
|
||||
* Character
|
||||
*****************************************************************************/
|
||||
void _ttywrch(int ch)
|
||||
{
|
||||
RETARGET_WriteChar(ch);
|
||||
}
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Library exit function. This function is called if stack
|
||||
* overflow occurs.
|
||||
*
|
||||
* @param[in] return_code
|
||||
* Return code
|
||||
*****************************************************************************/
|
||||
void _sys_exit(int return_code)
|
||||
{
|
||||
label: goto label;/* endless loop */
|
||||
}
|
||||
#endif /* defined( __CC_ARM ) */
|
||||
|
||||
/** @} (end group RetargetIo) */
|
@ -1,210 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?fileVersion 4.0.0?><cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
|
||||
<storageModule moduleId="org.eclipse.cdt.core.settings">
|
||||
<cconfiguration id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" moduleId="org.eclipse.cdt.core.settings" name="GNU ARM v7.2.1 - Debug">
|
||||
<macros>
|
||||
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="${StudioSdkPathFromID:com.silabs.sdk.stack.super:1.1.1._310456152}"/>
|
||||
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="${StudioToolchainPathFromID:com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904}"/>
|
||||
</macros>
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="com.silabs.ss.framework.debugger.core.HEX" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="com.silabs.ss.framework.debugger.core.EBL" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="com.silabs.ss.framework.debugger.core.GBL" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="com.silabs.ss.framework.debugger.core.BIN" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="com.silabs.ss.framework.debugger.core.S37" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule buildConfig.stockConfigId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" cppBuildConfig.builtinIncludes="studio:/sdk/hardware/kit/common/bsp/ studio:/sdk/hardware/kit/common/drivers/ studio:/sdk/platform/Device/SiliconLabs/EFM32JG1B/Include/ studio:/sdk/platform/CMSIS/Include/ studio:/sdk/platform/emlib/inc/ studio:/sdk/hardware/kit/common/bsp/ studio:/sdk/hardware/kit/common/drivers/ studio:/sdk/platform/Device/SiliconLabs/EFM32JG1B/Include/ studio:/sdk/platform/CMSIS/Include/ studio:/sdk/platform/emlib/inc/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="EFM32JG1B200F128GM32 EFM32JG1B200F128GM32" moduleId="com.silabs.ss.framework.ide.project.core.cpp" projectCommon.boardIds="com.silabs.board.none:0.0.0" projectCommon.partId="mcu.arm.efm32.jg1.efm32jg1b200f128gm32" projectCommon.referencedModules="[{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.drivers\">\r\n <exclusions pattern=\".*\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.bsp\">\r\n <exclusions pattern=\".*\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":["CMSIS/EFM32JG1B/startup_gcc_efm32jg1b.s","CMSIS/EFM32JG1B/system_efm32jg1b.c"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.part\"/>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.CMSIS\">\r\n <exclusions pattern=\".*\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":["emlib/em_gpio.c","emlib/em_system.c","emlib/em_cmu.c","emlib/em_assert.c","emlib/em_emu.c"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.emlib\">\r\n <inclusions pattern=\"emlib/em_system.c\"/>\r\n <inclusions pattern=\"emlib/em_emu.c\"/>\r\n <inclusions pattern=\"emlib/em_cmu.c\"/>\r\n <inclusions pattern=\"emlib/em_device.c\"/>\r\n <inclusions pattern=\"emlib/em_chip.c\"/>\r\n <inclusions pattern=\"emlib/em_assert.c\"/>\r\n <inclusions pattern=\"emlib/em_gpio.c\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.board\"/>"}]" projectCommon.sdkId="com.silabs.sdk.stack.super:1.1.1._310456152" projectCommon.toolchainId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904"/>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" name="GNU ARM v7.2.1 - Debug" parent="com.silabs.ide.si32.gcc.cdt.managedbuild.config.gnu.exe">
|
||||
<folderInfo id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904." name="/" resourcePath="">
|
||||
<toolChain id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe.930698941" name="Si32 GNU ARM" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe">
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.2037798819" name="Debug Level" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level" value="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.default" valueType="enumerated"/>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.overrideflash.495029551" name="Override default flash options" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.overrideflash" value="true" valueType="boolean"/>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.flashlength.2021030475" name="LENGTH" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.flashlength" value="0x4000" valueType="string"/>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.overrideram.2020332041" name="Override default RAM options" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.overrideram" value="true" valueType="boolean"/>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.ramorigin.2081162957" name="ORIGIN" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.ramorigin" value="0x20000000" valueType="string"/>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.ramlength.1981650487" name="LENGTH" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.ramlength" value="0x8000" valueType="string"/>
|
||||
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF;com.silabs.ss.framework.debugger.core.BIN;com.silabs.ss.framework.debugger.core.HEX;com.silabs.ss.framework.debugger.core.S37;com.silabs.ss.framework.debugger.core.EBL;com.silabs.ss.framework.debugger.core.GBL" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base.613101530" isAbstract="false" name="Debug Platform" osList="win32,linux,macosx" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base"/>
|
||||
<builder buildPath="${workspace_loc:/efm32boot}/GNU ARM v7.2.1 - Debug" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base.2113865201" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Si32 GNU ARM Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base"/>
|
||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.981192541" name="GNU ARM C Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base">
|
||||
<option id="gnu.c.compiler.option.optimization.level.1400029735" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" value="gnu.c.optimization.level.size" valueType="enumerated"/>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols.115820704" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="DEBUG=1"/>
|
||||
<listOptionValue builtIn="false" value="EFM32JG1B200F128GM32=1"/>
|
||||
</option>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin.422869633" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin" value="true" valueType="boolean"/>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog.384018529" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog" value="true" valueType="boolean"/>
|
||||
<option id="gnu.c.compiler.option.include.paths.749408413" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/inc""/>
|
||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../efm32/inc""/>
|
||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../../fido2""/>
|
||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../../fido2/extensions""/>
|
||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../../tinycbor/src""/>
|
||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../../crypto/sha256""/>
|
||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../../crypto/micro-ecc""/>
|
||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/../../crypto/tiny-AES-c""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/bsp""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/drivers""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/Device/SiliconLabs/EFM32JG1B/Include""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/CMSIS/Include""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/emlib/inc""/>
|
||||
</option>
|
||||
<inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.486237326" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base.856016047" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base">
|
||||
<option id="gnu.cpp.compiler.option.optimization.level.1012646883" name="Optimization Level" superClass="gnu.cpp.compiler.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin.1020668095" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin" value="true" valueType="boolean"/>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog.304697844" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog" value="true" valueType="boolean"/>
|
||||
</tool>
|
||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base.718152493" name="GNU ARM Assembler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base">
|
||||
<option id="gnu.both.asm.option.include.paths.998368574" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/inc""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/bsp""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/drivers""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/Device/SiliconLabs/EFM32JG1B/Include""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/CMSIS/Include""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/emlib/inc""/>
|
||||
</option>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols.604334894" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="EFM32JG1B200F128GM32=1"/>
|
||||
</option>
|
||||
<inputType id="org.eclipse.cdt.core.asmSource.695503458" superClass="org.eclipse.cdt.core.asmSource"/>
|
||||
</tool>
|
||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base.1884456996" name="GNU ARM C Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base">
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs.1998445955" name="No startup or default libs (-nostdlib)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs" value="false" valueType="boolean"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.185802893" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base.1862357894" name="GNU ARM C++ Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base"/>
|
||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.1275127827" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="CMSIS/EFM32PG1B|crypto|efm32|fido2" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
<entry excluding="aes-gcm|micro-ecc/examples|micro-ecc/scripts|micro-ecc/test|tiny-AES-c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="crypto"/>
|
||||
<entry excluding=".settings|CMSIS|docs|emlib|GNU ARM v7.2.1 - Debug|hw|inc|mbedtls|sl_crypto|src/crypto.c|src/main.c|.cproject|.project|EFM32.hwconf|Makefile|src/.crypto.c.swp|src/.device.c.swp|src/app.h" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="efm32"/>
|
||||
<entry excluding=".main.c.swp|crypto.c|ctap_parse.c|main.c|.ctap_errors.h.swp|.ctap.c.swp|.ctap.h.swp|.storage.h.swp|.wallet.c.swp|.wallet.h.swp" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="fido2"/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
<cconfiguration id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904">
|
||||
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" moduleId="org.eclipse.cdt.core.settings" name="GNU ARM v7.2.1 - Release">
|
||||
<macros>
|
||||
<stringMacro name="StudioSdkPath" type="VALUE_PATH_DIR" value="${StudioSdkPathFromID:com.silabs.sdk.stack.super:1.1.1._310456152}"/>
|
||||
<stringMacro name="StudioToolchainPath" type="VALUE_PATH_DIR" value="${StudioToolchainPathFromID:com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904}"/>
|
||||
</macros>
|
||||
<externalSettings/>
|
||||
<extensions>
|
||||
<extension id="com.silabs.ss.framework.debugger.core.HEX" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="com.silabs.ss.framework.debugger.core.EBL" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="com.silabs.ss.framework.debugger.core.GBL" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="com.silabs.ss.framework.debugger.core.BIN" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="com.silabs.ss.framework.debugger.core.S37" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GNU_ELF" point="org.eclipse.cdt.core.BinaryParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
|
||||
</extensions>
|
||||
</storageModule>
|
||||
<storageModule buildConfig.stockConfigId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" cppBuildConfig.builtinIncludes="studio:/sdk/hardware/kit/common/bsp/ studio:/sdk/hardware/kit/SLSTK3401A_EFM32PG/config/ studio:/sdk/hardware/kit/common/drivers/ studio:/sdk/platform/Device/SiliconLabs/EFM32PG1B/Include/ studio:/sdk/platform/CMSIS/Include/ studio:/sdk/platform/emlib/inc/ studio:/sdk/hardware/kit/common/bsp/ studio:/sdk/hardware/kit/SLSTK3401A_EFM32PG/config/ studio:/sdk/hardware/kit/common/drivers/ studio:/sdk/platform/Device/SiliconLabs/EFM32PG1B/Include/ studio:/sdk/platform/CMSIS/Include/ studio:/sdk/platform/emlib/inc/" cppBuildConfig.builtinLibraryFiles="" cppBuildConfig.builtinLibraryNames="" cppBuildConfig.builtinLibraryObjects="" cppBuildConfig.builtinLibraryPaths="" cppBuildConfig.builtinMacros="EFM32PG1B200F256GM48 EFM32PG1B200F256GM48" moduleId="com.silabs.ss.framework.ide.project.core.cpp" projectCommon.referencedModules="[{"builtinExcludes":[],"builtinSources":["emlib/em_gpio.c","emlib/em_system.c","emlib/em_cmu.c","emlib/em_assert.c","emlib/em_emu.c"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.emlib\">\r\n <inclusions pattern=\"emlib/em_system.c\"/>\r\n <inclusions pattern=\"emlib/em_emu.c\"/>\r\n <inclusions pattern=\"emlib/em_cmu.c\"/>\r\n <inclusions pattern=\"emlib/em_device.c\"/>\r\n <inclusions pattern=\"emlib/em_chip.c\"/>\r\n <inclusions pattern=\"emlib/em_assert.c\"/>\r\n <inclusions pattern=\"emlib/em_gpio.c\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.board\"/>"},{"builtinExcludes":[],"builtinSources":["CMSIS/EFM32PG1B/startup_gcc_efm32pg1b.s","CMSIS/EFM32PG1B/system_efm32pg1b.c"],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.part\"/>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.bsp\">\r\n <exclusions pattern=\".*\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.drivers\">\r\n <exclusions pattern=\".*\"/>\r\n</project:MModule>"},{"builtinExcludes":[],"builtinSources":[],"builtin":true,"module":"<project:MModule xmlns:project=\"http://www.silabs.com/ss/Project.ecore\" builtin=\"true\" id=\"com.silabs.sdk.exx32.common.CMSIS\">\r\n <exclusions pattern=\".*\"/>\r\n</project:MModule>"}]" projectCommon.toolchainId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904"/>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" description="" id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904" name="GNU ARM v7.2.1 - Release" parent="com.silabs.ide.si32.gcc.cdt.managedbuild.config.gnu.exe">
|
||||
<folderInfo id="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904." name="/" resourcePath="">
|
||||
<toolChain id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe.1542058136" name="Si32 GNU ARM" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.exe">
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.704282697" name="Debug Level" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level" value="com.silabs.ide.si32.gcc.cdt.managedbuild.toolchain.debug.level.default" valueType="enumerated"/>
|
||||
<targetPlatform binaryParser="org.eclipse.cdt.core.ELF;org.eclipse.cdt.core.GNU_ELF;com.silabs.ss.framework.debugger.core.BIN;com.silabs.ss.framework.debugger.core.HEX;com.silabs.ss.framework.debugger.core.S37;com.silabs.ss.framework.debugger.core.EBL;com.silabs.ss.framework.debugger.core.GBL" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base.67671565" isAbstract="false" name="Debug Platform" osList="win32,linux,macosx" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.platform.base"/>
|
||||
<builder buildPath="${workspace_loc:/efm32boot}/GNU ARM v7.2.1 - Release" id="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base.805468153" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="Si32 GNU ARM Builder" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.target.gnu.builder.base"/>
|
||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1301757596" name="GNU ARM C Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base">
|
||||
<option id="gnu.c.compiler.option.optimization.level.992246362" name="Optimization Level" superClass="gnu.c.compiler.option.optimization.level" value="gnu.c.optimization.level.most" valueType="enumerated"/>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols.1037480919" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.def.symbols" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="NDEBUG=1"/>
|
||||
<listOptionValue builtIn="false" value="EFM32PG1B200F256GM48=1"/>
|
||||
</option>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin.951908916" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.builtin" value="false" valueType="boolean"/>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog.1884913917" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.debug.prolog" value="false" valueType="boolean"/>
|
||||
<option id="gnu.c.compiler.option.include.paths.1968865334" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/inc""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/bsp""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/SLSTK3401A_EFM32PG/config""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/drivers""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/Device/SiliconLabs/EFM32PG1B/Include""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/CMSIS/Include""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/emlib/inc""/>
|
||||
</option>
|
||||
<inputType id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.2075078357" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input"/>
|
||||
</tool>
|
||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base.1495369104" name="GNU ARM C++ Compiler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.base">
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin.1435596684" name="Always branch to builtin functions (-fno-builtin)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.builtin" value="false" valueType="boolean"/>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog.258094144" name="Generate debugger-friendly prologs (-mno-sched-prolog)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.compiler.debug.prolog" value="false" valueType="boolean"/>
|
||||
</tool>
|
||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base.947557425" name="GNU ARM Assembler" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.assembler.base">
|
||||
<option id="gnu.both.asm.option.include.paths.220914305" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${ProjDirPath}/inc""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/bsp""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/SLSTK3401A_EFM32PG/config""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/hardware/kit/common/drivers""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/Device/SiliconLabs/EFM32PG1B/Include""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/CMSIS/Include""/>
|
||||
<listOptionValue builtIn="false" value=""${StudioSdkPath}/platform/emlib/inc""/>
|
||||
</option>
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols.1679775183" name="Defined symbols (-D)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.as.def.symbols" valueType="definedSymbols">
|
||||
<listOptionValue builtIn="false" value="EFM32PG1B200F256GM48=1"/>
|
||||
</option>
|
||||
<inputType id="org.eclipse.cdt.core.asmSource.1025131309" superClass="org.eclipse.cdt.core.asmSource"/>
|
||||
</tool>
|
||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base.158700898" name="GNU ARM C Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.base">
|
||||
<option id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs.1339758179" name="No startup or default libs (-nostdlib)" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.linker.nostdlibs" value="false" valueType="boolean"/>
|
||||
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.1667537250" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
</inputType>
|
||||
</tool>
|
||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base.305372504" name="GNU ARM C++ Linker" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.cpp.linker.base"/>
|
||||
<tool id="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base.29462529" name="GNU ARM Archiver" superClass="com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.archiver.base"/>
|
||||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="efm32/CMSIS/EFM32JG1B|CMSIS/EFM32JG1B" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
</sourceEntries>
|
||||
</configuration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
|
||||
</cconfiguration>
|
||||
</storageModule>
|
||||
<storageModule moduleId="com.silabs.ss.framework.ide.project.core.cpp" project.generation="92" projectCommon.boardIds="brd2500a:0.0.0" projectCommon.buildArtifactType="EXE" projectCommon.importModeId="COPY" projectCommon.partId="mcu.arm.efm32.pg1.efm32pg1b200f256gm48" projectCommon.sdkId="com.silabs.sdk.stack.super:1.1.1._310456152"/>
|
||||
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
|
||||
<project id="efm32boot.com.silabs.ss.framework.ide.project.core.cdt.cdtMbsProjectType.501778116" name="SLS CDT Project" projectType="com.silabs.ss.framework.ide.project.core.cdt.cdtMbsProjectType"/>
|
||||
</storageModule>
|
||||
<storageModule moduleId="org.eclipse.cdt.core.LanguageSettingsProviders"/>
|
||||
<storageModule moduleId="scannerConfiguration">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
<scannerConfigBuildInfo instanceId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904;com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.release#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904.;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.1301757596;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.2075078357">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
<scannerConfigBuildInfo instanceId="com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904;com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt.debug#com.silabs.ss.tool.ide.arm.toolchain.gnu.cdt:7.2.1.20170904.;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.base.981192541;com.silabs.ide.si32.gcc.cdt.managedbuild.tool.gnu.c.compiler.input.486237326">
|
||||
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
|
||||
</scannerConfigBuildInfo>
|
||||
</storageModule>
|
||||
<storageModule moduleId="refreshScope"/>
|
||||
</cproject>
|
@ -1,47 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>efm32boot</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.cdt.core.cnature</nature>
|
||||
<nature>com.silabs.ss.framework.ide.project.sls.core.SLSProjectNature</nature>
|
||||
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
|
||||
</natures>
|
||||
<linkedResources>
|
||||
<link>
|
||||
<name>crypto</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/crypto</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>efm32</name>
|
||||
<type>2</type>
|
||||
<locationURI>$%7BPARENT-1-PROJECT_LOC%7D/efm32</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>fido2</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/fido2</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>CMSIS/EFM32JG1B/startup_gcc_efm32jg1b.s</name>
|
||||
<type>1</type>
|
||||
<locationURI>STUDIO_SDK_LOC/platform/Device/SiliconLabs/EFM32JG1B/Source/GCC/startup_efm32jg1b.S</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>CMSIS/EFM32JG1B/system_efm32jg1b.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>STUDIO_SDK_LOC/platform/Device/SiliconLabs/EFM32JG1B/Source/system_efm32jg1b.c</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
</projectDescription>
|
@ -1,2 +0,0 @@
|
||||
copiedFilesOriginState={}
|
||||
eclipse.preferences.version=1
|
@ -1,317 +0,0 @@
|
||||
/* @file startup_efm32pg1b.S
|
||||
* @brief startup file for Silicon Labs EFM32PG1B devices.
|
||||
* For use with GCC for ARM Embedded Processors
|
||||
* @version 5.2.2
|
||||
* Date: 12 June 2014
|
||||
*
|
||||
*/
|
||||
/* Copyright (c) 2011 - 2014 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
.syntax unified
|
||||
.arch armv7-m
|
||||
.section .stack
|
||||
.align 3
|
||||
#ifdef __STACK_SIZE
|
||||
.equ Stack_Size, __STACK_SIZE
|
||||
#else
|
||||
.equ Stack_Size, 0x00000400
|
||||
#endif
|
||||
.globl __StackTop
|
||||
.globl __StackLimit
|
||||
__StackLimit:
|
||||
.space Stack_Size
|
||||
.size __StackLimit, . - __StackLimit
|
||||
__StackTop:
|
||||
.size __StackTop, . - __StackTop
|
||||
|
||||
.section .heap
|
||||
.align 3
|
||||
#ifdef __HEAP_SIZE
|
||||
.equ Heap_Size, __HEAP_SIZE
|
||||
#else
|
||||
.equ Heap_Size, 0x00000C00
|
||||
#endif
|
||||
.globl __HeapBase
|
||||
.globl __HeapLimit
|
||||
__HeapBase:
|
||||
.if Heap_Size
|
||||
.space Heap_Size
|
||||
.endif
|
||||
.size __HeapBase, . - __HeapBase
|
||||
__HeapLimit:
|
||||
.size __HeapLimit, . - __HeapLimit
|
||||
|
||||
.section .vectors
|
||||
.align 2
|
||||
.globl __Vectors
|
||||
__Vectors:
|
||||
.long __StackTop /* Top of Stack */
|
||||
.long Reset_Handler /* Reset Handler */
|
||||
.long NMI_Handler /* NMI Handler */
|
||||
.long HardFault_Handler /* Hard Fault Handler */
|
||||
.long MemManage_Handler /* MPU Fault Handler */
|
||||
.long BusFault_Handler /* Bus Fault Handler */
|
||||
.long UsageFault_Handler /* Usage Fault Handler */
|
||||
.long Default_Handler /* Reserved */
|
||||
.long Default_Handler /* Reserved */
|
||||
.long Default_Handler /* Reserved */
|
||||
.long Default_Handler /* Reserved */
|
||||
.long SVC_Handler /* SVCall Handler */
|
||||
.long DebugMon_Handler /* Debug Monitor Handler */
|
||||
.long Default_Handler /* Reserved */
|
||||
.long PendSV_Handler /* PendSV Handler */
|
||||
.long SysTick_Handler /* SysTick Handler */
|
||||
|
||||
/* External interrupts */
|
||||
.long EMU_IRQHandler /* 0 - EMU */
|
||||
.long Default_Handler /* 1 - Reserved */
|
||||
.long WDOG0_IRQHandler /* 2 - WDOG0 */
|
||||
.long Default_Handler /* 3 - Reserved */
|
||||
.long Default_Handler /* 4 - Reserved */
|
||||
.long Default_Handler /* 5 - Reserved */
|
||||
.long Default_Handler /* 6 - Reserved */
|
||||
.long Default_Handler /* 7 - Reserved */
|
||||
.long LDMA_IRQHandler /* 8 - LDMA */
|
||||
.long GPIO_EVEN_IRQHandler /* 9 - GPIO_EVEN */
|
||||
.long TIMER0_IRQHandler /* 10 - TIMER0 */
|
||||
.long USART0_RX_IRQHandler /* 11 - USART0_RX */
|
||||
.long USART0_TX_IRQHandler /* 12 - USART0_TX */
|
||||
.long ACMP0_IRQHandler /* 13 - ACMP0 */
|
||||
.long ADC0_IRQHandler /* 14 - ADC0 */
|
||||
.long IDAC0_IRQHandler /* 15 - IDAC0 */
|
||||
.long I2C0_IRQHandler /* 16 - I2C0 */
|
||||
.long GPIO_ODD_IRQHandler /* 17 - GPIO_ODD */
|
||||
.long TIMER1_IRQHandler /* 18 - TIMER1 */
|
||||
.long USART1_RX_IRQHandler /* 19 - USART1_RX */
|
||||
.long USART1_TX_IRQHandler /* 20 - USART1_TX */
|
||||
.long LEUART0_IRQHandler /* 21 - LEUART0 */
|
||||
.long PCNT0_IRQHandler /* 22 - PCNT0 */
|
||||
.long CMU_IRQHandler /* 23 - CMU */
|
||||
.long MSC_IRQHandler /* 24 - MSC */
|
||||
.long CRYPTO_IRQHandler /* 25 - CRYPTO */
|
||||
.long LETIMER0_IRQHandler /* 26 - LETIMER0 */
|
||||
.long Default_Handler /* 27 - Reserved */
|
||||
.long Default_Handler /* 28 - Reserved */
|
||||
.long RTCC_IRQHandler /* 29 - RTCC */
|
||||
.long Default_Handler /* 30 - Reserved */
|
||||
.long CRYOTIMER_IRQHandler /* 31 - CRYOTIMER */
|
||||
.long Default_Handler /* 32 - Reserved */
|
||||
.long FPUEH_IRQHandler /* 33 - FPUEH */
|
||||
|
||||
|
||||
.size __Vectors, . - __Vectors
|
||||
|
||||
.text
|
||||
.thumb
|
||||
.thumb_func
|
||||
.align 2
|
||||
.globl Reset_Handler
|
||||
.type Reset_Handler, %function
|
||||
Reset_Handler:
|
||||
#ifndef __NO_SYSTEM_INIT
|
||||
ldr r0, =SystemInit
|
||||
blx r0
|
||||
#endif
|
||||
|
||||
/* Firstly it copies data from read only memory to RAM. There are two schemes
|
||||
* to copy. One can copy more than one sections. Another can only copy
|
||||
* one section. The former scheme needs more instructions and read-only
|
||||
* data to implement than the latter.
|
||||
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
|
||||
|
||||
#ifdef __STARTUP_COPY_MULTIPLE
|
||||
/* Multiple sections scheme.
|
||||
*
|
||||
* Between symbol address __copy_table_start__ and __copy_table_end__,
|
||||
* there are array of triplets, each of which specify:
|
||||
* offset 0: LMA of start of a section to copy from
|
||||
* offset 4: VMA of start of a section to copy to
|
||||
* offset 8: size of the section to copy. Must be multiply of 4
|
||||
*
|
||||
* All addresses must be aligned to 4 bytes boundary.
|
||||
*/
|
||||
ldr r4, =__copy_table_start__
|
||||
ldr r5, =__copy_table_end__
|
||||
|
||||
.L_loop0:
|
||||
cmp r4, r5
|
||||
bge .L_loop0_done
|
||||
ldr r1, [r4]
|
||||
ldr r2, [r4, #4]
|
||||
ldr r3, [r4, #8]
|
||||
|
||||
.L_loop0_0:
|
||||
subs r3, #4
|
||||
ittt ge
|
||||
ldrge r0, [r1, r3]
|
||||
strge r0, [r2, r3]
|
||||
bge .L_loop0_0
|
||||
|
||||
adds r4, #12
|
||||
b .L_loop0
|
||||
|
||||
.L_loop0_done:
|
||||
#else
|
||||
/* Single section scheme.
|
||||
*
|
||||
* The ranges of copy from/to are specified by following symbols
|
||||
* __etext: LMA of start of the section to copy from. Usually end of text
|
||||
* __data_start__: VMA of start of the section to copy to
|
||||
* __data_end__: VMA of end of the section to copy to
|
||||
*
|
||||
* All addresses must be aligned to 4 bytes boundary.
|
||||
*/
|
||||
ldr r1, =__etext
|
||||
ldr r2, =__data_start__
|
||||
ldr r3, =__data_end__
|
||||
|
||||
.L_loop1:
|
||||
cmp r2, r3
|
||||
ittt lt
|
||||
ldrlt r0, [r1], #4
|
||||
strlt r0, [r2], #4
|
||||
blt .L_loop1
|
||||
#endif /*__STARTUP_COPY_MULTIPLE */
|
||||
|
||||
/* This part of work usually is done in C library startup code. Otherwise,
|
||||
* define this macro to enable it in this startup.
|
||||
*
|
||||
* There are two schemes too. One can clear multiple BSS sections. Another
|
||||
* can only clear one section. The former is more size expensive than the
|
||||
* latter.
|
||||
*
|
||||
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
|
||||
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
|
||||
*/
|
||||
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
|
||||
/* Multiple sections scheme.
|
||||
*
|
||||
* Between symbol address __zero_table_start__ and __zero_table_end__,
|
||||
* there are array of tuples specifying:
|
||||
* offset 0: Start of a BSS section
|
||||
* offset 4: Size of this BSS section. Must be multiply of 4
|
||||
*/
|
||||
ldr r3, =__zero_table_start__
|
||||
ldr r4, =__zero_table_end__
|
||||
|
||||
.L_loop2:
|
||||
cmp r3, r4
|
||||
bge .L_loop2_done
|
||||
ldr r1, [r3]
|
||||
ldr r2, [r3, #4]
|
||||
movs r0, 0
|
||||
|
||||
.L_loop2_0:
|
||||
subs r2, #4
|
||||
itt ge
|
||||
strge r0, [r1, r2]
|
||||
bge .L_loop2_0
|
||||
adds r3, #8
|
||||
b .L_loop2
|
||||
.L_loop2_done:
|
||||
#elif defined (__STARTUP_CLEAR_BSS)
|
||||
/* Single BSS section scheme.
|
||||
*
|
||||
* The BSS section is specified by following symbols
|
||||
* __bss_start__: start of the BSS section.
|
||||
* __bss_end__: end of the BSS section.
|
||||
*
|
||||
* Both addresses must be aligned to 4 bytes boundary.
|
||||
*/
|
||||
ldr r1, =__bss_start__
|
||||
ldr r2, =__bss_end__
|
||||
|
||||
movs r0, 0
|
||||
.L_loop3:
|
||||
cmp r1, r2
|
||||
itt lt
|
||||
strlt r0, [r1], #4
|
||||
blt .L_loop3
|
||||
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
|
||||
|
||||
#ifndef __START
|
||||
#define __START _start
|
||||
#endif
|
||||
bl __START
|
||||
|
||||
.pool
|
||||
.size Reset_Handler, . - Reset_Handler
|
||||
|
||||
.align 1
|
||||
.thumb_func
|
||||
.weak Default_Handler
|
||||
.type Default_Handler, %function
|
||||
Default_Handler:
|
||||
b .
|
||||
.size Default_Handler, . - Default_Handler
|
||||
|
||||
/* Macro to define default handlers. Default handler
|
||||
* will be weak symbol and just dead loops. They can be
|
||||
* overwritten by other handlers */
|
||||
.macro def_irq_handler handler_name
|
||||
.weak \handler_name
|
||||
.set \handler_name, Default_Handler
|
||||
.endm
|
||||
|
||||
def_irq_handler NMI_Handler
|
||||
def_irq_handler HardFault_Handler
|
||||
def_irq_handler MemManage_Handler
|
||||
def_irq_handler BusFault_Handler
|
||||
def_irq_handler UsageFault_Handler
|
||||
def_irq_handler SVC_Handler
|
||||
def_irq_handler DebugMon_Handler
|
||||
def_irq_handler PendSV_Handler
|
||||
def_irq_handler SysTick_Handler
|
||||
|
||||
|
||||
def_irq_handler EMU_IRQHandler
|
||||
def_irq_handler WDOG0_IRQHandler
|
||||
def_irq_handler LDMA_IRQHandler
|
||||
def_irq_handler GPIO_EVEN_IRQHandler
|
||||
def_irq_handler TIMER0_IRQHandler
|
||||
def_irq_handler USART0_RX_IRQHandler
|
||||
def_irq_handler USART0_TX_IRQHandler
|
||||
def_irq_handler ACMP0_IRQHandler
|
||||
def_irq_handler ADC0_IRQHandler
|
||||
def_irq_handler IDAC0_IRQHandler
|
||||
def_irq_handler I2C0_IRQHandler
|
||||
def_irq_handler GPIO_ODD_IRQHandler
|
||||
def_irq_handler TIMER1_IRQHandler
|
||||
def_irq_handler USART1_RX_IRQHandler
|
||||
def_irq_handler USART1_TX_IRQHandler
|
||||
def_irq_handler LEUART0_IRQHandler
|
||||
def_irq_handler PCNT0_IRQHandler
|
||||
def_irq_handler CMU_IRQHandler
|
||||
def_irq_handler MSC_IRQHandler
|
||||
def_irq_handler CRYPTO_IRQHandler
|
||||
def_irq_handler LETIMER0_IRQHandler
|
||||
def_irq_handler RTCC_IRQHandler
|
||||
def_irq_handler CRYOTIMER_IRQHandler
|
||||
def_irq_handler FPUEH_IRQHandler
|
||||
|
||||
.end
|
@ -1,389 +0,0 @@
|
||||
/***************************************************************************//**
|
||||
* @file system_efm32pg1b.c
|
||||
* @brief CMSIS Cortex-M3/M4 System Layer for EFM32 devices.
|
||||
* @version 5.2.2
|
||||
******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2017 Silicon Laboratories, Inc. http://www.silabs.com</b>
|
||||
******************************************************************************
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software.@n
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.@n
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Laboratories, Inc.
|
||||
* has no obligation to support this Software. Silicon Laboratories, Inc. is
|
||||
* providing the Software "AS IS", with no express or implied warranties of any
|
||||
* kind, including, but not limited to, any implied warranties of
|
||||
* merchantability or fitness for any particular purpose or warranties against
|
||||
* infringement of any proprietary rights of a third party.
|
||||
*
|
||||
* Silicon Laboratories, Inc. will not be liable for any consequential,
|
||||
* incidental, or special damages, or any other relief, or for any claim by
|
||||
* any third party, arising from your use of this Software.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "em_device.h"
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** DEFINES ************************************
|
||||
******************************************************************************/
|
||||
|
||||
/** LFRCO frequency, tuned to below frequency during manufacturing. */
|
||||
#define EFM32_LFRCO_FREQ (32768UL)
|
||||
/** ULFRCO frequency */
|
||||
#define EFM32_ULFRCO_FREQ (1000UL)
|
||||
|
||||
/*******************************************************************************
|
||||
************************** LOCAL VARIABLES ********************************
|
||||
******************************************************************************/
|
||||
|
||||
/* System oscillator frequencies. These frequencies are normally constant */
|
||||
/* for a target, but they are made configurable in order to allow run-time */
|
||||
/* handling of different boards. The crystal oscillator clocks can be set */
|
||||
/* compile time to a non-default value by defining respective EFM_nFXO_FREQ */
|
||||
/* values according to board design. By defining the EFM_nFXO_FREQ to 0, */
|
||||
/* one indicates that the oscillator is not present, in order to save some */
|
||||
/* SW footprint. */
|
||||
|
||||
#ifndef EFM32_HFRCO_MAX_FREQ
|
||||
/** Maximum HFRCO frequency */
|
||||
#define EFM32_HFRCO_MAX_FREQ (38000000UL)
|
||||
#endif
|
||||
|
||||
#ifndef EFM32_HFXO_FREQ
|
||||
/** HFXO frequency */
|
||||
#define EFM32_HFXO_FREQ (40000000UL)
|
||||
#endif
|
||||
|
||||
#ifndef EFM32_HFRCO_STARTUP_FREQ
|
||||
/** HFRCO startup frequency */
|
||||
#define EFM32_HFRCO_STARTUP_FREQ (19000000UL)
|
||||
#endif
|
||||
|
||||
|
||||
/* Do not define variable if HF crystal oscillator not present */
|
||||
#if (EFM32_HFXO_FREQ > 0UL)
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
/** System HFXO clock. */
|
||||
static uint32_t SystemHFXOClock = EFM32_HFXO_FREQ;
|
||||
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
|
||||
#endif
|
||||
|
||||
#ifndef EFM32_LFXO_FREQ
|
||||
/** LFXO frequency */
|
||||
#define EFM32_LFXO_FREQ (EFM32_LFRCO_FREQ)
|
||||
#endif
|
||||
/* Do not define variable if LF crystal oscillator not present */
|
||||
#if (EFM32_LFXO_FREQ > 0UL)
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
/** System LFXO clock. */
|
||||
static uint32_t SystemLFXOClock = 32768UL;
|
||||
/** @endcond (DO_NOT_INCLUDE_WITH_DOXYGEN) */
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL VARIABLES *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* System System Clock Frequency (Core Clock).
|
||||
*
|
||||
* @details
|
||||
* Required CMSIS global variable that must be kept up-to-date.
|
||||
*/
|
||||
uint32_t SystemCoreClock = EFM32_HFRCO_STARTUP_FREQ;
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* System HFRCO frequency
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary variable, not part of the CMSIS definition.
|
||||
*
|
||||
* @details
|
||||
* Frequency of the system HFRCO oscillator
|
||||
*/
|
||||
uint32_t SystemHfrcoFreq = EFM32_HFRCO_STARTUP_FREQ;
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
************************** GLOBAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the current core clock frequency.
|
||||
*
|
||||
* @details
|
||||
* Calculate and get the current core clock frequency based on the current
|
||||
* configuration. Assuming that the SystemCoreClock global variable is
|
||||
* maintained, the core clock frequency is stored in that variable as well.
|
||||
* This function will however calculate the core clock based on actual HW
|
||||
* configuration. It will also update the SystemCoreClock global variable.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* The current core clock frequency in Hz.
|
||||
******************************************************************************/
|
||||
uint32_t SystemCoreClockGet(void)
|
||||
{
|
||||
uint32_t ret;
|
||||
uint32_t presc;
|
||||
|
||||
ret = SystemHFClockGet();
|
||||
presc = (CMU->HFCOREPRESC & _CMU_HFCOREPRESC_PRESC_MASK) >>
|
||||
_CMU_HFCOREPRESC_PRESC_SHIFT;
|
||||
ret /= (presc + 1);
|
||||
|
||||
/* Keep CMSIS system clock variable up-to-date */
|
||||
SystemCoreClock = ret;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the maximum core clock frequency.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* The maximum core clock frequency in Hz.
|
||||
******************************************************************************/
|
||||
uint32_t SystemMaxCoreClockGet(void)
|
||||
{
|
||||
return (EFM32_HFRCO_MAX_FREQ > EFM32_HFXO_FREQ ? \
|
||||
EFM32_HFRCO_MAX_FREQ : EFM32_HFXO_FREQ);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Get the current HFCLK frequency.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* The current HFCLK frequency in Hz.
|
||||
******************************************************************************/
|
||||
uint32_t SystemHFClockGet(void)
|
||||
{
|
||||
uint32_t ret;
|
||||
|
||||
switch (CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK)
|
||||
{
|
||||
case CMU_HFCLKSTATUS_SELECTED_LFXO:
|
||||
#if (EFM32_LFXO_FREQ > 0)
|
||||
ret = SystemLFXOClock;
|
||||
#else
|
||||
/* We should not get here, since core should not be clocked. May */
|
||||
/* be caused by a misconfiguration though. */
|
||||
ret = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case CMU_HFCLKSTATUS_SELECTED_LFRCO:
|
||||
ret = EFM32_LFRCO_FREQ;
|
||||
break;
|
||||
|
||||
case CMU_HFCLKSTATUS_SELECTED_HFXO:
|
||||
#if (EFM32_HFXO_FREQ > 0)
|
||||
ret = SystemHFXOClock;
|
||||
#else
|
||||
/* We should not get here, since core should not be clocked. May */
|
||||
/* be caused by a misconfiguration though. */
|
||||
ret = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default: /* CMU_HFCLKSTATUS_SELECTED_HFRCO */
|
||||
ret = SystemHfrcoFreq;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret / (1U + ((CMU->HFPRESC & _CMU_HFPRESC_PRESC_MASK)
|
||||
>> _CMU_HFPRESC_PRESC_SHIFT));
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Get high frequency crystal oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* HFXO frequency in Hz.
|
||||
*****************************************************************************/
|
||||
uint32_t SystemHFXOClockGet(void)
|
||||
{
|
||||
/* External crystal oscillator present? */
|
||||
#if (EFM32_HFXO_FREQ > 0)
|
||||
return SystemHFXOClock;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Set high frequency crystal oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This function is mainly provided for being able to handle target systems
|
||||
* with different HF crystal oscillator frequencies run-time. If used, it
|
||||
* should probably only be used once during system startup.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @param[in] freq
|
||||
* HFXO frequency in Hz used for target.
|
||||
*****************************************************************************/
|
||||
void SystemHFXOClockSet(uint32_t freq)
|
||||
{
|
||||
/* External crystal oscillator present? */
|
||||
#if (EFM32_HFXO_FREQ > 0)
|
||||
SystemHFXOClock = freq;
|
||||
|
||||
/* Update core clock frequency if HFXO is used to clock core */
|
||||
if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_HFXO)
|
||||
{
|
||||
/* The function will update the global variable */
|
||||
SystemCoreClockGet();
|
||||
}
|
||||
#else
|
||||
(void)freq; /* Unused parameter */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Initialize the system.
|
||||
*
|
||||
* @details
|
||||
* Do required generic HW system init.
|
||||
*
|
||||
* @note
|
||||
* This function is invoked during system init, before the main() routine
|
||||
* and any data has been initialized. For this reason, it cannot do any
|
||||
* initialization of variables etc.
|
||||
*****************************************************************************/
|
||||
void SystemInit(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
|
||||
/* Set floating point coprosessor access mode. */
|
||||
SCB->CPACR |= ((3UL << 10*2) | /* set CP10 Full Access */
|
||||
(3UL << 11*2) ); /* set CP11 Full Access */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Get low frequency RC oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* LFRCO frequency in Hz.
|
||||
*****************************************************************************/
|
||||
uint32_t SystemLFRCOClockGet(void)
|
||||
{
|
||||
/* Currently we assume that this frequency is properly tuned during */
|
||||
/* manufacturing and is not changed after reset. If future requirements */
|
||||
/* for re-tuning by user, we can add support for that. */
|
||||
return EFM32_LFRCO_FREQ;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Get ultra low frequency RC oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* ULFRCO frequency in Hz.
|
||||
*****************************************************************************/
|
||||
uint32_t SystemULFRCOClockGet(void)
|
||||
{
|
||||
/* The ULFRCO frequency is not tuned, and can be very inaccurate */
|
||||
return EFM32_ULFRCO_FREQ;
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Get low frequency crystal oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @return
|
||||
* LFXO frequency in Hz.
|
||||
*****************************************************************************/
|
||||
uint32_t SystemLFXOClockGet(void)
|
||||
{
|
||||
/* External crystal oscillator present? */
|
||||
#if (EFM32_LFXO_FREQ > 0)
|
||||
return SystemLFXOClock;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************************//**
|
||||
* @brief
|
||||
* Set low frequency crystal oscillator clock frequency for target system.
|
||||
*
|
||||
* @note
|
||||
* This function is mainly provided for being able to handle target systems
|
||||
* with different HF crystal oscillator frequencies run-time. If used, it
|
||||
* should probably only be used once during system startup.
|
||||
*
|
||||
* @note
|
||||
* This is an EFM32 proprietary function, not part of the CMSIS definition.
|
||||
*
|
||||
* @param[in] freq
|
||||
* LFXO frequency in Hz used for target.
|
||||
*****************************************************************************/
|
||||
void SystemLFXOClockSet(uint32_t freq)
|
||||
{
|
||||
/* External crystal oscillator present? */
|
||||
#if (EFM32_LFXO_FREQ > 0)
|
||||
SystemLFXOClock = freq;
|
||||
|
||||
/* Update core clock frequency if LFXO is used to clock core */
|
||||
if ((CMU->HFCLKSTATUS & _CMU_HFCLKSTATUS_SELECTED_MASK) == CMU_HFCLKSTATUS_SELECTED_LFXO)
|
||||
{
|
||||
/* The function will update the global variable */
|
||||
SystemCoreClockGet();
|
||||
}
|
||||
#else
|
||||
(void)freq; /* Unused parameter */
|
||||
#endif
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="ASCII"?>
|
||||
<device:XMLDevice xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:device="http://www.silabs.com/ss/hwconfig/document/device.ecore" name="EFM32PG1B200F256GM48" partId="mcu.arm.efm32.pg1.efm32pg1b200f256gm48" contextId="%DEFAULT%">
|
||||
<mode name="DefaultMode">
|
||||
<property object="DefaultMode" propertyId="mode.diagramLocation" value="100, 100"/>
|
||||
</mode>
|
||||
<modeTransition>
|
||||
<property object="RESET → DefaultMode" propertyId="modeTransition.source" value="RESET"/>
|
||||
<property object="RESET → DefaultMode" propertyId="modeTransition.target" value="DefaultMode"/>
|
||||
</modeTransition>
|
||||
</device:XMLDevice>
|
@ -1,81 +0,0 @@
|
||||
/***************************************************************************//**
|
||||
* @file em_assert.c
|
||||
* @brief Assert API
|
||||
* @version 5.2.2
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
|
||||
* obligation to support this Software. Silicon Labs is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Silicon Labs will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "em_assert.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup emlib
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup ASSERT
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(DEBUG_EFM)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* EFM internal assert handling.
|
||||
*
|
||||
* This function is invoked through EFM_ASSERT() macro usage only, it should
|
||||
* not be used explicitly.
|
||||
*
|
||||
* This implementation simply enters an indefinite loop, allowing
|
||||
* the use of a debugger to determine cause of failure. By defining
|
||||
* DEBUG_EFM_USER to the preprocessor for all files, a user defined version
|
||||
* of this function must be defined and will be invoked instead, possibly
|
||||
* providing output of assertion location.
|
||||
*
|
||||
* @note
|
||||
* This function is not used unless @ref DEBUG_EFM is defined
|
||||
* during preprocessing of EFM_ASSERT() usage.
|
||||
*
|
||||
* @param[in] file
|
||||
* Name of source file where assertion failed.
|
||||
*
|
||||
* @param[in] line
|
||||
* Line number in source file where assertion failed.
|
||||
******************************************************************************/
|
||||
void assertEFM(const char *file, int line)
|
||||
{
|
||||
(void)file; /* Unused parameter */
|
||||
(void)line; /* Unused parameter */
|
||||
|
||||
while (true) {
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG_EFM */
|
||||
|
||||
/** @} (end addtogroup ASSERT) */
|
||||
/** @} (end addtogroup emlib) */
|
File diff suppressed because it is too large
Load Diff
@ -1,61 +0,0 @@
|
||||
/***************************************************************************//**
|
||||
* @file em_cryotimer.c
|
||||
* @brief Ultra Low Energy Timer/Counter (CRYOTIMER) peripheral API
|
||||
* @version 5.2.2
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2016 Silicon Laboratories, Inc. http://www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software.@n
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.@n
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
* DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no
|
||||
* obligation to support this Software. Silicon Labs is providing the
|
||||
* Software "AS IS", with no express or implied warranties of any kind,
|
||||
* including, but not limited to, any implied warranties of merchantability
|
||||
* or fitness for any particular purpose or warranties against infringement
|
||||
* of any proprietary rights of a third party.
|
||||
*
|
||||
* Silicon Labs will not be liable for any consequential, incidental, or
|
||||
* special damages, or any other relief, or for any claim by any third party,
|
||||
* arising from your use of this Software.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "em_cryotimer.h"
|
||||
#include "em_bus.h"
|
||||
|
||||
#if defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT == 1)
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize the CRYOTIMER.
|
||||
*
|
||||
* @details
|
||||
* Use this function to initialize the CRYOTIMER.
|
||||
* Select prescaler setting and select low frequency oscillator.
|
||||
* Refer to the configuration structure @ref CRYOTIMER_Init_TypeDef for more
|
||||
* details.
|
||||
*
|
||||
* @param[in] init
|
||||
* Pointer to initialization structure.
|
||||
******************************************************************************/
|
||||
void CRYOTIMER_Init(const CRYOTIMER_Init_TypeDef *init)
|
||||
{
|
||||
CRYOTIMER->PERIODSEL = (uint32_t)init->period & _CRYOTIMER_PERIODSEL_MASK;
|
||||
CRYOTIMER->CTRL = ((uint32_t)init->enable << _CRYOTIMER_CTRL_EN_SHIFT)
|
||||
| ((uint32_t)init->debugRun << _CRYOTIMER_CTRL_DEBUGRUN_SHIFT)
|
||||
| ((uint32_t)init->osc << _CRYOTIMER_CTRL_OSCSEL_SHIFT)
|
||||
| ((uint32_t)init->presc << _CRYOTIMER_CTRL_PRESC_SHIFT);
|
||||
CRYOTIMER_EM4WakeupEnable(init->em4Wakeup);
|
||||
}
|
||||
|
||||
#endif /* defined(CRYOTIMER_PRESENT) && (CRYOTIMER_COUNT > 0) */
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user