mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge #18547
18547: sys: PSA Crypto API implementation r=MrKevinWeiss a=Einhornhool ### Contribution description This adds an implementation of the ARM [PSA Crypto API](https://armmbed.github.io/mbed-crypto/html/index.html) specification to RIOT. It is a cryptographic API that supports software and hardware backends as well as the use of multiple secure elements, which can be configured with Kconfig. It integrates indirect, identifier based key management to support persistent storage of key material in local memory and devices with protected key storage. A description of the implementation design and an evaluation of the processing time and memory overhead in RIOT has been published here: [Usable Security for an IoT OS: Integrating the Zoo of Embedded Crypto Components Below a Common API](https://arxiv.org/abs/2208.09281) #### Implementation status So far this implementation supports the following operations: - Volatile key storage - AES in CBC mode - Hashes (MD5, SHA1, SHA224, SHA256) - HMAC SHA256 - ECDSA with NIST P192 and P256 curves The following backends are supported so far: - RIOT Cipher Module - RIOT Hash Module - Micro ECC library package - Cryptocell 310 hardware accelerator on the Nordic NRF52840dk - Microchip ATECC608A secure element Other operations and backends as well as persistent key storage can and will be implemented by me and anyone who wants to contribute in the future. ### Testing procedure So far there is a show case application in `examples/psa_crypto` to demonstrate the usage and configuration of different backends of the API (refer to the application README for more information). Co-authored-by: Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
This commit is contained in:
commit
9be022afd8
@ -36,7 +36,15 @@ static const i2c_conf_t i2c_config[] = {
|
||||
.scl = 27,
|
||||
.sda = 26,
|
||||
.speed = I2C_SPEED_NORMAL
|
||||
},
|
||||
#ifdef BOARD_NRF52840DK
|
||||
{
|
||||
.dev = NRF_TWIM0,
|
||||
.scl = 28,
|
||||
.sda = 29,
|
||||
.speed = I2C_SPEED_NORMAL
|
||||
}
|
||||
#endif
|
||||
};
|
||||
#define I2C_NUMOF ARRAY_SIZE(i2c_config)
|
||||
/** @} */
|
||||
|
@ -69,6 +69,15 @@ config CPU_MODEL_NRF52840XXAA
|
||||
select HAS_BLE_PHY_CODED
|
||||
select HAS_RADIO_NRF802154
|
||||
select HAS_PERIPH_UART_NONBLOCKING
|
||||
select HAS_PERIPH_HASH_SHA_1
|
||||
select HAS_PERIPH_HASH_SHA_224
|
||||
select HAS_PERIPH_HASH_SHA_256
|
||||
select HAS_PERIPH_HASH_SHA_512
|
||||
select HAS_PERIPH_HMAC_SHA_256
|
||||
select HAS_PERIPH_CIPHER_AES_128_CBC
|
||||
select HAS_PERIPH_ECC_P192R1
|
||||
select HAS_PERIPH_ECC_P256R1
|
||||
select HAS_PERIPH_CRYPTOCELL_310
|
||||
|
||||
## CPU common symbols
|
||||
config CPU_FAM
|
||||
|
@ -36,5 +36,6 @@ ifneq (,$(filter periph_spi,$(USEMODULE)))
|
||||
USEMODULE += periph_spi_gpio_mode
|
||||
endif
|
||||
|
||||
include $(RIOTCPU)/nrf52/periph/Makefile.dep
|
||||
include $(RIOTCPU)/nrf5x_common/Makefile.dep
|
||||
include $(RIOTCPU)/cortexm_common/Makefile.dep
|
||||
|
@ -10,6 +10,18 @@ ifneq (,$(filter nrf52811xxaa nrf52820xxaa nrf52833xxaa nrf52840xxaa,$(CPU_MODEL
|
||||
FEATURES_PROVIDED += radio_nrf802154
|
||||
endif
|
||||
|
||||
# crypto features
|
||||
ifneq (,$(filter nrf52840xxaa,$(CPU_MODEL)))
|
||||
FEATURES_PROVIDED += periph_hash_sha_1
|
||||
FEATURES_PROVIDED += periph_hash_sha_224
|
||||
FEATURES_PROVIDED += periph_hash_sha_256
|
||||
FEATURES_PROVIDED += periph_hash_sha_512
|
||||
FEATURES_PROVIDED += periph_hmac_sha_256
|
||||
FEATURES_PROVIDED += periph_cipher_aes_128_cbc
|
||||
FEATURES_PROVIDED += periph_ecc_p192r1
|
||||
FEATURES_PROVIDED += periph_ecc_p256r1
|
||||
endif
|
||||
|
||||
ifeq (,$(filter nrf52832%,$(CPU_MODEL)))
|
||||
FEATURES_PROVIDED += periph_uart_nonblocking
|
||||
endif
|
||||
@ -33,6 +45,10 @@ ifneq (,$(filter nrf52811% nrf52820% nrf52833% nrf52840%,$(CPU_MODEL)))
|
||||
FEATURES_PROVIDED += ble_phy_coded
|
||||
endif
|
||||
|
||||
ifneq (,$(filter nrf52840%,$(CPU_MODEL)))
|
||||
FEATURES_PROVIDED += periph_cryptocell_310
|
||||
endif
|
||||
|
||||
FEATURES_PROVIDED += ble_adv_ext
|
||||
|
||||
include $(RIOTCPU)/nrf5x_common/Makefile.features
|
||||
|
@ -12,6 +12,61 @@ config MODULE_SAUL_NRF_VDDH
|
||||
depends on HAS_PERIPH_ADC
|
||||
select MODULE_PERIPH_ADC
|
||||
|
||||
config MODULE_PERIPH_CRYPTOCELL_310
|
||||
bool
|
||||
depends on HAS_PERIPH_CRYPTOCELL_310
|
||||
select PACKAGE_DRIVER_CRYPTOCELL_310
|
||||
|
||||
# Asymmetric Crypto Peripheral
|
||||
config MODULE_PERIPH_ECC_P192R1
|
||||
bool
|
||||
depends on HAS_PERIPH_ECC_P192R1
|
||||
select MODULE_PERIPH_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_ECC_P192
|
||||
|
||||
config MODULE_PERIPH_ECC_P256R1
|
||||
bool
|
||||
depends on HAS_PERIPH_ECC_P256R1
|
||||
select MODULE_PERIPH_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_ECC_P256
|
||||
|
||||
# Hash Related Symbols
|
||||
config MODULE_PERIPH_HASH_SHA_1
|
||||
bool
|
||||
depends on HAS_PERIPH_HASH_SHA_1
|
||||
select MODULE_PERIPH_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_HASHES_SHA1
|
||||
|
||||
config MODULE_PERIPH_HASH_SHA_224
|
||||
bool
|
||||
depends on HAS_PERIPH_HASH_SHA_224
|
||||
select MODULE_PERIPH_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_HASHES_SHA224
|
||||
|
||||
config MODULE_PERIPH_HASH_SHA_256
|
||||
bool
|
||||
depends on HAS_PERIPH_HASH_SHA_256
|
||||
select MODULE_PERIPH_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_HASHES_SHA256
|
||||
|
||||
config MODULE_PERIPH_HASH_SHA_512
|
||||
bool
|
||||
depends on HAS_PERIPH_HASH_SHA_512
|
||||
select MODULE_PERIPH_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_HASHES_SHA512
|
||||
|
||||
config MODULE_PERIPH_CIPHER_AES_128_CBC
|
||||
bool
|
||||
depends on HAS_PERIPH_CIPHER_AES_128_CBC
|
||||
select MODULE_PERIPH_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_AES_CBC
|
||||
|
||||
config MODULE_PERIPH_HMAC_SHA_256
|
||||
bool
|
||||
depends on HAS_PERIPH_HMAC_SHA_256
|
||||
select MODULE_PERIPH_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_HMAC
|
||||
|
||||
endif # TEST_KCONFIG
|
||||
|
||||
config HAVE_SAUL_NRF_VDDH
|
||||
|
39
cpu/nrf52/periph/Makefile.dep
Normal file
39
cpu/nrf52/periph/Makefile.dep
Normal file
@ -0,0 +1,39 @@
|
||||
ifneq (,$(filter periph_ecc_p192r1,$(USEMODULE)))
|
||||
USEPKG += driver_cryptocell_310
|
||||
USEMODULE += psa_cryptocell_310_ecc_p192
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_ecc_p256r1,$(USEMODULE)))
|
||||
USEPKG += driver_cryptocell_310
|
||||
USEMODULE += psa_cryptocell_310_ecc_p256
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_hash_sha_1,$(USEMODULE)))
|
||||
USEPKG += driver_cryptocell_310
|
||||
USEMODULE += psa_cryptocell_310_hashes_sha1
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_hash_sha_224,$(USEMODULE)))
|
||||
USEPKG += driver_cryptocell_310
|
||||
USEMODULE += psa_cryptocell_310_hashes_sha224
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_hash_sha_256,$(USEMODULE)))
|
||||
USEPKG += driver_cryptocell_310
|
||||
USEMODULE += psa_cryptocell_310_hashes_sha256
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_hash_sha_512,$(USEMODULE)))
|
||||
USEPKG += driver_cryptocell_310
|
||||
USEMODULE += psa_cryptocell_310_hashes_sha512
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_cipher_aes_128_cbc,$(USEMODULE)))
|
||||
USEPKG += driver_cryptocell_310
|
||||
USEMODULE += psa_cryptocell_310_aes_cbc
|
||||
endif
|
||||
|
||||
ifneq (,$(filter periph_hmac_sha_256,$(USEMODULE)))
|
||||
USEPKG += driver_cryptocell_310
|
||||
USEMODULE += psa_cryptocell_310_hmac
|
||||
endif
|
6
dist/tools/codespell/ignored_words.txt
vendored
6
dist/tools/codespell/ignored_words.txt
vendored
@ -162,3 +162,9 @@ noe
|
||||
|
||||
# NWE (Negative Write Enable) ==> NEW
|
||||
nwe
|
||||
|
||||
# rsource (used to include Kconfig files) ==> resource, source
|
||||
rsource
|
||||
|
||||
# SHS (abbreviation for Secure Hash Standard) => SSH, NHS
|
||||
shs
|
||||
|
851
doc/doxygen/src/riot-psa-structure.svg
Normal file
851
doc/doxygen/src/riot-psa-structure.svg
Normal file
@ -0,0 +1,851 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
width="500"
|
||||
height="266"
|
||||
id="svg1869"
|
||||
sodipodi:docname="riot-psa-structure.svg"
|
||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14, custom)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<sodipodi:namedview
|
||||
id="namedview1871"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#000000"
|
||||
borderopacity="0.25"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
showgrid="false"
|
||||
inkscape:zoom="1.9539249"
|
||||
inkscape:cx="187.82707"
|
||||
inkscape:cy="175.28821"
|
||||
inkscape:window-width="2556"
|
||||
inkscape:window-height="1396"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="20"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="gnrc-detail" />
|
||||
<title
|
||||
id="title1749">RIOT's GNRC Network Stack</title>
|
||||
<metadata
|
||||
id="metadata1751">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="Provides a general overview over RIOT's GNRC Network Stack">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title>RIOT's GNRC Network Stack</dc:title>
|
||||
<cc:license
|
||||
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>Cenk Gündoğan</dc:title>
|
||||
</cc:Agent>
|
||||
<cc:Agent>
|
||||
<dc:title>Martine Lenders</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
</cc:Work>
|
||||
<cc:License
|
||||
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Reproduction" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#Distribution" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Notice" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#Attribution" />
|
||||
<cc:permits
|
||||
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
|
||||
<cc:requires
|
||||
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs1779">
|
||||
<style
|
||||
type="text/css"
|
||||
id="style1753"><![CDATA[
|
||||
@font-face {
|
||||
font-family: 'Miso';
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
src: url('miso.eot'); /* IE 9 Compatibility Mode */
|
||||
src: url('miso.eot?#iefix') format('embedded-opentype'), /* IE < 9 */
|
||||
url('data:application/x-font-woff;charset=utf-8;base64, \
|
||||
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 \
|
||||
') format('woff'), /* Firefox >= 3.6, any other modern browser */
|
||||
url('miso.ttf') format('truetype'), /* Safari, Android, iOS */
|
||||
url('miso.svg#Miso') format('svg'); /* Chrome < 4, Legacy iOS */
|
||||
}
|
||||
.modbox-text {
|
||||
line-height: 125%;
|
||||
fill: #ffffff;
|
||||
font-family: 'Miso';
|
||||
font-size: 28px;
|
||||
text-anchor: middle;
|
||||
}
|
||||
.modbox {
|
||||
fill: #275a4b;
|
||||
stroke: #3fa687;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-miterlimit: 4;
|
||||
stroke-width: 3;
|
||||
}
|
||||
.outer-text {
|
||||
line-height: 125%;
|
||||
fill: #3fa687;
|
||||
font-family: 'Miso';
|
||||
font-size: 32px;
|
||||
text-anchor: middle;
|
||||
}
|
||||
.outer-text-netapi {
|
||||
line-height: 125%;
|
||||
fill: #3fa687;
|
||||
font-family: 'Miso';
|
||||
font-size: 28px;
|
||||
text-anchor: start;
|
||||
}
|
||||
.outer-stroke {
|
||||
fill: none;
|
||||
stroke: #3fa687;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: miter;
|
||||
stroke-miterlimit: 4;
|
||||
stroke-width: 3;
|
||||
}
|
||||
#gnrc-detail-sock {
|
||||
fill: none;
|
||||
stroke: url(#outer-gradient-sock);
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: miter;
|
||||
stroke-miterlimit: 4;
|
||||
stroke-width: 3;
|
||||
}
|
||||
#gnrc-detail-netdev {
|
||||
fill: none;
|
||||
stroke: url(#outer-gradient-netdev);
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: miter;
|
||||
stroke-miterlimit: 4;
|
||||
stroke-width: 3;
|
||||
}
|
||||
.outer-stroke-dashed {
|
||||
fill: none;
|
||||
stroke: #3fa687;
|
||||
stroke-dasharray: 9, 9;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: miter;
|
||||
stroke-miterlimit: 4;
|
||||
stroke-width: 3;
|
||||
}
|
||||
.outer-stroke-dotted {
|
||||
fill: none;
|
||||
stroke: #3fa687;
|
||||
stroke-dasharray: 1, 5;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: miter;
|
||||
stroke-miterlimit: 4;
|
||||
stroke-width: 3;
|
||||
}
|
||||
.outer-stroke-arrow {
|
||||
fill: none;
|
||||
marker-start: url(#arrow-start);
|
||||
marker-end: url(#arrow-end);
|
||||
stroke: #3fa687;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: miter;
|
||||
stroke-miterlimit: 4;
|
||||
stroke-width: 3;
|
||||
}
|
||||
.outer-arrow-head {
|
||||
fill: #3fa687;
|
||||
fill-rule: evenodd;
|
||||
stroke: #3fa687;
|
||||
stroke-width: 1pt;
|
||||
}
|
||||
]]></style>
|
||||
<linearGradient
|
||||
id="outer-gradient-sock"
|
||||
x1="-0.44030017"
|
||||
y1="-5.1101503"
|
||||
x2="-0.44030017"
|
||||
y2="107.31316"
|
||||
gradientTransform="scale(3.4067669,0.29353344)"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color: #3fa687; stop-opacity: 0;"
|
||||
offset="0"
|
||||
id="stop1755" />
|
||||
<stop
|
||||
style="stop-color: #3fa687; stop-opacity: 0;"
|
||||
offset="0.1"
|
||||
id="stop1757" />
|
||||
<stop
|
||||
style="stop-color: #3fa687; stop-opacity: 1;"
|
||||
offset="0.9"
|
||||
id="stop1759" />
|
||||
<stop
|
||||
style="stop-color: #3fa687; stop-opacity: 1;"
|
||||
offset="1"
|
||||
id="stop1761" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="outer-gradient-netdev"
|
||||
x1="-0.44030017"
|
||||
y1="1221.3259"
|
||||
x2="-0.44030017"
|
||||
y2="1333.7491"
|
||||
gradientTransform="scale(3.4067669,0.29353344)"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop
|
||||
style="stop-color: #3fa687; stop-opacity: 1;"
|
||||
offset="0"
|
||||
id="stop1764" />
|
||||
<stop
|
||||
style="stop-color: #3fa687; stop-opacity: 1;"
|
||||
offset="0.1"
|
||||
id="stop1766" />
|
||||
<stop
|
||||
style="stop-color: #3fa687; stop-opacity: 0;"
|
||||
offset="0.9"
|
||||
id="stop1768" />
|
||||
<stop
|
||||
style="stop-color: #3fa687; stop-opacity: 0;"
|
||||
offset="1"
|
||||
id="stop1770" />
|
||||
</linearGradient>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="arrow-start"
|
||||
orient="auto">
|
||||
<path
|
||||
class="outer-arrow-head"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
transform="matrix(0.2,0,0,0.2,1.2,0)"
|
||||
id="path1773" />
|
||||
</marker>
|
||||
<marker
|
||||
style="overflow:visible"
|
||||
id="arrow-end"
|
||||
orient="auto">
|
||||
<path
|
||||
class="outer-arrow-head"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
transform="matrix(-0.2,0,0,-0.2,-1.2,0)"
|
||||
id="path1776" />
|
||||
</marker>
|
||||
</defs>
|
||||
<g
|
||||
id="gnrc-detail"
|
||||
transform="matrix(0.75,0,0,0.75,3.75,0)">
|
||||
<g
|
||||
id="g8922">
|
||||
<rect
|
||||
id="gnrc-sock-box"
|
||||
class="modbox"
|
||||
x="9.759263"
|
||||
y="17.349091"
|
||||
rx="7.0792012"
|
||||
ry="4.0499377"
|
||||
width="637.12817"
|
||||
height="50.624222"
|
||||
style="stroke-width:2.70911;stroke-dasharray:none" />
|
||||
<text
|
||||
id="gnrc-sock-label"
|
||||
class="modbox-text"
|
||||
x="328.18332"
|
||||
y="51.050667"><tspan
|
||||
id="tspan1785">PSA Crypto</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g3901"
|
||||
transform="matrix(0.99993339,0,0,1.0321558,-0.71650498,84.465735)"
|
||||
style="stroke-width:2.62489;stroke-dasharray:none">
|
||||
<rect
|
||||
id="gnrc-sock-box-6"
|
||||
class="modbox"
|
||||
x="10.476466"
|
||||
y="0.47646618"
|
||||
rx="7.0796728"
|
||||
ry="3.9237654"
|
||||
width="637.17059"
|
||||
height="49.04707"
|
||||
style="fill:#275a4b;stroke:#3fa687;stroke-width:2.62489;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<text
|
||||
id="gnrc-sock-label-7"
|
||||
class="modbox-text"
|
||||
x="328.92175"
|
||||
y="32"
|
||||
style="font-size:28px;line-height:125%;font-family:Miso;text-anchor:middle;fill:#ffffff;stroke-width:2.62489;stroke-dasharray:none"><tspan
|
||||
id="tspan1785-5"
|
||||
style="stroke-width:2.62489;stroke-dasharray:none">Key Management and Location Dispatch</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g3896"
|
||||
transform="translate(43.403416,87.323162)">
|
||||
<rect
|
||||
id="gnrc-sock-box-6-5"
|
||||
class="modbox"
|
||||
x="293.2406"
|
||||
y="65.227448"
|
||||
rx="3.4473193"
|
||||
ry="4.052392"
|
||||
width="310.25876"
|
||||
height="50.6549"
|
||||
style="fill:#275a4b;stroke:#3fa687;stroke-width:2.67843;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<text
|
||||
id="gnrc-sock-label-7-6"
|
||||
class="modbox-text"
|
||||
x="448.90601"
|
||||
y="97.554901"
|
||||
style="font-size:28px;line-height:125%;font-family:Miso;text-anchor:middle;fill:#ffffff"><tspan
|
||||
id="tspan1785-5-2">Algorithm Dispatch</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g3896-2"
|
||||
transform="matrix(0.99996209,0,0,1.0088791,43.420411,154.13341)">
|
||||
<rect
|
||||
id="gnrc-sock-box-6-5-0"
|
||||
class="modbox"
|
||||
x="293.23471"
|
||||
y="65.450356"
|
||||
rx="3.4474499"
|
||||
ry="4.016727"
|
||||
width="310.27051"
|
||||
height="50.209087"
|
||||
style="fill:#275a4b;stroke:#3fa687;stroke-width:2.66667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<text
|
||||
id="gnrc-sock-label-7-6-23"
|
||||
class="modbox-text"
|
||||
x="448.90601"
|
||||
y="97.554901"
|
||||
style="font-size:28px;line-height:125%;font-family:Miso;text-anchor:middle;fill:#ffffff"><tspan
|
||||
id="tspan1785-5-2-75">Spec. Algorithm API</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g7406"
|
||||
transform="matrix(0.99996307,0,0,1.0086479,0.00608848,0.69035637)">
|
||||
<rect
|
||||
id="gnrc-sock-box-6-5-1"
|
||||
class="modbox"
|
||||
x="9.7380409"
|
||||
y="150.56415"
|
||||
rx="3.4474499"
|
||||
ry="4.016727"
|
||||
width="310.27051"
|
||||
height="50.209087"
|
||||
style="fill:#275a4b;stroke:#3fa687;stroke-width:2.66667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<text
|
||||
id="gnrc-sock-label-7-6-2"
|
||||
class="modbox-text"
|
||||
x="164.89879"
|
||||
y="182.05269"
|
||||
style="font-size:28px;line-height:125%;font-family:Miso;text-anchor:middle;fill:#ffffff"><tspan
|
||||
id="tspan1785-5-2-7">SE Dispatch</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g5505"
|
||||
transform="matrix(1.0002158,0,0,0.98547915,-282.22812,86.706483)">
|
||||
<rect
|
||||
id="gnrc-sock-box-6-5-1-9"
|
||||
class="modbox"
|
||||
x="291.89359"
|
||||
y="135.4252"
|
||||
rx="0.98559189"
|
||||
ry="4.1146121"
|
||||
width="88.70327"
|
||||
height="51.432655"
|
||||
style="fill:#275a4b;stroke:#3fa687;stroke-width:2.66667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<text
|
||||
id="gnrc-sock-label-7-6-2-3"
|
||||
class="modbox-text"
|
||||
x="336.57822"
|
||||
y="170.04283"
|
||||
style="font-size:28px;line-height:125%;font-family:Miso;text-anchor:middle;fill:#ffffff"><tspan
|
||||
id="tspan1785-5-2-7-6">SE API</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g5505-0"
|
||||
transform="matrix(1.0002158,0,0,0.98547915,-172.47439,86.706483)">
|
||||
<rect
|
||||
id="gnrc-sock-box-6-5-1-9-6"
|
||||
class="modbox"
|
||||
x="291.89359"
|
||||
y="135.4252"
|
||||
rx="0.98559189"
|
||||
ry="4.1146121"
|
||||
width="88.70327"
|
||||
height="51.432655"
|
||||
style="fill:#275a4b;stroke:#3fa687;stroke-width:2.66667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<text
|
||||
id="gnrc-sock-label-7-6-2-3-2"
|
||||
class="modbox-text"
|
||||
x="336.57822"
|
||||
y="170.04283"
|
||||
style="font-size:28px;line-height:125%;font-family:Miso;text-anchor:middle;fill:#ffffff"><tspan
|
||||
id="tspan1785-5-2-7-6-6">SE API</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g5505-1"
|
||||
transform="matrix(1.0002158,0,0,0.98547915,-62.864627,86.706483)">
|
||||
<rect
|
||||
id="gnrc-sock-box-6-5-1-9-8"
|
||||
class="modbox"
|
||||
x="291.89359"
|
||||
y="135.4252"
|
||||
rx="0.98559189"
|
||||
ry="4.1146121"
|
||||
width="88.70327"
|
||||
height="51.432655"
|
||||
style="fill:#275a4b;stroke:#3fa687;stroke-width:2.66667;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<text
|
||||
id="gnrc-sock-label-7-6-2-3-7"
|
||||
class="modbox-text"
|
||||
x="336.57822"
|
||||
y="170.04283"
|
||||
style="font-size:28px;line-height:125%;font-family:Miso;text-anchor:middle;fill:#ffffff"><tspan
|
||||
id="tspan1785-5-2-7-6-9">SE API</tspan></text>
|
||||
</g>
|
||||
<rect
|
||||
id="gnrc-sock-box-6-5-1-9-2"
|
||||
class="modbox"
|
||||
x="9.7284555"
|
||||
y="287.78241"
|
||||
rx="0.98580456"
|
||||
ry="4.0548644"
|
||||
width="88.722412"
|
||||
height="50.68581"
|
||||
style="fill:#b6e0d3;fill-opacity:1;stroke:#3fa687;stroke-width:2.64752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<text
|
||||
id="gnrc-sock-label-7-6-2-3-8"
|
||||
class="modbox-text"
|
||||
x="54.020325"
|
||||
y="324.29523"
|
||||
style="font-size:27.799px;line-height:125%;font-family:Miso;text-anchor:middle;fill:#275a4b;fill-opacity:1;stroke-width:0.99282"
|
||||
transform="scale(1.0074492,0.99260593)"><tspan
|
||||
id="tspan1785-5-2-7-6-97"
|
||||
style="fill:#275a4b;fill-opacity:1;stroke-width:0.99282">SE1 Drv</tspan></text>
|
||||
<rect
|
||||
id="gnrc-sock-box-6-5-1-9-6-6"
|
||||
class="modbox"
|
||||
x="119.48219"
|
||||
y="287.78241"
|
||||
rx="0.98580456"
|
||||
ry="4.0548644"
|
||||
width="88.722412"
|
||||
height="50.68581"
|
||||
style="fill:#b6e0d3;fill-opacity:1;stroke:#3fa687;stroke-width:2.64752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<text
|
||||
id="gnrc-sock-label-7-6-2-3-2-1"
|
||||
class="modbox-text"
|
||||
x="162.96252"
|
||||
y="324.29523"
|
||||
style="font-size:27.799px;line-height:125%;font-family:Miso;text-anchor:middle;fill:#275a4b;fill-opacity:1;stroke-width:0.99282"
|
||||
transform="scale(1.0074492,0.99260593)"><tspan
|
||||
id="tspan1785-5-2-7-6-6-2"
|
||||
style="fill:#275a4b;fill-opacity:1;stroke-width:0.99282">SE2 Drv</tspan></text>
|
||||
<rect
|
||||
id="gnrc-sock-box-6-5-1-9-8-3"
|
||||
class="modbox"
|
||||
x="229.09195"
|
||||
y="287.78241"
|
||||
rx="0.98580456"
|
||||
ry="4.0548644"
|
||||
width="88.722412"
|
||||
height="50.68581"
|
||||
style="fill:#b6e0d3;fill-opacity:1;stroke:#3fa687;stroke-width:2.64752;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<text
|
||||
id="gnrc-sock-label-7-6-2-3-7-1"
|
||||
class="modbox-text"
|
||||
x="271.76184"
|
||||
y="324.29523"
|
||||
style="font-size:27.799px;line-height:125%;font-family:Miso;text-anchor:middle;fill:#275a4b;fill-opacity:1;stroke-width:0.99282"
|
||||
transform="scale(1.0074492,0.99260593)"><tspan
|
||||
id="tspan1785-5-2-7-6-9-9"
|
||||
style="fill:#275a4b;fill-opacity:1;stroke-width:0.99282">SE3 Drv</tspan></text>
|
||||
<rect
|
||||
id="gnrc-sock-box-6-5-1-9-6-6-7"
|
||||
class="modbox"
|
||||
x="337.05817"
|
||||
y="287.77283"
|
||||
rx="1.6380999"
|
||||
ry="4.0533733"
|
||||
width="147.429"
|
||||
height="50.667171"
|
||||
style="fill:#b6e0d3;fill-opacity:1;stroke:#3fa687;stroke-width:2.66617;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<text
|
||||
id="gnrc-sock-label-7-6-2-3-2-1-8"
|
||||
class="modbox-text"
|
||||
x="410.22644"
|
||||
y="322.06619"
|
||||
style="font-size:27.9947px;line-height:125%;font-family:Miso;text-anchor:middle;fill:#275a4b;fill-opacity:1;stroke-width:2.66617;stroke-dasharray:none"
|
||||
transform="scale(1.0001922,0.99980782)"><tspan
|
||||
id="tspan1785-5-2-7-6-6-2-4"
|
||||
style="fill:#275a4b;fill-opacity:1;stroke-width:2.66617;stroke-dasharray:none">HW Drv</tspan></text>
|
||||
<rect
|
||||
id="gnrc-sock-box-6-5-1-9-6-6-7-0"
|
||||
class="modbox"
|
||||
x="499.10678"
|
||||
y="287.7822"
|
||||
rx="1.6380999"
|
||||
ry="4.0533733"
|
||||
width="147.429"
|
||||
height="50.667171"
|
||||
style="fill:#b6e0d3;fill-opacity:1;stroke:#3fa687;stroke-width:2.66617;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none" />
|
||||
<text
|
||||
id="gnrc-sock-label-7-6-2-3-2-1-8-6"
|
||||
class="modbox-text"
|
||||
x="572.2439"
|
||||
y="322.07556"
|
||||
style="font-size:27.9947px;line-height:125%;font-family:Miso;text-anchor:middle;fill:#275a4b;fill-opacity:1;stroke-width:0.999811"
|
||||
transform="scale(1.0001922,0.99980782)"><tspan
|
||||
id="tspan1785-5-2-7-6-6-2-4-1"
|
||||
style="fill:#275a4b;fill-opacity:1;stroke-width:0.999811">SW Library</tspan></text>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 50 KiB |
116
examples/psa_crypto/Makefile
Normal file
116
examples/psa_crypto/Makefile
Normal file
@ -0,0 +1,116 @@
|
||||
# This has to be the absolute path to the RIOT base directory:
|
||||
RIOTBASE ?= $(CURDIR)/../..
|
||||
|
||||
APPLICATION = example_psa_crypto
|
||||
|
||||
BOARD ?= native
|
||||
|
||||
# Necessary configurations when using Kconfig dependency resolution
|
||||
# The file `app.config.test` is always used for the build configuration.
|
||||
# The config files below are only added if needed.
|
||||
ifeq (1, $(TEST_KCONFIG))
|
||||
ifeq (1, $(SECURE_ELEMENT))
|
||||
CFLAGS += -DSECURE_ELEMENT # Application specific (not needed by PSA)
|
||||
CFLAGS += -DCUSTOM_ATCA_PARAMS # Application specific (not needed by PSA)
|
||||
INCLUDES += -I$(APPDIR) # Application specific (not needed by PSA)
|
||||
KCONFIG_ADD_CONFIG += $(APPDIR)/app.config.test.se
|
||||
else ifeq (2, $(SECURE_ELEMENT))
|
||||
CFLAGS += -DSECURE_ELEMENT # Application specific (not needed by PSA)
|
||||
CFLAGS += -DMULTIPLE_SE # Application specific (not needed by PSA)
|
||||
CFLAGS += -DCUSTOM_ATCA_PARAMS # Application specific (not needed by PSA)
|
||||
INCLUDES += -I$(APPDIR)
|
||||
KCONFIG_ADD_CONFIG += $(APPDIR)/app.config.test.multi_se
|
||||
else ifdef CUSTOM_BACKEND
|
||||
KCONFIG_ADD_CONFIG += $(APPDIR)/app.config.test.base
|
||||
KCONFIG_ADD_CONFIG += $(APPDIR)/app.config.test.custom
|
||||
else
|
||||
KCONFIG_ADD_CONFIG += $(APPDIR)/app.config.test.base
|
||||
endif
|
||||
else
|
||||
USEMODULE += ztimer
|
||||
USEMODULE += ztimer_usec
|
||||
|
||||
USEMODULE += psa_crypto
|
||||
|
||||
# Hashes are needed for ECDSA operations (including secure elements), which
|
||||
# is why we always build them
|
||||
USEMODULE += psa_hash
|
||||
USEMODULE += psa_hash_sha_256
|
||||
|
||||
ifeq (1, $(SECURE_ELEMENT))
|
||||
# When using a secure element, the type is required.
|
||||
# Also you can specify the number of key slots required to store keys.
|
||||
CFLAGS += -DSECURE_ELEMENT # Application specific (not needed by PSA)
|
||||
CFLAGS += -DCUSTOM_ATCA_PARAMS # Application specific (not needed by PSA)
|
||||
INCLUDES += -I$(APPDIR) # Application specific (not needed by PSA)
|
||||
|
||||
CFLAGS += -DCONFIG_PSA_PROTECTED_KEY_COUNT=4
|
||||
CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=1
|
||||
USEMODULE += psa_secure_element
|
||||
USEMODULE += psa_secure_element_ateccx08a
|
||||
USEMODULE += psa_secure_element_ateccx08a_ecc_p256
|
||||
else ifeq (2, $(SECURE_ELEMENT))
|
||||
CFLAGS += -DSECURE_ELEMENT # Application specific (not needed by PSA)
|
||||
CFLAGS += -DMULTIPLE_SE # Application specific (not needed by PSA)
|
||||
CFLAGS += -DCUSTOM_ATCA_PARAMS # Application specific (not needed by PSA)
|
||||
INCLUDES += -I$(APPDIR) # Application specific (not needed by PSA)
|
||||
CFLAGS += -DCONFIG_PSA_MAX_SE_COUNT=2
|
||||
CFLAGS += -DCONFIG_PSA_PROTECTED_KEY_COUNT=8
|
||||
CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=2
|
||||
USEMODULE += psa_secure_element
|
||||
USEMODULE += psa_secure_element_multiple
|
||||
USEMODULE += psa_secure_element_ateccx08a
|
||||
USEMODULE += psa_secure_element_ateccx08a_ecc_p256
|
||||
else ifdef CUSTOM_BACKEND
|
||||
# Necessary configuration when using Make dependency resolution
|
||||
# This first part chooses the operation. If nothing else es specified,
|
||||
# a default backend is built depending on the platform capabilities.
|
||||
USEMODULE += psa_cipher
|
||||
USEMODULE += psa_cipher_aes_128_cbc
|
||||
|
||||
USEMODULE += psa_mac
|
||||
USEMODULE += psa_mac_hmac_sha_256
|
||||
|
||||
USEMODULE += psa_asymmetric
|
||||
USEMODULE += psa_asymmetric_ecc_p256r1
|
||||
|
||||
# If you want to use a custom backend, you need to do it this way.
|
||||
USEMODULE += psa_cipher_aes_128_cbc_custom_backend
|
||||
USEMODULE += psa_cipher_aes_128_cbc_backend_riot # force custom backend
|
||||
|
||||
USEMODULE += psa_mac_hmac_sha_256_custom_backend
|
||||
USEMODULE += psa_mac_hmac_sha_256_backend_riot # force custom backend
|
||||
|
||||
USEMODULE += psa_hash_sha_256_custom_backend
|
||||
USEMODULE += psa_hash_sha_256_backend_riot
|
||||
|
||||
USEMODULE += psa_asymmetric_ecc_p256r1_custom_backend
|
||||
USEMODULE += psa_asymmetric_ecc_p256r1_backend_microecc # force custom backend
|
||||
else
|
||||
# Necessary configuration when using Make dependency resolution
|
||||
# This part only chooses the operation. If nothing else es specified,
|
||||
# a default backend is built depending on the platform capabilities.
|
||||
USEMODULE += psa_cipher
|
||||
USEMODULE += psa_cipher_aes_128_cbc
|
||||
|
||||
USEMODULE += psa_mac
|
||||
USEMODULE += psa_mac_hmac_sha_256
|
||||
|
||||
USEMODULE += psa_asymmetric
|
||||
USEMODULE += psa_asymmetric_ecc_p256r1
|
||||
endif
|
||||
|
||||
ifndef SECURE_ELEMENT
|
||||
CFLAGS += -DCONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1
|
||||
CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=3
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef SECURE_ELEMENT
|
||||
# The software implementations need a larger stack, so we increase the stack size.
|
||||
CFLAGS += -DTHREAD_STACKSIZE_MAIN=\(12*THREAD_STACKSIZE_DEFAULT\)
|
||||
endif
|
||||
|
||||
SHOULD_RUN_KCONFIG :=
|
||||
|
||||
include $(RIOTBASE)/Makefile.include
|
28
examples/psa_crypto/Makefile.ci
Normal file
28
examples/psa_crypto/Makefile.ci
Normal file
@ -0,0 +1,28 @@
|
||||
BOARD_INSUFFICIENT_MEMORY := \
|
||||
arduino-duemilanove \
|
||||
arduino-leonardo \
|
||||
arduino-mega2560 \
|
||||
arduino-nano \
|
||||
arduino-uno \
|
||||
atmega328p \
|
||||
atmega328p-xplained-mini \
|
||||
atmega8 \
|
||||
bluepill-stm32f030c8 \
|
||||
i-nucleo-lrwan1 \
|
||||
nucleo-f030r8 \
|
||||
nucleo-f031k6 \
|
||||
nucleo-f042k6 \
|
||||
nucleo-f303k8 \
|
||||
nucleo-f334r8 \
|
||||
nucleo-l011k4 \
|
||||
nucleo-l031k6 \
|
||||
nucleo-l053r8 \
|
||||
samd10-xmini \
|
||||
slstk3400a \
|
||||
stk3200 \
|
||||
stm32f030f4-demo \
|
||||
stm32f0discovery \
|
||||
stm32g0316-disco \
|
||||
stm32l0538-disco \
|
||||
waspmote-pro \
|
||||
#
|
102
examples/psa_crypto/README.md
Normal file
102
examples/psa_crypto/README.md
Normal file
@ -0,0 +1,102 @@
|
||||
# Example Applications for PSA Crypto
|
||||
This example application is supposed to show two things:
|
||||
1. How to use basic functions of the PSA Crypto API
|
||||
2. How to configure the implementation with Kconfig dependency resolution vs. Make dependency resolution
|
||||
|
||||
## Basic usage of PSA Crypto
|
||||
There are three example operations:
|
||||
- AES 128 CBC
|
||||
- HMAC SHA256
|
||||
- ECDSA with a P256 curve
|
||||
|
||||
Each comes in its own sourcefile called `example_<operation>.c`. To see which functions to call to perform each operations, please read the code.
|
||||
|
||||
The application measures the processing times of the example operations. The table below shows the expected runtime values
|
||||
for software and hardware backends as well as secure elements, measured on the nRF52840dk (this is only to show the expected difference, values will differ on other platforms).
|
||||
|
||||
| Operations | Backends | Runtime \[us\] |
|
||||
|-------------|----------------|------------------|
|
||||
| HMAC SHA256 | CryptoCell 310 | 282 |
|
||||
| | RIOT Hashes | 468 |
|
||||
| | ATECC608A | 56376 |
|
||||
| AES 128 CBC | CryptoCell 310 | 140 |
|
||||
| | RIOT Cipher | 295 |
|
||||
| | ATECC608A | 68819 |
|
||||
| ECDSA P256 | CryptoCell 310 | 60931 |
|
||||
| | Micro-ECC | 522424 |
|
||||
| | ATECC608A | 285542 |
|
||||
|
||||
|
||||
## Configuration of the API
|
||||
There are two ways to configure the API: module selection via Kconfig and module selection
|
||||
via Makefiles.
|
||||
|
||||
To see which modules should be chosen for each configuration, please read the Makefile and
|
||||
the `app.config.test.*` files.
|
||||
|
||||
### Kconfig
|
||||
> **NOTE:** In this application all the configurations are in separate app.config files
|
||||
> for demonstration purposes. You can also write all configs into one file or choose them
|
||||
> via `menuconfig`.
|
||||
> To access the GUI, run `TEST_KCONFIG=1 BOARD=<your board> make menuconfig`.
|
||||
|
||||
When building the application with the `TEST_KCONFIG=1` option, the first config file parsed by the build system is `app.config.test`. This selects the PSA Crypto module and other modules our application needs (e.g. ztimer). If you need cryptographic keys, you can specify the number of key slots needed for key storage (the default is set to 5).
|
||||
The graph below shows how the `app.config` files in this application are included.
|
||||
Selections in `app.config.test` are always applied.
|
||||
The others are only added, if you specify the corresponding build option.
|
||||
|
||||
```mermaid
|
||||
flowchart TD;
|
||||
app.config.test -- default --> app.config.test.base;
|
||||
app.config.test.base -- CUSTOM_BACKEND=1 --> app.config.test.custom;
|
||||
app.config.test -- SECURE_ELEMENT=1 --> app.config.test.se;
|
||||
app.config.test -- SECURE_ELEMENT=2 --> app.config.test.multi_se;
|
||||
```
|
||||
If you build this without specifying anything else, the symbols in `app.config.test.base`
|
||||
are added and PSA Crypto will automatically choose a default crypto backend depending on the platform you're building for.
|
||||
For example when your platform is `native`, software implementations are built.
|
||||
When you specify `BOARD=nrf52840dk`, the hardware accelerator of the board will be built.
|
||||
|
||||
If you want to force a custom backend, you can specify that in the Kconfig file. This application already contains the configuration for a custom backend (see `app.config.test.custom`), which will be added to the application build when you define `CUSTOM_BACKEND=1`.
|
||||
|
||||
Instead of or in addition to the default and custom implementations you can use a secure element as a backend (see Section [Using Secure Elements](#using-secure-elements]).
|
||||
Secure elements are independent of the other backends. In this application, when you
|
||||
choose secure elements, they are built instead of the other backends.
|
||||
|
||||
Please note that the build options `CUSTOM_BACKEND` and `SECURE_ELEMENT` only apply to this specific application and have nothing to do with the PSA implementation.
|
||||
|
||||
### Make
|
||||
All the configurations in the Kconfig files can also be applied using Make dependency resolution. The Makefile contains all the modules that must be selected when building the different configurations.
|
||||
They can all be built as described above, but *without* defining TEST_KCONFIG.
|
||||
|
||||
To prevent conflicts when building this application multiple times with different backends, it is best to remove the `bin` directory in between builds.
|
||||
|
||||
## Using Secure Elements
|
||||
> **NOTE:**
|
||||
> Currently this implementation only supports Microchip ATECCX08A devices. Those devices need to be configured and locked to be able to correctly use them.
|
||||
> This implementation assumes that you have done that and that you know your device's configuration.
|
||||
|
||||
You can build this app either with one secure element or two secure elements (`SECURE_ELEMENT=1` or `SECURE_ELEMENT=2`). To be able to use your device, make sure, you've completed the following procedure.
|
||||
|
||||
In the application folder you can find a file called `custom_atca_params.h`, which overwrites the device parameters in `atca_params.h` in the cryptoauthlib package folder.
|
||||
To use more than one secure element, you need to specify device parameters for both of them.
|
||||
This application assumes that you connect two devices with different I2C addresses on the same I2C bus.
|
||||
Alternatively you can connect two devices with the same address on separate buses.
|
||||
You can modify `custom_atca_params.h` according to your device configurations and requirements.
|
||||
|
||||
For PSA Crypto, you also need to define a location value. Here these are defined as `PSA_ATCA_LOCATION_DEV0` and `PSA_ATCA_LOCATION_DEV1`. They can be any value between `PSA_KEY_LOCATION_SE_MIN` and `PSA_KEY_LOCATION_SE_MAX`.
|
||||
A special value is `PSA_KEY_LOCATION_PRIMARY_SECURE_ELEMENT`, which can be used when only one secure element is needed.
|
||||
|
||||
Below the `ATCA_PARAMS` definitions, you can see the slot configurations.
|
||||
Here you need to specify for each connected secure element what kind of key can be stored in which slot, and whether a slot is already occupied. The structure is declared in `pkg/cryptoauthlib/include/atca.h` and contains the following elements:
|
||||
1. `key_type_allowed` (takes `psa_key_type_t`)
|
||||
2. `key_persistent` (is 0, can be ignored for now, since PSA does not yet support persistent storage)
|
||||
3. `slot_occupied` (should be 0 at start up, PSA will use this to mark slots as occupied)
|
||||
|
||||
The list in `custom_atca_params.h` contains an example configuration. If your device configuration is not compatible, you'll need to change the values as necessary.
|
||||
This is required, so the implementation can allocate free key slots and can generate and import new keys. If the device configuration does not match the values in the list or if your key slots are not writeable, you will get execution errors.
|
||||
|
||||
The current implementation does not support the use of keys that are already stored on the device.
|
||||
|
||||
## Note
|
||||
If you need more information about the build options, please refer to the API documentation.
|
6
examples/psa_crypto/app.config.test
Normal file
6
examples/psa_crypto/app.config.test
Normal file
@ -0,0 +1,6 @@
|
||||
CONFIG_MODULE_PSA_CRYPTO=y
|
||||
|
||||
CONFIG_MODULE_PSA_HASH=y
|
||||
CONFIG_MODULE_PSA_HASH_SHA_256=y
|
||||
|
||||
CONFIG_ZTIMER_USEC=y
|
11
examples/psa_crypto/app.config.test.base
Normal file
11
examples/psa_crypto/app.config.test.base
Normal file
@ -0,0 +1,11 @@
|
||||
CONFIG_MODULE_PSA_CIPHER=y
|
||||
CONFIG_MODULE_PSA_CIPHER_AES_128_CBC=y
|
||||
|
||||
CONFIG_MODULE_PSA_MAC=y
|
||||
CONFIG_MODULE_PSA_MAC_HMAC_SHA_256=y
|
||||
|
||||
CONFIG_MODULE_PSA_ASYMMETRIC=y
|
||||
CONFIG_MODULE_PSA_ASYMMETRIC_ECC_P256R1=y
|
||||
|
||||
CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1
|
||||
CONFIG_PSA_SINGLE_KEY_COUNT=3
|
8
examples/psa_crypto/app.config.test.custom
Normal file
8
examples/psa_crypto/app.config.test.custom
Normal file
@ -0,0 +1,8 @@
|
||||
# force software backends
|
||||
CONFIG_MODULE_PSA_CIPHER_AES_128_CBC_BACKEND_RIOT=y
|
||||
CONFIG_MODULE_PSA_HASH_SHA_256_BACKEND_RIOT=y
|
||||
CONFIG_MODULE_PSA_MAC_HMAC_SHA_256_BACKEND_RIOT=y
|
||||
CONFIG_MODULE_PSA_ASYMMETRIC_ECC_P256R1_BACKEND_MICROECC=y
|
||||
|
||||
CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1
|
||||
CONFIG_PSA_SINGLE_KEY_COUNT=3
|
9
examples/psa_crypto/app.config.test.multi_se
Normal file
9
examples/psa_crypto/app.config.test.multi_se
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT=y
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT_ATECCX08A=y
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256=y
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT_MULTIPLE=y
|
||||
|
||||
CONFIG_PSA_MAX_SE_COUNT=2
|
||||
CONFIG_PSA_PROTECTED_KEY_COUNT=8
|
||||
CONFIG_PSA_SINGLE_KEY_COUNT=2
|
6
examples/psa_crypto/app.config.test.se
Normal file
6
examples/psa_crypto/app.config.test.se
Normal file
@ -0,0 +1,6 @@
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT=y
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT_ATECCX08A=y
|
||||
CONFIG_MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256=y
|
||||
|
||||
CONFIG_PSA_PROTECTED_KEY_COUNT=4
|
||||
CONFIG_PSA_SINGLE_KEY_COUNT=1
|
125
examples/psa_crypto/custom_atca_params.h
Normal file
125
examples/psa_crypto/custom_atca_params.h
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (C) 2023 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Example custom atca_params.h file to use multiple ATECC608A
|
||||
* secure elements as backends for PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
#ifndef CUSTOM_ATCA_PARAMS_H
|
||||
#define CUSTOM_ATCA_PARAMS_H
|
||||
|
||||
#include "cryptoauthlib.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define PSA_ATCA_LOCATION_DEV0 (PSA_KEY_LOCATION_PRIMARY_SECURE_ELEMENT)
|
||||
#define ATCA_PARAM_I2C_DEV0 (I2C_DEV(0)) /*!< Change this to the bus you want to use */
|
||||
#define ATCA_PARAM_ADDR_DEV0 (0xC0) /*!< Change this to your first device's address */
|
||||
#define ATCA_DEVTYPE_DEV0 (ATECC608A)
|
||||
#define ATCA_RX_RETRIES (20)
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
#define PSA_ATCA_LOCATION_DEV1 (PSA_KEY_LOCATION_SE_MIN)
|
||||
#define ATCA_PARAM_I2C_DEV1 (I2C_DEV(0)) /*!< Change this to the bus you want to use */
|
||||
#define ATCA_PARAM_ADDR_DEV1 (0xCC) /*!< Change this to your second device's address */
|
||||
#define ATCA_DEVTYPE_DEV1 (ATECC608A)
|
||||
|
||||
#define ATCA_PARAMS { .atca_loc = PSA_ATCA_LOCATION_DEV0,\
|
||||
.cfg = {\
|
||||
.iface_type = ATCA_I2C_IFACE, \
|
||||
.devtype = ATCA_DEVTYPE_DEV0, \
|
||||
.atcai2c.address = ATCA_PARAM_ADDR_DEV0, \
|
||||
.atcai2c.bus = ATCA_PARAM_I2C_DEV0, \
|
||||
.atcai2c.baud = -1, /**< Not used in RIOT */ \
|
||||
.wake_delay = 1500, \
|
||||
.rx_retries = ATCA_RX_RETRIES } \
|
||||
}, \
|
||||
{ .atca_loc = PSA_ATCA_LOCATION_DEV1,\
|
||||
.cfg = {\
|
||||
.iface_type = ATCA_I2C_IFACE, \
|
||||
.devtype = ATCA_DEVTYPE_DEV1, \
|
||||
.atcai2c.address = ATCA_PARAM_ADDR_DEV1, \
|
||||
.atcai2c.bus = ATCA_PARAM_I2C_DEV1, \
|
||||
.atcai2c.baud = -1, /**< Not used in RIOT */ \
|
||||
.wake_delay = 1500, \
|
||||
.rx_retries = ATCA_RX_RETRIES } \
|
||||
}
|
||||
#else
|
||||
#define ATCA_PARAMS { .atca_loc = PSA_ATCA_LOCATION_DEV0,\
|
||||
.cfg = {\
|
||||
.iface_type = ATCA_I2C_IFACE, \
|
||||
.devtype = ATCA_DEVTYPE_DEV0, \
|
||||
.atcai2c.address = ATCA_PARAM_ADDR_DEV0, \
|
||||
.atcai2c.bus = ATCA_PARAM_I2C_DEV0, \
|
||||
.atcai2c.baud = -1, /**< Not used in RIOT */ \
|
||||
.wake_delay = 1500, \
|
||||
.rx_retries = ATCA_RX_RETRIES } \
|
||||
}
|
||||
#endif /* MULTIPLE_SE */
|
||||
|
||||
#define ATCA_SLOTS_DEV0 { \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_AES, 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_HMAC, 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ 0, 1, 1 }, \
|
||||
{ 0, 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ 0, 0, 0 }, \
|
||||
{ 0, 0, 0 }}
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
#define ATCA_SLOTS_DEV1 { \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_AES, 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_HMAC, 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ 0, 1, 1 }, \
|
||||
{ 0, 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
{ 0, 0, 0 }, \
|
||||
{ 0, 0, 0 }}
|
||||
#endif
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
#define ATCA_CONFIG_LIST { ATCA_SLOTS_DEV0 }, \
|
||||
{ ATCA_SLOTS_DEV1 }
|
||||
#else
|
||||
#define ATCA_CONFIG_LIST { ATCA_SLOTS_DEV0 }
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CUSTOM_ATCA_PARAMS_H */
|
||||
/** @} */
|
131
examples/psa_crypto/example_cipher_aes_128.c
Normal file
131
examples/psa_crypto/example_cipher_aes_128.c
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @brief Example functions for AES CBC encryption with PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#define AES_128_KEY_SIZE (16)
|
||||
#define AES_256_KEY_SIZE (32)
|
||||
|
||||
static const uint8_t KEY_128[] = {
|
||||
0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
||||
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c
|
||||
};
|
||||
|
||||
static uint8_t PLAINTEXT[] = {
|
||||
0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
|
||||
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51
|
||||
};
|
||||
static uint8_t PLAINTEXT_LEN = 32;
|
||||
|
||||
/**
|
||||
* @brief Example function to perform an AES-128 CBC encryption and decryption
|
||||
* with the PSA Crypto API.
|
||||
*
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t example_cipher_aes_128(void)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_DOES_NOT_EXIST;
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_attributes_t attr = psa_key_attributes_init();
|
||||
psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
|
||||
|
||||
size_t encr_output_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_AES,
|
||||
PSA_ALG_CBC_NO_PADDING, PLAINTEXT_LEN);
|
||||
|
||||
uint8_t cipher_out[encr_output_size];
|
||||
uint8_t plain_out[sizeof(PLAINTEXT)];
|
||||
size_t output_len = 0;
|
||||
|
||||
psa_set_key_algorithm(&attr, PSA_ALG_CBC_NO_PADDING);
|
||||
psa_set_key_usage_flags(&attr, usage);
|
||||
psa_set_key_bits(&attr, 128);
|
||||
psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
|
||||
|
||||
#ifdef SECURE_ELEMENT
|
||||
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION
|
||||
(PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV0);
|
||||
psa_set_key_lifetime(&attr, lifetime);
|
||||
#endif
|
||||
|
||||
status = psa_import_key(&attr, KEY_128, AES_128_KEY_SIZE, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, PLAINTEXT,
|
||||
PLAINTEXT_LEN, cipher_out, encr_output_size, &output_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_cipher_decrypt(key_id, PSA_ALG_CBC_NO_PADDING, cipher_out,
|
||||
sizeof(cipher_out), plain_out, sizeof(plain_out), &output_len);
|
||||
if (status == PSA_SUCCESS) {
|
||||
return (memcmp(PLAINTEXT, plain_out, sizeof(plain_out)) ? -1 : 0);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
psa_status_t example_cipher_aes_128_sec_se(void)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_DOES_NOT_EXIST;
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_attributes_t attr = psa_key_attributes_init();
|
||||
psa_key_usage_t usage = PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT;
|
||||
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
|
||||
PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV1);
|
||||
|
||||
size_t encr_output_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_AES,
|
||||
PSA_ALG_CBC_NO_PADDING, PLAINTEXT_LEN);
|
||||
uint8_t cipher_out[encr_output_size];
|
||||
uint8_t plain_out[sizeof(PLAINTEXT)];
|
||||
size_t output_len = 0;
|
||||
|
||||
psa_set_key_lifetime(&attr, lifetime);
|
||||
psa_set_key_algorithm(&attr, PSA_ALG_CBC_NO_PADDING);
|
||||
psa_set_key_usage_flags(&attr, usage);
|
||||
psa_set_key_bits(&attr, 128);
|
||||
psa_set_key_type(&attr, PSA_KEY_TYPE_AES);
|
||||
|
||||
status = psa_import_key(&attr, KEY_128, AES_128_KEY_SIZE, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, PLAINTEXT,
|
||||
PLAINTEXT_LEN, cipher_out, encr_output_size, &output_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_cipher_decrypt(key_id, PSA_ALG_CBC_NO_PADDING, cipher_out,
|
||||
sizeof(cipher_out), plain_out, sizeof(plain_out), &output_len);
|
||||
if (status == PSA_SUCCESS) {
|
||||
return (memcmp(PLAINTEXT, plain_out, sizeof(plain_out)) ? -1 : 0);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif
|
177
examples/psa_crypto/example_ecdsa_p256.c
Normal file
177
examples/psa_crypto/example_ecdsa_p256.c
Normal file
@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @brief Example functions for ECDSA with PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#define ECDSA_MESSAGE_SIZE (127)
|
||||
#define ECC_KEY_SIZE (256)
|
||||
|
||||
/**
|
||||
* @brief Example function to perform an ECDSA operation with a NIST P256 curve
|
||||
* with the PSA Crypto API.
|
||||
*
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t example_ecdsa_p256(void)
|
||||
{
|
||||
psa_key_id_t privkey_id;
|
||||
psa_key_attributes_t privkey_attr = psa_key_attributes_init();
|
||||
psa_key_id_t pubkey_id;
|
||||
psa_key_attributes_t pubkey_attr = psa_key_attributes_init();
|
||||
|
||||
psa_key_usage_t usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
|
||||
psa_key_type_t type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
|
||||
psa_algorithm_t alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
|
||||
psa_key_bits_t bits = ECC_KEY_SIZE;
|
||||
uint8_t bytes =
|
||||
PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), bits);
|
||||
|
||||
uint8_t public_key[PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_ECC_KEY_PAIR(
|
||||
PSA_ECC_FAMILY_SECP_R1),
|
||||
ECC_KEY_SIZE)] = { 0 };
|
||||
size_t pubkey_length;
|
||||
uint8_t signature[PSA_SIGN_OUTPUT_SIZE(type, bits, alg)];
|
||||
size_t sig_length;
|
||||
uint8_t msg[ECDSA_MESSAGE_SIZE] = { 0x0b };
|
||||
uint8_t hash[PSA_HASH_LENGTH(PSA_ALG_SHA_256)];
|
||||
size_t hash_length;
|
||||
|
||||
psa_set_key_algorithm(&privkey_attr, alg);
|
||||
psa_set_key_usage_flags(&privkey_attr, usage);
|
||||
psa_set_key_type(&privkey_attr, type);
|
||||
psa_set_key_bits(&privkey_attr, bits);
|
||||
|
||||
#ifdef SECURE_ELEMENT
|
||||
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
|
||||
PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV0);
|
||||
psa_set_key_lifetime(&privkey_attr, lifetime);
|
||||
#endif
|
||||
|
||||
psa_status_t status = PSA_ERROR_DOES_NOT_EXIST;
|
||||
|
||||
status = psa_generate_key(&privkey_attr, &privkey_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_export_public_key(privkey_id, public_key, sizeof(public_key), &pubkey_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_hash_compute(PSA_ALG_SHA_256, msg, sizeof(msg), hash, sizeof(hash), &hash_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef SECURE_ELEMENT
|
||||
psa_set_key_lifetime(&pubkey_attr, lifetime);
|
||||
#endif
|
||||
psa_set_key_algorithm(&pubkey_attr, alg);
|
||||
psa_set_key_usage_flags(&pubkey_attr, PSA_KEY_USAGE_VERIFY_HASH);
|
||||
psa_set_key_bits(&pubkey_attr, PSA_BYTES_TO_BITS(bytes));
|
||||
psa_set_key_type(&pubkey_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
|
||||
|
||||
status = psa_import_key(&pubkey_attr, public_key, pubkey_length, &pubkey_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_sign_hash(privkey_id, alg, hash, sizeof(hash), signature, sizeof(signature),
|
||||
&sig_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return psa_verify_hash(pubkey_id, alg, hash, sizeof(hash), signature, sig_length);
|
||||
}
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
psa_status_t example_ecdsa_p256_sec_se(void)
|
||||
{
|
||||
psa_key_id_t privkey_id;
|
||||
psa_key_attributes_t privkey_attr = psa_key_attributes_init();
|
||||
psa_key_id_t pubkey_id;
|
||||
psa_key_attributes_t pubkey_attr = psa_key_attributes_init();
|
||||
|
||||
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
|
||||
PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV1);
|
||||
psa_key_usage_t usage = PSA_KEY_USAGE_SIGN_HASH | PSA_KEY_USAGE_VERIFY_HASH;
|
||||
psa_key_type_t type = PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1);
|
||||
psa_algorithm_t alg = PSA_ALG_ECDSA(PSA_ALG_SHA_256);
|
||||
psa_key_bits_t bits = 256;
|
||||
uint8_t bytes =
|
||||
PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), bits);
|
||||
|
||||
uint8_t public_key[PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(PSA_KEY_TYPE_ECC_KEY_PAIR(
|
||||
PSA_ECC_FAMILY_SECP_R1), 256)] = { 0 };
|
||||
size_t pubkey_length;
|
||||
|
||||
uint8_t signature[PSA_SIGN_OUTPUT_SIZE(type, bits, alg)];
|
||||
size_t sig_length;
|
||||
uint8_t msg[ECDSA_MESSAGE_SIZE] = { 0x0b };
|
||||
uint8_t hash[PSA_HASH_LENGTH(PSA_ALG_SHA_256)];
|
||||
size_t hash_length;
|
||||
|
||||
psa_set_key_lifetime(&privkey_attr, lifetime);
|
||||
psa_set_key_algorithm(&privkey_attr, alg);
|
||||
psa_set_key_usage_flags(&privkey_attr, usage);
|
||||
psa_set_key_type(&privkey_attr, type);
|
||||
psa_set_key_bits(&privkey_attr, bits);
|
||||
|
||||
psa_status_t status = PSA_ERROR_DOES_NOT_EXIST;
|
||||
|
||||
status = psa_generate_key(&privkey_attr, &privkey_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_export_public_key(privkey_id, public_key, sizeof(public_key), &pubkey_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_hash_compute(PSA_ALG_SHA_256, msg, sizeof(msg), hash, sizeof(hash), &hash_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_set_key_lifetime(&pubkey_attr, lifetime);
|
||||
psa_set_key_algorithm(&pubkey_attr, alg);
|
||||
psa_set_key_usage_flags(&pubkey_attr, PSA_KEY_USAGE_VERIFY_HASH);
|
||||
psa_set_key_bits(&pubkey_attr, PSA_BYTES_TO_BITS(bytes));
|
||||
psa_set_key_type(&pubkey_attr, PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1));
|
||||
|
||||
status = psa_import_key(&pubkey_attr, public_key, pubkey_length, &pubkey_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = psa_sign_hash(privkey_id, alg, hash, sizeof(hash), signature, sizeof(signature),
|
||||
&sig_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return psa_verify_hash(pubkey_id, alg, hash, sizeof(hash), signature, sig_length);
|
||||
}
|
||||
#endif
|
111
examples/psa_crypto/example_hmac_sha256.c
Normal file
111
examples/psa_crypto/example_hmac_sha256.c
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @brief Example functions for HMAC SHA256 with PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
static const uint8_t HMAC_KEY[] = {
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
|
||||
0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b
|
||||
};
|
||||
static size_t HMAC_KEY_LEN = 32;
|
||||
|
||||
static const uint8_t HMAC_MSG[] = {
|
||||
0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20,
|
||||
0x61, 0x20, 0x74, 0x65, 0x73, 0x74, 0x73, 0x74,
|
||||
0x72, 0x69, 0x6e, 0x67, 0x20, 0x66, 0x6f, 0x72,
|
||||
0x20, 0x68, 0x6d, 0x61, 0x63, 0x32, 0x35, 0x36
|
||||
};
|
||||
static size_t HMAC_MSG_LEN = 32;
|
||||
|
||||
/**
|
||||
* @brief Example function to perform an HMAC SHA-256 computation
|
||||
* with the PSA Crypto API.
|
||||
*
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t example_hmac_sha256(void)
|
||||
{
|
||||
psa_key_attributes_t attr = psa_key_attributes_init();
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_usage_t usage = PSA_KEY_USAGE_SIGN_MESSAGE;
|
||||
|
||||
size_t digest_size =
|
||||
PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, HMAC_KEY_LEN, PSA_ALG_HMAC(PSA_ALG_SHA_256));
|
||||
uint8_t digest[digest_size];
|
||||
size_t output_len = 0;
|
||||
|
||||
psa_set_key_algorithm(&attr, PSA_ALG_HMAC(PSA_ALG_SHA_256));
|
||||
psa_set_key_usage_flags(&attr, usage);
|
||||
psa_set_key_bits(&attr, PSA_BYTES_TO_BITS(HMAC_KEY_LEN));
|
||||
psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC);
|
||||
|
||||
#ifdef SECURE_ELEMENT
|
||||
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
|
||||
PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV0);
|
||||
psa_set_key_lifetime(&attr, lifetime);
|
||||
#endif
|
||||
|
||||
psa_status_t status = PSA_ERROR_DOES_NOT_EXIST;
|
||||
status = psa_import_key(&attr, HMAC_KEY, HMAC_KEY_LEN, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
|
||||
HMAC_MSG, HMAC_MSG_LEN, digest, digest_size,
|
||||
&output_len);
|
||||
}
|
||||
|
||||
#if MULTIPLE_SE
|
||||
psa_status_t example_hmac_sha256_sec_se(void)
|
||||
{
|
||||
psa_key_attributes_t attr = psa_key_attributes_init();
|
||||
psa_key_id_t key_id = 0;
|
||||
psa_key_usage_t usage = PSA_KEY_USAGE_SIGN_MESSAGE;
|
||||
psa_key_lifetime_t lifetime = PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(
|
||||
PSA_KEY_LIFETIME_VOLATILE, PSA_ATCA_LOCATION_DEV1);
|
||||
|
||||
size_t digest_size =
|
||||
PSA_MAC_LENGTH(PSA_KEY_TYPE_HMAC, HMAC_KEY_LEN, PSA_ALG_HMAC(PSA_ALG_SHA_256));
|
||||
uint8_t digest[digest_size];
|
||||
size_t output_len = 0;
|
||||
|
||||
psa_set_key_lifetime(&attr, lifetime);
|
||||
psa_set_key_algorithm(&attr, PSA_ALG_HMAC(PSA_ALG_SHA_256));
|
||||
psa_set_key_usage_flags(&attr, usage);
|
||||
psa_set_key_bits(&attr, PSA_BYTES_TO_BITS(HMAC_KEY_LEN));
|
||||
psa_set_key_type(&attr, PSA_KEY_TYPE_HMAC);
|
||||
|
||||
psa_status_t status = PSA_ERROR_DOES_NOT_EXIST;
|
||||
|
||||
status = psa_import_key(&attr, HMAC_KEY, HMAC_KEY_LEN, &key_id);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return psa_mac_compute(key_id, PSA_ALG_HMAC(PSA_ALG_SHA_256),
|
||||
HMAC_MSG, HMAC_MSG_LEN, digest, digest_size,
|
||||
&output_len);
|
||||
}
|
||||
#endif
|
90
examples/psa_crypto/main.c
Normal file
90
examples/psa_crypto/main.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup examples
|
||||
* @{
|
||||
*
|
||||
* @brief Example application for PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "psa/crypto.h"
|
||||
#include "ztimer.h"
|
||||
|
||||
extern psa_status_t example_cipher_aes_128(void);
|
||||
extern psa_status_t example_hmac_sha256(void);
|
||||
extern psa_status_t example_ecdsa_p256(void);
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
extern psa_status_t example_cipher_aes_128_sec_se(void);
|
||||
extern psa_status_t example_hmac_sha256_sec_se(void);
|
||||
extern psa_status_t example_ecdsa_p256_sec_se(void);
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
psa_status_t status;
|
||||
|
||||
psa_crypto_init();
|
||||
|
||||
ztimer_acquire(ZTIMER_USEC);
|
||||
ztimer_now_t start = ztimer_now(ZTIMER_USEC);
|
||||
|
||||
status = example_hmac_sha256();
|
||||
printf("HMAC SHA256 took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("HMAC SHA256 failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
|
||||
start = ztimer_now(ZTIMER_USEC);
|
||||
status = example_cipher_aes_128();
|
||||
printf("Cipher AES 128 took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("Cipher AES 128 failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
|
||||
start = ztimer_now(ZTIMER_USEC);
|
||||
status = example_ecdsa_p256();
|
||||
printf("ECDSA took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("ECDSA failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
|
||||
#ifdef MULTIPLE_SE
|
||||
puts("Running Examples with secondary SE:");
|
||||
status = example_hmac_sha256_sec_se();
|
||||
printf("HMAC SHA256 took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("HMAC SHA256 failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
|
||||
start = ztimer_now(ZTIMER_USEC);
|
||||
status = example_cipher_aes_128_sec_se();
|
||||
printf("Cipher AES 128 took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("Cipher AES 128 failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
|
||||
start = ztimer_now(ZTIMER_USEC);
|
||||
status = example_ecdsa_p256_sec_se();
|
||||
printf("ECDSA took %d us\n", (int)(ztimer_now(ZTIMER_USEC) - start));
|
||||
if (status != PSA_SUCCESS) {
|
||||
printf("ECDSA failed: %s\n", psa_status_to_humanly_readable(status));
|
||||
}
|
||||
#endif
|
||||
|
||||
ztimer_release(ZTIMER_USEC);
|
||||
|
||||
puts("All Done");
|
||||
return 0;
|
||||
}
|
13
examples/psa_crypto/tests/01-run.py
Executable file
13
examples/psa_crypto/tests/01-run.py
Executable file
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
from testrunner import run
|
||||
|
||||
|
||||
def testfunc(child):
|
||||
child.expect_exact('All Done')
|
||||
print("[TEST PASSED]")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(run(testfunc))
|
@ -134,6 +134,11 @@ config HAS_CPU_CHECK_ADDRESS
|
||||
help
|
||||
Indicates that address validity check is supported.
|
||||
|
||||
config HAS_PERIPH_CRYPTOCELL_310
|
||||
bool
|
||||
help
|
||||
Indicates that a cryptocell peripheral is present.
|
||||
|
||||
config HAS_DBGPIN
|
||||
bool
|
||||
help
|
||||
@ -188,6 +193,11 @@ config HAS_PERIPH_CAN
|
||||
help
|
||||
Indicates that a CAN peripheral is present.
|
||||
|
||||
config HAS_PERIPH_CIPHER_AES_128_CBC
|
||||
bool
|
||||
help
|
||||
Indicates that there is AES 128 CBC hardware acceleration present
|
||||
|
||||
config HAS_PERIPH_CORETIMER
|
||||
bool
|
||||
help
|
||||
@ -208,6 +218,16 @@ config HAS_PERIPH_DMA
|
||||
help
|
||||
Indicates that a DMA peripheral is present.
|
||||
|
||||
config HAS_PERIPH_ECC_P192R1
|
||||
bool
|
||||
help
|
||||
Indicates that there is ECC P192R1 hardware acceleration peripheral present.
|
||||
|
||||
config HAS_PERIPH_ECC_P256R1
|
||||
bool
|
||||
help
|
||||
Indicates that there is ECC P256R1 hardware acceleration peripheral present.
|
||||
|
||||
config HAS_PERIPH_EEPROM
|
||||
bool
|
||||
help
|
||||
@ -285,6 +305,36 @@ config HAS_PERIPH_GPIO_LL_IRQ_UNMASK
|
||||
Indicates that the GPIO peripheral supports unmasking interrupts without
|
||||
clearing pending IRQs that came in while masked.
|
||||
|
||||
config HAS_PERIPH_HASH_MD5
|
||||
bool
|
||||
help
|
||||
Indicates that there is MD5 hardware acceleration present.
|
||||
|
||||
config HAS_PERIPH_HASH_SHA_1
|
||||
bool
|
||||
help
|
||||
Indicates that there is SHA-1 hardware acceleration present.
|
||||
|
||||
config HAS_PERIPH_HASH_SHA_224
|
||||
bool
|
||||
help
|
||||
Indicates that there is SHA-224 hardware acceleration present.
|
||||
|
||||
config HAS_PERIPH_HASH_SHA_256
|
||||
bool
|
||||
help
|
||||
Indicates that there is SHA-256 hardware acceleration present.
|
||||
|
||||
config HAS_PERIPH_HASH_SHA_512
|
||||
bool
|
||||
help
|
||||
Indicates that there is SHA-512 hardware acceleration present.
|
||||
|
||||
config HAS_PERIPH_HMAC_SHA_256
|
||||
bool
|
||||
help
|
||||
Indicates that there is HMAC SHA-256 hardware acceleration present.
|
||||
|
||||
config HAS_PERIPH_HWRNG
|
||||
bool
|
||||
help
|
||||
|
@ -93,4 +93,12 @@ else
|
||||
"don't run this on public networks!$(COLOR_RESET)" 1>&2)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Warn about PSA Crypto
|
||||
ifneq (,$(filter psa_crypto,$(USEMODULE)))
|
||||
$(shell $(COLOR_ECHO) "$(COLOR_YELLOW) You are going to use the PSA Crypto module,"\
|
||||
"which is only partly implemented and not yet thouroughly tested.\n"\
|
||||
"Please do not use this module in production, as it may introduce"\
|
||||
"security issues!$(COLOR_RESET)" 1>&2)
|
||||
endif
|
||||
endif
|
||||
|
@ -11,9 +11,13 @@ USEMODULE += $(PERIPH_FEATURES)
|
||||
|
||||
# Add all USED periph_% init modules unless they are blacklisted
|
||||
PERIPH_IGNORE_MODULES := \
|
||||
periph_cipher_aes_128_cbc \
|
||||
periph_clic \
|
||||
periph_common \
|
||||
periph_coretimer \
|
||||
periph_cryptocell_310 \
|
||||
periph_ecc_p192r1 \
|
||||
periph_ecc_p256r1 \
|
||||
periph_eth \
|
||||
periph_eth_common \
|
||||
periph_flash \
|
||||
@ -25,6 +29,11 @@ PERIPH_IGNORE_MODULES := \
|
||||
periph_gpio_ll_irq_level_triggered_low \
|
||||
periph_gpio_ll_irq_unmask \
|
||||
periph_gpio_mux \
|
||||
periph_hash_sha_1 \
|
||||
periph_hash_sha_224 \
|
||||
periph_hash_sha_256 \
|
||||
periph_hash_sha_512 \
|
||||
periph_hmac_sha_256 \
|
||||
periph_i2c_hw \
|
||||
periph_i2c_sw \
|
||||
periph_init% \
|
||||
|
@ -388,6 +388,16 @@ PSEUDOMODULES += posix_headers
|
||||
PSEUDOMODULES += printf_float
|
||||
PSEUDOMODULES += prng
|
||||
PSEUDOMODULES += prng_%
|
||||
PSEUDOMODULES += psa_riot_cipher_aes_common
|
||||
PSEUDOMODULES += psa_riot_cipher_aes_128_ecb
|
||||
PSEUDOMODULES += psa_riot_cipher_aes_128_cbc
|
||||
PSEUDOMODULES += psa_riot_cipher_aes_192_cbc
|
||||
PSEUDOMODULES += psa_riot_cipher_aes_256_cbc
|
||||
PSEUDOMODULES += psa_riot_hashes_md5
|
||||
PSEUDOMODULES += psa_riot_hashes_sha_1
|
||||
PSEUDOMODULES += psa_riot_hashes_sha_224
|
||||
PSEUDOMODULES += psa_riot_hashes_sha_256
|
||||
PSEUDOMODULES += psa_riot_hashes_hmac_sha256
|
||||
PSEUDOMODULES += fortuna_reseed
|
||||
## @defgroup pseudomodule_random_cmd random_cmd
|
||||
## @ingroup sys_shell_commands
|
||||
|
@ -17,6 +17,7 @@ rsource "corejson/Kconfig"
|
||||
rsource "cryptoauthlib/Kconfig"
|
||||
rsource "driver_atwinc15x0/Kconfig"
|
||||
rsource "driver_bme680/Kconfig"
|
||||
rsource "driver_cryptocell_310/Kconfig"
|
||||
rsource "driver_sx126x/Kconfig"
|
||||
rsource "elk/Kconfig"
|
||||
rsource "emlearn/Kconfig"
|
||||
|
@ -9,6 +9,7 @@ menuconfig PACKAGE_CRYPTOAUTHLIB
|
||||
bool "Microchip CryptoAuthentication Library package"
|
||||
depends on TEST_KCONFIG
|
||||
depends on !HAS_ARCH_EFM32
|
||||
depends on HAS_PERIPH_I2C
|
||||
select MODULE_AUTO_INIT_SECURITY
|
||||
select MODULE_CRYPTOAUTHLIB_CONTRIB
|
||||
|
||||
@ -20,6 +21,12 @@ config MODULE_CRYPTOAUTHLIB_CONTRIB
|
||||
select MODULE_PERIPH_I2C
|
||||
select MODULE_PERIPH_I2C_RECONFIGURE if HAS_PERIPH_I2C_RECONFIGURE
|
||||
|
||||
config MODULE_PSA_ATCA_DRIVER
|
||||
bool
|
||||
depends on PACKAGE_CRYPTOAUTHLIB
|
||||
default y if MODULE_PSA_CRYPTO
|
||||
select PSA_KEY_MANAGEMENT
|
||||
|
||||
config MODULE_CRYPTOAUTHLIB_TEST
|
||||
bool "Module for cryptoauthlib tests"
|
||||
depends on TEST_KCONFIG
|
||||
@ -56,4 +63,4 @@ config MODULE_CRYPTOAUTHLIB_TEST_API_CRYPTO
|
||||
config MODULE_CRYPTOAUTHLIB_TEST_VECTORS
|
||||
bool
|
||||
|
||||
endif
|
||||
endif # PACKAGE_CRYPTOAUTHLIB
|
||||
|
@ -10,7 +10,7 @@ include $(RIOTBASE)/pkg/pkg.mk
|
||||
|
||||
CMAKE_MINIMAL_VERSION = 3.6.0
|
||||
|
||||
CFLAGS += $(INCLUDES)
|
||||
CFLAGS += $(INCLUDES) # for some reason this is needed by llvm, but not for gcc
|
||||
CFLAGS += -DATCA_HAL_I2C
|
||||
CFLAGS += -Wno-cast-align
|
||||
CFLAGS += -Wno-char-subscripts
|
||||
|
@ -19,3 +19,11 @@ endif
|
||||
# Some EFM32 CPU families define AES_COUNT, which is also defined by this
|
||||
# library.
|
||||
FEATURES_BLACKLIST += arch_efm32
|
||||
|
||||
ifneq (,$(filter psa_crypto,$(USEMODULE)))
|
||||
USEMODULE += psa_atca_driver
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_secure_element_ateccx08a_ecc_p256, $(USEMODULE)))
|
||||
USEMODULE += psa_secure_element_asymmetric
|
||||
endif
|
||||
|
@ -7,6 +7,11 @@ INCLUDES += -I$(PKG_SOURCE_DIR)/app
|
||||
INCLUDES += -I$(PKG_SOURCE_DIR)/lib/calib
|
||||
INCLUDES += -I$(RIOTPKG)/cryptoauthlib/include
|
||||
|
||||
ifneq (,$(filter psa_crypto, $(USEMODULE)))
|
||||
DIRS += $(RIOTPKG)/cryptoauthlib/psa_atca_driver
|
||||
INCLUDES += -I$(RIOTBASE)/sys/psa_crypto/include
|
||||
endif
|
||||
|
||||
DIRS += $(RIOTPKG)/cryptoauthlib/contrib
|
||||
ARCHIVES += $(BINDIR)/cryptoauthlib.a
|
||||
|
||||
@ -21,3 +26,8 @@ ifneq (,$(filter cryptoauthlib_test,$(USEMODULE)))
|
||||
INCLUDES += -I$(PKG_TESTINCLDIR)/vectors
|
||||
INCLUDES += -I$(PKG_SOURCE_DIR)/third_party/unity
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_crypto,$(USEMODULE)))
|
||||
PSEUDOMODULES += psa_secure_element_ateccx08a
|
||||
PSEUDOMODULES += psa_secure_element_ateccx08a_ecc_p256
|
||||
endif
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "atca.h"
|
||||
#include "atca_params.h"
|
||||
|
||||
|
||||
/* Timer functions */
|
||||
void atca_delay_us(uint32_t delay)
|
||||
{
|
||||
@ -65,7 +64,7 @@ ATCA_STATUS hal_i2c_post_init(ATCAIface iface)
|
||||
|
||||
ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata, int txlength)
|
||||
{
|
||||
(void) word_address;
|
||||
(void)word_address;
|
||||
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
|
||||
int ret;
|
||||
|
||||
@ -84,7 +83,7 @@ ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t word_address, uint8_t *txdata,
|
||||
ATCA_STATUS hal_i2c_receive(ATCAIface iface, uint8_t word_address, uint8_t *rxdata,
|
||||
uint16_t *rxlength)
|
||||
{
|
||||
(void) word_address;
|
||||
(void)word_address;
|
||||
ATCAIfaceCfg *cfg = atgetifacecfg(iface);
|
||||
uint8_t retries = cfg->rx_retries;
|
||||
int ret = -1;
|
||||
@ -170,24 +169,24 @@ ATCA_STATUS hal_i2c_sleep(ATCAIface iface)
|
||||
return ATCA_SUCCESS;
|
||||
}
|
||||
|
||||
ATCA_STATUS hal_i2c_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen)
|
||||
ATCA_STATUS hal_i2c_control(ATCAIface iface, uint8_t option, void *param, size_t paramlen)
|
||||
{
|
||||
(void) param;
|
||||
(void) paramlen;
|
||||
(void)param;
|
||||
(void)paramlen;
|
||||
switch (option) {
|
||||
case ATCA_HAL_CONTROL_WAKE:
|
||||
return hal_i2c_wake(iface);
|
||||
case ATCA_HAL_CONTROL_IDLE:
|
||||
return hal_i2c_idle(iface);
|
||||
case ATCA_HAL_CONTROL_SLEEP:
|
||||
return hal_i2c_sleep(iface);
|
||||
case ATCA_HAL_CHANGE_BAUD:
|
||||
return ATCA_UNIMPLEMENTED;
|
||||
case ATCA_HAL_CONTROL_SELECT:
|
||||
case ATCA_HAL_CONTROL_DESELECT:
|
||||
return ATCA_SUCCESS;
|
||||
default:
|
||||
return ATCA_BAD_PARAM;
|
||||
case ATCA_HAL_CONTROL_WAKE:
|
||||
return hal_i2c_wake(iface);
|
||||
case ATCA_HAL_CONTROL_IDLE:
|
||||
return hal_i2c_idle(iface);
|
||||
case ATCA_HAL_CONTROL_SLEEP:
|
||||
return hal_i2c_sleep(iface);
|
||||
case ATCA_HAL_CHANGE_BAUD:
|
||||
return ATCA_UNIMPLEMENTED;
|
||||
case ATCA_HAL_CONTROL_SELECT:
|
||||
case ATCA_HAL_CONTROL_DESELECT:
|
||||
return ATCA_SUCCESS;
|
||||
default:
|
||||
return ATCA_BAD_PARAM;
|
||||
}
|
||||
return ATCA_UNIMPLEMENTED;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @defgroup pkg_cryptoauthlib Microchip CryptoAuthentication Library
|
||||
* @ingroup pkg drivers_misc sys_crypto
|
||||
* @ingroup pkg drivers_misc
|
||||
* @brief Provides the library for Microchip CryptoAuth devices
|
||||
* @see https://github.com/MicrochipTech/cryptoauthlib
|
||||
*
|
||||
@ -8,22 +8,19 @@
|
||||
*
|
||||
* This package provides support for the official library for Microchip CryptoAuth devices.
|
||||
*
|
||||
*
|
||||
* ## Warning
|
||||
*
|
||||
* Some functions can only be used, when the data, config and otp zones of the
|
||||
* device are locked. Locking is permanent and cannot be undone. Be careful if
|
||||
* you're not sure you've configured everything correctly.
|
||||
* For more information we refer to the data sheet of the device.
|
||||
*
|
||||
* @warning Some functions can only be used, when the data, config and otp zones
|
||||
* of the device are locked. Locking is permanent and cannot be undone.
|
||||
* Be careful if you're not sure you've configured everything correctly.
|
||||
* For more information please refer to the data sheet of the device.
|
||||
*
|
||||
* ## Usage
|
||||
*
|
||||
* Add
|
||||
* @code
|
||||
* USEPKG += cryptoauthlib
|
||||
* @endcode
|
||||
* to your Makefile.
|
||||
*
|
||||
*
|
||||
* ### Shell
|
||||
*
|
||||
* To facilitate the device configuration the RIOT shell provides some
|
||||
@ -33,7 +30,6 @@
|
||||
* The shell handler is enabled, if cryptoauthlib is included as a package in the
|
||||
* Makefile of an application that also includes the shell (e.g. examples/default).
|
||||
*
|
||||
*
|
||||
* ### No poll mode
|
||||
*
|
||||
* After sending a command to the device, responses are usually polled to enable
|
||||
@ -41,25 +37,11 @@
|
||||
* Alternatively ATCA_NO_POLL can be enabled through CFLAGS to simply
|
||||
* wait for the max execution time of a command before reading the response.
|
||||
*
|
||||
*
|
||||
* ## Implementation status
|
||||
*
|
||||
* This implementation was partly tested with ATECC508A and ATECC608A devices.
|
||||
* We haven't tested the functions that require locking the device, yet. There's
|
||||
* a wrapper in the cryptoauthlib/contrib folder, which implements most of the
|
||||
* HAL functions.
|
||||
* Currently the functions hal_i2c_discover_devices and hal_i2c_discover_buses
|
||||
* are unimplemented, as well as hal_i2c_post_init.
|
||||
*
|
||||
* ### Wake function
|
||||
*
|
||||
* The wake function only works when a 0x00 byte is sent on an i2c interface that
|
||||
* runs with with 133kHz or less.
|
||||
* Currently RIOT sets the baudrate to the default value of 100 kHz and there's
|
||||
* no interface to change that. If the default speed ever changes to a value
|
||||
* higher than 133 kHz the wake function needs to be adapted.
|
||||
* For more information on how to send a proper wake condition we refer to the
|
||||
* data sheet of the device.
|
||||
* Currently the functions `hal_i2c_release`, `hal_i2c_discover_devices` and
|
||||
* `hal_i2c_discover_buses` are unimplemented, as well as `hal_i2c_post_init`.
|
||||
*
|
||||
* ## Tests
|
||||
*
|
||||
@ -72,4 +54,189 @@
|
||||
* permanently. Unlocking is not possible!
|
||||
* Also there is a test for comparing the runtime of the RIOT software implementation
|
||||
* and the CryptoAuth hardware implementation for calculating a SHA-256 hash value.
|
||||
*
|
||||
* ## Using Multiple ATECCX08A Devices {#multi-ateccx08a}
|
||||
*
|
||||
* When using more than one device, you can either connect devices with different
|
||||
* I2C addresses to one bus or devices with the same address to separate buses.
|
||||
* The ATECCX08A devices provide a way to change the I2C address during device
|
||||
* configuration (for more details, read the datasheet or the API documentation).
|
||||
*
|
||||
* ATECCX08A device parameters are configured in
|
||||
* `RIOT/pkg/cryptoauthlib/include/atca_params.h`.
|
||||
* There you can specify your device's address, the I2C bus to use and more by
|
||||
* defining `ATCA_PARAMS`. Per default one device is defined in RIOT (example shown below).
|
||||
*
|
||||
* @code
|
||||
* #define ATCA_PARAM_I2C (I2C_DEV(0))
|
||||
* #define ATCA_PARAM_ADDR (ATCA_I2C_ADDR)
|
||||
* #define ATCA_RX_RETRIES (20)
|
||||
* #define ATCA_DEVTYPE (ATECC608A)
|
||||
*
|
||||
* #define ATCA_PARAMS { .iface_type = ATCA_I2C_IFACE, \
|
||||
* .devtype = ATCA_DEVTYPE, \
|
||||
* .atcai2c.address = ATCA_PARAM_ADDR, \
|
||||
* .atcai2c.bus = ATCA_PARAM_I2C, \
|
||||
* .atcai2c.baud = -1, \
|
||||
* .wake_delay = 1500, \
|
||||
* .rx_retries = ATCA_RX_RETRIES }
|
||||
* @endcode
|
||||
*
|
||||
* If you want to use more than one device, the best way is to create a file called
|
||||
* `custom_atca_params.h` in your application folder (you can see an example of this in
|
||||
* `examples/psa_crypto`).
|
||||
*
|
||||
* In your custom file you can now add a second device to `ATCA_PARAMS`:
|
||||
* @code
|
||||
* #define ATCA_PARAM_I2C_DEV0 (I2C_DEV(0))
|
||||
* #define ATCA_PARAM_ADDR_DEV0 (ATCA_I2C_ADDR_DEV0)
|
||||
* #define ATCA_RX_RETRIES_DEV0 (20)
|
||||
* #define ATCA_DEVTYPE_DEV0 (ATECC608A)
|
||||
*
|
||||
* #define ATCA_PARAM_I2C_DEV1 (I2C_DEV(0))
|
||||
* #define ATCA_PARAM_ADDR_DEV1 (ATCA_I2C_ADDR_DEV1)
|
||||
* #define ATCA_RX_RETRIES_DEV1 (20)
|
||||
* #define ATCA_DEVTYPE_DEV1 (ATECC608A)
|
||||
*
|
||||
* #define ATCA_PARAMS { .iface_type = ATCA_I2C_IFACE, \
|
||||
* .devtype = ATCA_DEVTYPE_DEV0, \
|
||||
* .atcai2c.address = ATCA_PARAM_ADDR_DEV0, \
|
||||
* .atcai2c.bus = ATCA_PARAM_I2C_DEV0, \
|
||||
* .atcai2c.baud = -1, \
|
||||
* .wake_delay = 1500, \
|
||||
* .rx_retries = ATCA_RX_RETRIES }, \
|
||||
* { .iface_type = ATCA_I2C_IFACE, \
|
||||
* .devtype = ATCA_DEVTYPE_DEV1, \
|
||||
* .atcai2c.address = ATCA_PARAM_ADDR_DEV1, \
|
||||
* .atcai2c.bus = ATCA_PARAM_I2C_DEV1, \
|
||||
* .atcai2c.baud = -1, \
|
||||
* .wake_delay = 1500, \
|
||||
* .rx_retries = ATCA_RX_RETRIES }
|
||||
* @endcode
|
||||
*
|
||||
* Now you just need to add the following to your Makefile:
|
||||
* @code
|
||||
* CFLAGS += -DCUSTOM_ATCA_PARAMS
|
||||
* INCLUDES += -I$(APPDIR)
|
||||
* @endcode
|
||||
*
|
||||
* This way your custom params file is included in the build process and both your
|
||||
* devices will be initialized by the `auto_init` module.
|
||||
*
|
||||
* To use them you need to utilize the `calib`-API of the cryptoauth driver, which
|
||||
* allows you to pass a device handle. Pointers to all initialized devices are stored
|
||||
* in the `atca_devs_ptr` array, which is included in `atca_params.h`.
|
||||
* Include `atca_params.h` in your source file and pass the device handle as shown below.
|
||||
*
|
||||
* @code {.c}
|
||||
* ATCADevice dev = atca_devs_ptr[0];
|
||||
* calib_sha_start(dev);
|
||||
* @endcode
|
||||
*
|
||||
* ## Using Cryptoauthlib as a backend for PSA Crypto {#psa-cryptoauthlib}
|
||||
*
|
||||
* To use cryptoauthlib as a backend for [PSA Crypto](#sys_psa_crypto), it is best to
|
||||
* overwrite the `atca_params.h` file with your own `custom_atca_params.h` file, similar
|
||||
* to the one described in [Using Multiple ATECCX08A Devices](#multi-ateccx08a).
|
||||
*
|
||||
* When using PSA, the `ATCA_PARAMS` define contains an additional value: A location
|
||||
* value of the type @ref psa_key_location_t. Each secure element you use needs its own
|
||||
* location value. The primary device can get the value
|
||||
* @ref PSA_KEY_LOCATION_PRIMARY_SECURE_ELEMENT. All others must be within the range of
|
||||
* @ref PSA_KEY_LOCATION_SE_MIN and @ref PSA_KEY_LOCATION_SE_MAX.
|
||||
*
|
||||
* Your structure should now look like this:
|
||||
* @code
|
||||
* #define PSA_ATCA_LOCATION (PSA_KEY_LOCATION_PRIMARY_SECURE_ELEMENT)
|
||||
* #define ATCA_PARAM_I2C (I2C_DEV(0))
|
||||
* #define ATCA_PARAM_ADDR (ATCA_I2C_ADDR)
|
||||
* #define ATCA_DEVTYPE (ATECC608A)
|
||||
* #define ATCA_RX_RETRIES (20)
|
||||
*
|
||||
* #define ATCA_PARAMS { .atca_loc = PSA_ATCA_LOCATION,\
|
||||
* .cfg = {\
|
||||
* .iface_type = ATCA_I2C_IFACE, \
|
||||
* .devtype = ATCA_DEVTYPE, \
|
||||
* .atcai2c.address = ATCA_PARAM_ADDR, \
|
||||
* .atcai2c.bus = ATCA_PARAM_I2C, \
|
||||
* .atcai2c.baud = -1, \
|
||||
* .wake_delay = 1500, \
|
||||
* .rx_retries = ATCA_RX_RETRIES } \
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* When using multiple SEs, just add more device parameters as shown in section
|
||||
* [Using Multiple ATECCX08A Devices](#multi-ateccx08a).
|
||||
*
|
||||
* ## Slot Configurations
|
||||
* The ATECCX08A devices have their own key management, which can be configured by
|
||||
* setting flags in the device's configuration and data zone. There is a large variety
|
||||
* of possible configurations, which can not entirely be represented by PSA Crypto.
|
||||
*
|
||||
* For now we assume that users are familiar with their device's datasheet and have configured
|
||||
* it in a way that it is usable. PSA can not yet work with keys that are already stored on the
|
||||
* device, which means all key slots must be writable after locking the configuration and data zone.
|
||||
*
|
||||
* For ECC operations this means that key slot configurations need to allow at least the
|
||||
* use of the `gen_key` command, for AES and HMAC key slots it means that clear write operations
|
||||
* must be allowed.
|
||||
*
|
||||
* @warning In case of AES and HMAC keys this may lead to security issues,
|
||||
* as it allows for manipulating key material.
|
||||
*
|
||||
* Users need to make their configurations known to PSA Crypto.
|
||||
* For this you need to initialize a list of key slot configuration structures, with a structure
|
||||
* for each slot.
|
||||
*
|
||||
* For these devices the structure looks like this:
|
||||
* @code {.c}
|
||||
* typedef struct {
|
||||
* psa_key_type_t key_type_allowed; // Declare the key type allowed in this slot
|
||||
* uint8_t key_persistent; // Ignore for now, PSA does not yet support persistent keys
|
||||
* uint8_t slot_occupied; // Set to 0, PSA will set this to one after writing a key
|
||||
* } psa_atca_slot_config_t;
|
||||
* @endcode
|
||||
*
|
||||
* To make your configurations known to PSA, simply add the following to your `custom_atca_params.h`
|
||||
* file (these values are only an example, of course you need to modify them according to
|
||||
* your needs).
|
||||
*
|
||||
* @code {.c}
|
||||
* #define ATCA_SLOTS_DEV0 { { PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
* { PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
* { PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
* { PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
* { PSA_KEY_TYPE_AES, 0, 0 }, \
|
||||
* { PSA_KEY_TYPE_HMAC, 0, 0 }, \
|
||||
* { PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
* { 0, 1, 1 }, \
|
||||
* { 0, 0, 0 }, \
|
||||
* { PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
* { PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
* { PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
* { PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
* { PSA_KEY_TYPE_ECC_PUBLIC_KEY(PSA_ECC_FAMILY_SECP_R1), 0, 0 }, \
|
||||
* { 0, 0, 0 }, \
|
||||
* { 0, 0, 0 }}
|
||||
*
|
||||
* #define ATCA_CONFIG_LIST { ATCA_SLOTS_DEV0 }
|
||||
* @endcode
|
||||
*
|
||||
* To use multiple devices, define `ATCA_SLOTS_DEV0` - `ATCA_SLOTS_DEVX` and add them to
|
||||
* `ATCA_CONFIG_LIST` like so:
|
||||
*
|
||||
* @code {.c}
|
||||
* #define ATCA_CONFIG_LIST { ATCA_SLOTS_DEV0 }, \
|
||||
* { ATCA_SLOTS_DEV1 }, \
|
||||
* ... \
|
||||
* { ATCA_SLOTS_DEVX }
|
||||
* @endcode
|
||||
*
|
||||
* A usage example for this can be found in `examples/psa_crypto`.
|
||||
*
|
||||
* ## Troubleshooting
|
||||
*
|
||||
* ### Device Initialization fails
|
||||
*
|
||||
* Make sure the I2C bus speed is set to `I2C_SPEED_NORMAL`.
|
||||
*/
|
||||
|
@ -29,6 +29,7 @@ extern "C" {
|
||||
|
||||
/**
|
||||
* @brief Default device and word addresses for ATECC508A
|
||||
* @{
|
||||
*/
|
||||
#define ATCA_I2C_ADDR (0xC0) /**< Default device address is 0xC0 */
|
||||
|
||||
@ -36,6 +37,38 @@ extern "C" {
|
||||
#define ATCA_SLEEP_ADDR (0x01) /**< Word address to write to for sleep mode */
|
||||
#define ATCA_IDLE_ADDR (0x02) /**< Word address to write to for idle mode */
|
||||
#define ATCA_DATA_ADDR (0x03) /**< Word address to read and write to data area */
|
||||
/** @} */
|
||||
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A)
|
||||
#include "psa/crypto_types.h"
|
||||
|
||||
/**
|
||||
* @brief Structure containing the Cryptoauthlib specific AES context
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t iv[16];
|
||||
psa_encrypt_or_decrypt_t direction;
|
||||
union atca_context {
|
||||
atca_aes_cbc_ctx_t aes_cbc;
|
||||
} aes_ctx;
|
||||
} psa_atca_cipher_context_t;
|
||||
|
||||
/**
|
||||
* @brief Structure containing information about which type of key
|
||||
* can be held by a specific key slot on an ATECCX08 device.
|
||||
*
|
||||
* If a slot should be ignored by the implementation,
|
||||
* just mark it as persistent and occupied.
|
||||
*/
|
||||
typedef struct {
|
||||
/* Type of key permitted for slot */
|
||||
psa_key_type_t key_type_allowed;
|
||||
/* Specify if key should be stored persistently or can be overwritten */
|
||||
uint8_t key_persistent;
|
||||
/* Specify whether slot is already occupied */
|
||||
uint8_t slot_occupied;
|
||||
} psa_atca_slot_config_t;
|
||||
#endif /* MODULE_PSA_SECURE_ELEMENT_ATECCX08A */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -49,4 +49,4 @@ extern "C" {
|
||||
}
|
||||
#endif
|
||||
#endif /* ATCA_CONFIG_H */
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
@ -22,8 +22,19 @@
|
||||
|
||||
#include "board.h"
|
||||
#include "periph/i2c.h"
|
||||
#include "atca.h"
|
||||
#include "cryptoauthlib.h"
|
||||
|
||||
#include "kernel_defines.h"
|
||||
|
||||
#ifdef CUSTOM_ATCA_PARAMS
|
||||
#include "custom_atca_params.h"
|
||||
#endif
|
||||
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A)
|
||||
#include "psa/crypto_types.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -45,8 +56,9 @@ extern "C" {
|
||||
*/
|
||||
|
||||
#ifndef ATCA_PARAM_I2C
|
||||
#define ATCA_PARAM_I2C I2C_DEV(0)
|
||||
#define ATCA_PARAM_I2C (I2C_DEV(0))
|
||||
#endif
|
||||
|
||||
#ifndef ATCA_PARAM_ADDR
|
||||
#define ATCA_PARAM_ADDR (ATCA_I2C_ADDR)
|
||||
#endif
|
||||
@ -58,17 +70,37 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef ATCA_PARAMS
|
||||
#define ATCA_PARAMS { .iface_type = ATCA_I2C_IFACE, \
|
||||
.devtype = ATCA_DEVTYPE, \
|
||||
.atcai2c.address = ATCA_PARAM_ADDR, \
|
||||
.atcai2c.bus = ATCA_PARAM_I2C, \
|
||||
.atcai2c.baud = -1, /**< Not used in RIOT */ \
|
||||
.wake_delay = 1500, \
|
||||
.rx_retries = ATCA_RX_RETRIES }
|
||||
/**
|
||||
* @brief Configuration parameters for the primary ATCA device
|
||||
*/
|
||||
#define ATCA_PARAMS { .iface_type = ATCA_I2C_IFACE, \
|
||||
.devtype = ATCA_DEVTYPE, \
|
||||
.atcai2c.address = ATCA_PARAM_ADDR, \
|
||||
.atcai2c.bus = ATCA_PARAM_I2C, \
|
||||
.atcai2c.baud = -1, /**< Not used in RIOT */ \
|
||||
.wake_delay = 1500, \
|
||||
.rx_retries = ATCA_RX_RETRIES }
|
||||
#endif
|
||||
|
||||
/**@}*/
|
||||
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A)
|
||||
/**
|
||||
* @brief Structure to store ATCA device configuration
|
||||
*/
|
||||
typedef struct {
|
||||
psa_key_location_t atca_loc;
|
||||
ATCAIfaceCfg cfg; /**< ATCA configuration parameters */
|
||||
} atca_params_t;
|
||||
|
||||
/**
|
||||
* @brief Allocation of ATCA device descriptors
|
||||
*/
|
||||
static const atca_params_t atca_params[] =
|
||||
{
|
||||
ATCA_PARAMS
|
||||
};
|
||||
#else
|
||||
/**
|
||||
* @brief Allocation of ATCA device descriptors
|
||||
*/
|
||||
@ -76,6 +108,17 @@ static const ATCAIfaceCfg atca_params[] =
|
||||
{
|
||||
ATCA_PARAMS
|
||||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Number of connected devices
|
||||
*/
|
||||
#define ATCA_NUMOF (ARRAY_SIZE(atca_params))
|
||||
|
||||
/**
|
||||
* @brief List of device pointers for all available devices
|
||||
*/
|
||||
extern ATCADevice atca_devs_ptr[ATCA_NUMOF];
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
1
pkg/cryptoauthlib/psa_atca_driver/Makefile
Normal file
1
pkg/cryptoauthlib/psa_atca_driver/Makefile
Normal file
@ -0,0 +1 @@
|
||||
include $(RIOTBASE)/Makefile.base
|
691
pkg/cryptoauthlib/psa_atca_driver/psa_atca_se_driver.c
Normal file
691
pkg/cryptoauthlib/psa_atca_driver/psa_atca_se_driver.c
Normal file
@ -0,0 +1,691 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_psa_crypto
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Glue code translating between PSA Crypto and the Microchip Cryptoauth Library APIs
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "atca_params.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_se_driver.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
* @brief AES block size supported by ATCA devices
|
||||
*/
|
||||
#define AES_128_BLOCK_SIZE (16)
|
||||
|
||||
/**
|
||||
* @brief AES key size supported by ATCA devices
|
||||
*/
|
||||
#define AES_128_KEY_SIZE (16)
|
||||
|
||||
/**
|
||||
* @brief Size of an ellipic curve public key supported by ATCA devices
|
||||
*/
|
||||
#define ECC_P256_PUB_KEY_SIZE (64)
|
||||
|
||||
/**
|
||||
* @brief Maximum IV length supported by ATCA devices
|
||||
*/
|
||||
#define ATCA_MAX_IV_LEN (16)
|
||||
|
||||
/**
|
||||
* @brief Size of ATCA TempKey Register
|
||||
*/
|
||||
#define ATCA_WRITE_BUFFER_SIZE (32)
|
||||
|
||||
/**
|
||||
* @brief Check whether a specified algorithm is supported by this driver
|
||||
*
|
||||
* @param alg Algorithm of type @ref psa_algorithm_t
|
||||
*
|
||||
* @return int
|
||||
* 1 if @c alg is supported
|
||||
* 0 otherwise
|
||||
*/
|
||||
#define ALG_IS_SUPPORTED(alg) \
|
||||
((alg == PSA_ALG_ECB_NO_PADDING) || \
|
||||
(alg == PSA_ALG_CBC_NO_PADDING) || \
|
||||
(alg == PSA_ALG_ECDSA(PSA_ALG_SHA_256)) || \
|
||||
(alg == PSA_ALG_HMAC(PSA_ALG_SHA_256)))
|
||||
|
||||
/**
|
||||
* @brief Check whether a specified key size is supported by this driver
|
||||
*
|
||||
* @param size Size of the specified key
|
||||
* @param type Type of the specified key
|
||||
*
|
||||
* @return int
|
||||
* 1 if @c size is supported
|
||||
* 0 otherwise
|
||||
*/
|
||||
#define KEY_SIZE_IS_SUPPORTED(size, type) \
|
||||
((type == PSA_KEY_TYPE_AES && size == AES_128_KEY_SIZE) || \
|
||||
(PSA_KEY_TYPE_IS_ECC(type) && size == (ECC_P256_PUB_KEY_SIZE + 1)) || \
|
||||
(type == PSA_KEY_TYPE_HMAC && size == 32))
|
||||
|
||||
/**
|
||||
* @brief Convert ATCA status values to PSA errors
|
||||
*
|
||||
* @param error
|
||||
*
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
static psa_status_t atca_to_psa_error(ATCA_STATUS error)
|
||||
{
|
||||
switch (error) {
|
||||
case ATCA_NOT_LOCKED:
|
||||
case ATCA_EXECUTION_ERROR:
|
||||
case ATCA_FUNC_FAIL:
|
||||
return PSA_ERROR_BAD_STATE;
|
||||
case ATCA_WAKE_FAILED:
|
||||
case ATCA_RX_FAIL:
|
||||
case ATCA_RX_NO_RESPONSE:
|
||||
case ATCA_TX_TIMEOUT:
|
||||
case ATCA_RX_TIMEOUT:
|
||||
case ATCA_TOO_MANY_COMM_RETRIES:
|
||||
case ATCA_COMM_FAIL:
|
||||
case ATCA_TIMEOUT:
|
||||
case ATCA_TX_FAIL:
|
||||
return PSA_ERROR_COMMUNICATION_FAILURE;
|
||||
case ATCA_RX_CRC_ERROR:
|
||||
case ATCA_STATUS_CRC:
|
||||
return PSA_ERROR_DATA_CORRUPT;
|
||||
case ATCA_SMALL_BUFFER:
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
case ATCA_BAD_OPCODE:
|
||||
case ATCA_BAD_PARAM:
|
||||
case ATCA_INVALID_SIZE:
|
||||
case ATCA_INVALID_ID:
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
case ATCA_UNIMPLEMENTED:
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
default:
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
const char *atca_status_to_humanly_readable(ATCA_STATUS status)
|
||||
{
|
||||
switch (status) {
|
||||
case ATCA_NOT_LOCKED:
|
||||
return "ATCA_NOT_LOCKED";
|
||||
case ATCA_EXECUTION_ERROR:
|
||||
return "ATCA_EXECUTION_ERROR";
|
||||
case ATCA_FUNC_FAIL:
|
||||
return "ATCA_FUNC_FAIL";
|
||||
case ATCA_WAKE_FAILED:
|
||||
return "ATCA_WAKE_FAILED";
|
||||
case ATCA_RX_FAIL:
|
||||
return "ATCA_RX_FAIL";
|
||||
case ATCA_RX_NO_RESPONSE:
|
||||
return "ATCA_RX_NO_RESPONSE";
|
||||
case ATCA_TX_TIMEOUT:
|
||||
return "ATCA_TX_TIMEOUT";
|
||||
case ATCA_RX_TIMEOUT:
|
||||
return "ATCA_RX_TIMEOUT";
|
||||
case ATCA_TOO_MANY_COMM_RETRIES:
|
||||
return "ATCA_TOO_MANY_COMM_RETRIES";
|
||||
case ATCA_COMM_FAIL:
|
||||
return "ATCA_COMM_FAIL";
|
||||
case ATCA_TIMEOUT:
|
||||
return "ATCA_TIMEOUT";
|
||||
case ATCA_TX_FAIL:
|
||||
return "ATCA_TX_FAIL";
|
||||
case ATCA_RX_CRC_ERROR:
|
||||
return "ATCA_RX_CRC_ERROR";
|
||||
case ATCA_STATUS_CRC:
|
||||
return "ATCA_STATUS_CRC";
|
||||
case ATCA_SMALL_BUFFER:
|
||||
return "ATCA_SMALL_BUFFER";
|
||||
case ATCA_BAD_OPCODE:
|
||||
return "ATCA_BAD_OPCODE";
|
||||
case ATCA_BAD_PARAM:
|
||||
return "ATCA_BAD_PARAM";
|
||||
case ATCA_INVALID_SIZE:
|
||||
return "ATCA_INVALID_SIZE";
|
||||
case ATCA_INVALID_ID:
|
||||
return "ATCA_INVALID_ID";
|
||||
case ATCA_UNIMPLEMENTED:
|
||||
return "ATCA_UNIMPLEMENTED";
|
||||
default:
|
||||
return "Error value not recognized";
|
||||
}
|
||||
}
|
||||
|
||||
/* Secure Element Cipher Functions */
|
||||
/**
|
||||
* @brief Set up a driver specific AES CBC mode operation
|
||||
*
|
||||
* @param ctx
|
||||
* @param dev
|
||||
* @param key_slot
|
||||
*/
|
||||
static void atca_cbc_setup(atca_aes_cbc_ctx_t *ctx,
|
||||
ATCADevice dev,
|
||||
psa_key_slot_number_t key_slot)
|
||||
{
|
||||
ctx->device = dev;
|
||||
ctx->key_id = key_slot;
|
||||
ctx->key_block = 0;
|
||||
}
|
||||
|
||||
psa_status_t atca_cipher_setup(psa_drv_se_context_t *drv_context,
|
||||
void *op_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t algorithm,
|
||||
psa_encrypt_or_decrypt_t direction)
|
||||
{
|
||||
ATCADevice dev = (ATCADevice)drv_context->transient_data;
|
||||
psa_se_cipher_context_t *ctx = (psa_se_cipher_context_t *)op_context;
|
||||
|
||||
/* Only device type ATECC608 supports AES operations */
|
||||
if (dev->mIface.mIfaceCFG->devtype != ATECC608) {
|
||||
DEBUG("ATCA Cipher Setup: Only ATECC608 devices support AES operations.\n");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
switch (algorithm) {
|
||||
case PSA_ALG_CBC_NO_PADDING:
|
||||
atca_cbc_setup(&ctx->drv_ctx.atca_aes_cbc, dev, key_slot);
|
||||
break;
|
||||
default:
|
||||
DEBUG("ATCA Cipher Setup: Algorithm not supported by implementation.\n");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
ctx->direction = direction;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t atca_cipher_set_iv(void *op_context,
|
||||
const uint8_t *p_iv,
|
||||
size_t iv_length)
|
||||
{
|
||||
|
||||
atca_aes_cbc_ctx_t *ctx = &((psa_se_cipher_context_t *)op_context)->drv_ctx.atca_aes_cbc;
|
||||
|
||||
if (iv_length != ATCA_MAX_IV_LEN) {
|
||||
DEBUG("ATCA Cipher Set IV: Invalid IV length: Expected %d, was %d\n", \
|
||||
ATCA_MAX_IV_LEN, iv_length);
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
memcpy(ctx->ciphertext, p_iv, iv_length);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t atca_cipher_update(void *op_context,
|
||||
const uint8_t *p_input,
|
||||
size_t input_size,
|
||||
uint8_t *p_output,
|
||||
size_t output_size,
|
||||
size_t *p_output_length)
|
||||
{
|
||||
psa_se_cipher_context_t *ctx = (psa_se_cipher_context_t *)op_context;
|
||||
ATCA_STATUS status = ATCA_EXECUTION_ERROR;
|
||||
size_t offset = 0;
|
||||
|
||||
for (size_t data_block = 0; data_block < (input_size / AES_128_BLOCK_SIZE); data_block++) {
|
||||
offset = data_block * AES_128_BLOCK_SIZE;
|
||||
if (ctx->direction == PSA_CRYPTO_DRIVER_ENCRYPT) {
|
||||
status = atcab_aes_cbc_encrypt_block(&ctx->drv_ctx.atca_aes_cbc, p_input + offset,
|
||||
p_output + offset);
|
||||
}
|
||||
else {
|
||||
status = atcab_aes_cbc_decrypt_block(&ctx->drv_ctx.atca_aes_cbc, p_input + offset,
|
||||
p_output + offset);
|
||||
}
|
||||
|
||||
if (status != ATCA_SUCCESS) {
|
||||
DEBUG("ATCA Cipher Update failed. ATCA Error: %s\n",
|
||||
atca_status_to_humanly_readable(status));
|
||||
return atca_to_psa_error(status);
|
||||
}
|
||||
}
|
||||
|
||||
*p_output_length += input_size;
|
||||
|
||||
(void)output_size;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t atca_cipher_finish(void *op_context,
|
||||
uint8_t *p_output,
|
||||
size_t output_size,
|
||||
size_t *p_output_length)
|
||||
{
|
||||
(void)op_context;
|
||||
(void)p_output;
|
||||
(void)output_size;
|
||||
(void)p_output_length;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t atca_cipher_ecb(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t algorithm,
|
||||
psa_encrypt_or_decrypt_t direction,
|
||||
const uint8_t *p_input,
|
||||
size_t input_size,
|
||||
uint8_t *p_output,
|
||||
size_t output_size)
|
||||
{
|
||||
ATCA_STATUS status;
|
||||
ATCADevice dev = (ATCADevice)drv_context->transient_data;
|
||||
size_t offset = 0;
|
||||
|
||||
if (dev->mIface.mIfaceCFG->devtype != ATECC608) {
|
||||
DEBUG("ATCA Cipher ECB: Only ATECC608 devices support AES operations.\n");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (algorithm != PSA_ALG_ECB_NO_PADDING || direction != PSA_CRYPTO_DRIVER_ENCRYPT) {
|
||||
DEBUG("ATCA Cipher ECB: Only AES ECB encryption without padding is supported.\n");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (input_size % AES_128_BLOCK_SIZE != 0) {
|
||||
DEBUG("ATCA Cipher ECB: Input must be multiple of 16, was %d.\n", input_size);
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
do {
|
||||
status = calib_aes_encrypt(dev, key_slot, 0, p_input + offset, p_output + offset);
|
||||
if (status != ATCA_SUCCESS) {
|
||||
DEBUG("ATCA Cipher ECB encrypt failed. ATCA Error: %s\n",
|
||||
atca_status_to_humanly_readable(status));
|
||||
return atca_to_psa_error(status);
|
||||
}
|
||||
|
||||
offset += AES_128_BLOCK_SIZE;
|
||||
} while (offset < input_size);
|
||||
|
||||
(void)output_size;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
/* Secure Element Key Management Functions */
|
||||
|
||||
psa_status_t atca_allocate(psa_drv_se_context_t *drv_context,
|
||||
void *persistent_data,
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_key_creation_method_t method,
|
||||
psa_key_slot_number_t *key_slot)
|
||||
{
|
||||
if (!ALG_IS_SUPPORTED(attributes->policy.alg)) {
|
||||
DEBUG("ATCA allocate: Algorithm is not supported by device.\n");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
psa_key_type_t type = attributes->type;
|
||||
psa_se_config_t *device_config = (psa_se_config_t *)persistent_data;
|
||||
psa_atca_slot_config_t *slot_config = device_config->slots;
|
||||
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (slot_config[i].key_type_allowed == type) {
|
||||
/* If a slot is occupied, but the stored key is not marked as persistent,
|
||||
we treat it as an empty slot and overwrite the key */
|
||||
if (slot_config[i].slot_occupied && slot_config[i].key_persistent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
*key_slot = i;
|
||||
|
||||
(&slot_config[i])->slot_occupied = 1;
|
||||
|
||||
DEBUG("Allocating slot %d for key type %x\n", (int)*key_slot, attributes->type);
|
||||
|
||||
if (PSA_KEY_LIFETIME_GET_PERSISTENCE(attributes->lifetime) != \
|
||||
PSA_KEY_PERSISTENCE_VOLATILE) {
|
||||
(&slot_config[i])->key_persistent = 1;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
(void)drv_context;
|
||||
(void)method;
|
||||
|
||||
DEBUG("ATCA allocate: No free slot available.\n");
|
||||
return PSA_ERROR_INSUFFICIENT_STORAGE;
|
||||
}
|
||||
|
||||
psa_status_t atca_destroy(psa_drv_se_context_t *drv_context,
|
||||
void *persistent_data,
|
||||
psa_key_slot_number_t key_slot)
|
||||
{
|
||||
/**
|
||||
* The ATECCX08A driver does not provide a key destruction function.
|
||||
*
|
||||
* This function just sets the `slot_occupied` flag in the driver's persistent
|
||||
* data to 0, in case the key generation or import goes wrong, so the slot can
|
||||
* be reused.
|
||||
*/
|
||||
psa_atca_slot_config_t *slot_config = (psa_atca_slot_config_t *)persistent_data;
|
||||
|
||||
DEBUG("Setting Key Slot %d to not occupied.\n", (int)key_slot);
|
||||
(&slot_config[key_slot])->slot_occupied = 0;
|
||||
|
||||
(void)drv_context;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t atca_import(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data,
|
||||
size_t data_length,
|
||||
size_t *bits)
|
||||
{
|
||||
ATCA_STATUS status;
|
||||
ATCADevice dev = (ATCADevice)drv_context->transient_data;
|
||||
|
||||
if (!ALG_IS_SUPPORTED(attributes->policy.alg)) {
|
||||
DEBUG("ATCA import: Algorithm is not supported by device.\n");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (!KEY_SIZE_IS_SUPPORTED(data_length, attributes->type)) {
|
||||
DEBUG("ATCA import: Key size is not supported by device.\n");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (PSA_KEY_TYPE_IS_ECC_PUBLIC_KEY(attributes->type)) {
|
||||
status = calib_write_pubkey(dev, key_slot, data + 1);
|
||||
if (status != ATCA_SUCCESS) {
|
||||
DEBUG("ATCA Write Pubkey failed. ATCA Error: %s\n",
|
||||
atca_status_to_humanly_readable(status));
|
||||
return atca_to_psa_error(status);
|
||||
}
|
||||
*bits = PSA_BYTES_TO_BITS(data_length);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
else {
|
||||
if (data_length > ATCA_WRITE_BUFFER_SIZE) {
|
||||
DEBUG("ATCA import: Key size too large.\n");
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
uint8_t buf_in[ATCA_WRITE_BUFFER_SIZE] = { 0 };
|
||||
/* AES keys can be written to slots in 32 or 64 byte chunks. For this we
|
||||
copy them into a 32 byte buffer first and pad the empty bits with 0 */
|
||||
memcpy(buf_in, data, data_length);
|
||||
status = calib_write_bytes_zone(dev, ATCA_ZONE_DATA, key_slot, 0, buf_in, sizeof(buf_in));
|
||||
if (status != ATCA_SUCCESS) {
|
||||
DEBUG("ATCA Write AES key failed. ATCA Error: %s\n",
|
||||
atca_status_to_humanly_readable(status));
|
||||
return atca_to_psa_error(status);
|
||||
}
|
||||
|
||||
*bits = PSA_BYTES_TO_BITS(data_length);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
DEBUG("ATCA import: Operation is not supported.\n");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
psa_status_t atca_generate_key(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
const psa_key_attributes_t *attributes,
|
||||
uint8_t *pubkey, size_t pubkey_size, size_t *pubkey_length)
|
||||
{
|
||||
ATCA_STATUS status;
|
||||
ATCADevice dev = (ATCADevice)drv_context->transient_data;
|
||||
|
||||
if (!PSA_KEY_TYPE_IS_ECC(attributes->type)) {
|
||||
DEBUG("ATCA Generate Key: Only ECC key generation is supported.\n");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (pubkey_size > PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(attributes->type, attributes->bits)) {
|
||||
DEBUG("ATCA Generate Key: Pubkey size not supported. Expected %d, was %d.\n", \
|
||||
PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(attributes->type, attributes->bits), pubkey_size);
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (pubkey != NULL) {
|
||||
/**
|
||||
* PSA supports the uncompressed binary format to encode ECC public keys.
|
||||
* This means, that both the x and y coordinate are stored.
|
||||
* This format is encoded by adding an extra byte containing the value 0x04
|
||||
* (see also "Technical Guideline BSI TR-03111").
|
||||
*
|
||||
* The ATECCX08A stores and exports the x and y coordinate, so all we need to do is
|
||||
* add the byte before the coordinates.
|
||||
*/
|
||||
pubkey[0] = 0x04;
|
||||
*pubkey_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(attributes->type, attributes->bits);
|
||||
status = calib_genkey(dev, key_slot, &pubkey[1]);
|
||||
}
|
||||
else {
|
||||
status = calib_genkey(dev, key_slot, NULL);
|
||||
}
|
||||
|
||||
if (status != ATCA_SUCCESS) {
|
||||
DEBUG("ATCA Genkey failed. ATCA Error: %s\n",
|
||||
atca_status_to_humanly_readable(status));
|
||||
return atca_to_psa_error(status);
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t atca_export_public_key(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
uint8_t *p_data,
|
||||
size_t data_size,
|
||||
size_t *p_data_length)
|
||||
{
|
||||
ATCA_STATUS status;
|
||||
ATCADevice dev = (ATCADevice)drv_context->transient_data;
|
||||
|
||||
if (data_size < ECC_P256_PUB_KEY_SIZE) {
|
||||
DEBUG("ATCA Export public key: Buffer too small, expected %d, was %d\n", \
|
||||
ECC_P256_PUB_KEY_SIZE, data_size);
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
status = calib_get_pubkey(dev, key_slot, &p_data[1]);
|
||||
if (status != ATCA_SUCCESS) {
|
||||
DEBUG("ATCA Get Pubkey failed. ATCA Error: %s\n",
|
||||
atca_status_to_humanly_readable(status));
|
||||
return atca_to_psa_error(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* PSA supports the uncompressed binary format to encode ECC public keys.
|
||||
* This means, that both the x and y coordinate are stored.
|
||||
* This format is encoded by adding an extra byte containing the value 0x04
|
||||
* (see also "Technical Guideline BSI TR-03111").
|
||||
*
|
||||
* The ATECCX08A stored and exports the x and y coordinate, so all we need to do is
|
||||
* add the byte before the coordinates.
|
||||
*/
|
||||
p_data[0] = 0x04;
|
||||
|
||||
/* Since we added the encoding byte, the stored public key is now 65 bytes long instead of 64 */
|
||||
*p_data_length = ECC_P256_PUB_KEY_SIZE + 1;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t atca_sign(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *p_hash,
|
||||
size_t hash_length,
|
||||
uint8_t *p_signature,
|
||||
size_t signature_size,
|
||||
size_t *p_signature_length)
|
||||
{
|
||||
ATCA_STATUS status;
|
||||
ATCADevice dev = (ATCADevice)drv_context->transient_data;
|
||||
|
||||
if (alg != PSA_ALG_ECDSA(PSA_ALG_SHA_256)) {
|
||||
DEBUG("ATCA Sign: Only ECDSA with SHA256 Messages is supported.\n");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if ((signature_size != ECC_P256_PUB_KEY_SIZE) || \
|
||||
(hash_length != PSA_HASH_LENGTH(PSA_ALG_SHA_256))) {
|
||||
DEBUG("ATCA Sign: Invalid signature or hash size. Expected Sig: %d |\
|
||||
Hash %d, were Sig: %d | Hash: %d\n",\
|
||||
ECC_P256_PUB_KEY_SIZE, PSA_HASH_LENGTH(PSA_ALG_SHA_256),\
|
||||
signature_size, hash_length);
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
status = calib_sign(dev, key_slot, p_hash, p_signature);
|
||||
if (status != ATCA_SUCCESS) {
|
||||
DEBUG("ATCA Sign failed. ATCA Error: %s\n",
|
||||
atca_status_to_humanly_readable(status));
|
||||
return atca_to_psa_error(status);
|
||||
}
|
||||
|
||||
*p_signature_length = signature_size;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t atca_verify(psa_drv_se_context_t *drv_context,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *p_hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *p_signature,
|
||||
size_t signature_length)
|
||||
{
|
||||
ATCA_STATUS status;
|
||||
ATCADevice dev = (ATCADevice)drv_context->transient_data;
|
||||
|
||||
bool is_verified;
|
||||
|
||||
/* We only support the operation on public keys, if they're stored on a device. */
|
||||
if (alg != PSA_ALG_ECDSA(PSA_ALG_SHA_256)) {
|
||||
DEBUG("ATCA Verify: Only ECDSA with SHA256 Messages is supported.\n");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if ((signature_length != ECC_P256_PUB_KEY_SIZE) || \
|
||||
(hash_length != PSA_HASH_LENGTH(PSA_ALG_SHA_256))) {
|
||||
DEBUG("ATCA Sign: Invalid signature or hash size. Expected Sig: %d |\
|
||||
Hash %d, were Sig: %d | Hash: %d\n",\
|
||||
ECC_P256_PUB_KEY_SIZE, PSA_HASH_LENGTH(PSA_ALG_SHA_256),\
|
||||
signature_length, hash_length);
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
status = calib_verify_stored(dev, p_hash, p_signature, key_slot, &is_verified);
|
||||
if (status != ATCA_SUCCESS) {
|
||||
DEBUG("ATCA Verify failed. ATCA Error: %s\n",
|
||||
atca_status_to_humanly_readable(status));
|
||||
return atca_to_psa_error(status);
|
||||
}
|
||||
|
||||
return is_verified ? PSA_SUCCESS : PSA_ERROR_INVALID_SIGNATURE;
|
||||
}
|
||||
|
||||
psa_status_t atca_generate_mac(psa_drv_se_context_t *drv_context,
|
||||
const uint8_t *p_input,
|
||||
size_t input_length,
|
||||
psa_key_slot_number_t key_slot,
|
||||
psa_algorithm_t alg,
|
||||
uint8_t *p_mac,
|
||||
size_t mac_size,
|
||||
size_t *p_mac_length)
|
||||
{
|
||||
ATCA_STATUS status;
|
||||
ATCADevice dev = (ATCADevice)drv_context->transient_data;
|
||||
|
||||
if (!PSA_ALG_IS_HMAC(alg)) {
|
||||
DEBUG("ATCA Generate MAC: Only HMAC SHA256 is supported.\n");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (mac_size < PSA_HASH_LENGTH(PSA_ALG_SHA_256)) {
|
||||
DEBUG("ATCA Generate Mac: Buffer too small, expected %d, was %d\n", \
|
||||
PSA_HASH_LENGTH(PSA_ALG_SHA_256), mac_size);
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
status = calib_sha_hmac(dev, p_input, input_length, key_slot, p_mac, SHA_MODE_TARGET_OUT_ONLY);
|
||||
if (status != ATCA_SUCCESS) {
|
||||
DEBUG("ATCA SHA HMAC failed. ATCA Error: %s\n",
|
||||
atca_status_to_humanly_readable(status));
|
||||
return atca_to_psa_error(status);
|
||||
}
|
||||
*p_mac_length = PSA_HASH_LENGTH(PSA_ALG_SHA_256);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
static psa_drv_se_mac_t atca_mac = {
|
||||
.context_size = 0,
|
||||
.p_setup = NULL,
|
||||
.p_update = NULL,
|
||||
.p_finish = NULL,
|
||||
.p_finish_verify = NULL,
|
||||
.p_abort = NULL,
|
||||
.p_mac = atca_generate_mac,
|
||||
.p_mac_verify = NULL,
|
||||
};
|
||||
|
||||
static psa_drv_se_cipher_t atca_cipher = {
|
||||
.context_size = 0,
|
||||
.p_setup = atca_cipher_setup,
|
||||
.p_set_iv = atca_cipher_set_iv,
|
||||
.p_update = atca_cipher_update,
|
||||
.p_finish = atca_cipher_finish,
|
||||
.p_abort = NULL,
|
||||
.p_ecb = atca_cipher_ecb
|
||||
};
|
||||
|
||||
static psa_drv_se_key_management_t atca_key_management = {
|
||||
.p_allocate = atca_allocate,
|
||||
.p_validate_slot_number = NULL,
|
||||
.p_import = atca_import,
|
||||
.p_generate = atca_generate_key,
|
||||
.p_destroy = atca_destroy,
|
||||
.p_export = NULL,
|
||||
.p_export_public = atca_export_public_key
|
||||
};
|
||||
|
||||
static psa_drv_se_asymmetric_t atca_asymmetric = {
|
||||
.p_sign = atca_sign,
|
||||
.p_verify = atca_verify,
|
||||
.p_encrypt = NULL,
|
||||
.p_decrypt = NULL
|
||||
};
|
||||
|
||||
psa_drv_se_t atca_methods = {
|
||||
.hal_version = PSA_DRV_SE_HAL_VERSION,
|
||||
.persistent_data_size = 0,
|
||||
.p_init = NULL,
|
||||
.key_management = &atca_key_management,
|
||||
.mac = &atca_mac,
|
||||
.cipher = &atca_cipher,
|
||||
.aead = NULL,
|
||||
.asymmetric = &atca_asymmetric,
|
||||
.derivation = NULL
|
||||
};
|
19
pkg/driver_cryptocell_310/Kconfig
Normal file
19
pkg/driver_cryptocell_310/Kconfig
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2020 HAW Hamburg
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU Lesser
|
||||
# General Public License v2.1. See the file LICENSE in the top level
|
||||
# directory for more details.
|
||||
#
|
||||
|
||||
config PACKAGE_DRIVER_CRYPTOCELL_310
|
||||
bool
|
||||
depends on CPU_MODEL_NRF52840XXAA
|
||||
depends on TEST_KCONFIG
|
||||
depends on HAS_PERIPH_CRYPTOCELL_310
|
||||
depends on MODULE_PERIPH_CRYPTOCELL_310
|
||||
select MODULE_DRIVER_CRYPTOCELL_310_CONTRIB
|
||||
|
||||
config MODULE_DRIVER_CRYPTOCELL_310_CONTRIB
|
||||
bool
|
||||
|
||||
rsource "psa_cryptocell_310/Kconfig"
|
36
pkg/driver_cryptocell_310/Makefile
Normal file
36
pkg/driver_cryptocell_310/Makefile
Normal file
@ -0,0 +1,36 @@
|
||||
PKG_NAME=driver_cryptocell_310
|
||||
PKG_URL=https://www.nordicsemi.com/-/media/Software-and-other-downloads/SDKs/nRF5/Binaries
|
||||
PKG_VERSION=17.1.0
|
||||
PKG_EXT=zip
|
||||
PKG_DIR_NAME=nRF5_SDK_17.1.0_ddde560
|
||||
PKG_LICENSE=ARM Object Code and Header Files License
|
||||
|
||||
PKG_SOURCE_DIR ?= $(PKGDIRBASE)/$(PKG_NAME)
|
||||
NRF_CC310_PATH = $(PKG_DIR_NAME)/external/nrf_cc310
|
||||
PKG_ZIPFILE = $(PKG_DIR_NAME).$(PKG_EXT)
|
||||
|
||||
ifneq ($(RIOTBASE),)
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
endif
|
||||
|
||||
.PHONY: all clean distclean prepare
|
||||
|
||||
prepare: $(PKG_PREPARED)
|
||||
@:
|
||||
|
||||
all: $(PKGDIRBASE)/$(PKG_ZIPFILE)
|
||||
$(Q)$(UNZIP_HERE) -D -n -d $(PKGDIRBASE) $(PKGDIRBASE)/$(PKG_ZIPFILE)
|
||||
$(Q) mkdir -p $(PKG_SOURCE_DIR)/include
|
||||
$(Q)cp $(PKGDIRBASE)/$(NRF_CC310_PATH)/include/* $(PKG_SOURCE_DIR)/include
|
||||
$(Q)cp $(PKGDIRBASE)/$(NRF_CC310_PATH)/lib/cortex-m4/hard-float/libnrf_cc310_0.9.13.a $(PKG_SOURCE_DIR)
|
||||
$(Q)rm -rf $(PKGDIRBASE)/$(PKG_DIR_NAME)
|
||||
|
||||
$(PKGDIRBASE)/$(PKG_ZIPFILE):
|
||||
$(QQ)mkdir -p $(PKGDIRBASE)
|
||||
$(Q)$(DOWNLOAD_TO_FILE) $(PKGDIRBASE)/$(PKG_ZIPFILE) $(PKG_URL)/$(PKG_ZIPFILE)
|
||||
|
||||
clean::
|
||||
rm -rf $(PKG_SOURCE_DIR)
|
||||
|
||||
distclean::
|
||||
rm -rf $(PKG_SOURCE_DIR) $(PKGDIRBASE)/$(PKG_ZIPFILE)
|
6
pkg/driver_cryptocell_310/Makefile.dep
Normal file
6
pkg/driver_cryptocell_310/Makefile.dep
Normal file
@ -0,0 +1,6 @@
|
||||
USEMODULE += driver_cryptocell_310_contrib
|
||||
FEATURES_REQUIRED += periph_cryptocell_310
|
||||
|
||||
ifneq (,$(filter psa_cryptocell_310_%,$(USEMODULE)))
|
||||
include $(RIOTPKG)/driver_cryptocell_310/psa_cryptocell_310/Makefile.dep
|
||||
endif
|
25
pkg/driver_cryptocell_310/Makefile.include
Normal file
25
pkg/driver_cryptocell_310/Makefile.include
Normal file
@ -0,0 +1,25 @@
|
||||
INCLUDES += -I$(PKGDIRBASE)/driver_cryptocell_310/include
|
||||
INCLUDES += -I$(RIOTPKG)/driver_cryptocell_310/include
|
||||
DIRS += $(RIOTPKG)/driver_cryptocell_310/contrib
|
||||
|
||||
ARCHIVES += $(PKGDIRBASE)/driver_cryptocell_310/libnrf_cc310_0.9.13.a
|
||||
|
||||
ifneq (,$(filter psa_cryptocell_310_%, $(USEMODULE)))
|
||||
DIRS += $(RIOTPKG)/driver_cryptocell_310/psa_cryptocell_310
|
||||
INCLUDES += -I$(RIOTBASE)/sys/psa_crypto/include
|
||||
endif
|
||||
|
||||
CFLAGS += -Wno-cast-align
|
||||
|
||||
PSEUDOMODULES += psa_cryptocell_310_aes_cbc
|
||||
PSEUDOMODULES += psa_cryptocell_310_aes_common
|
||||
PSEUDOMODULES += psa_cryptocell_310_ecc_common
|
||||
PSEUDOMODULES += psa_cryptocell_310_ecc_p192
|
||||
PSEUDOMODULES += psa_cryptocell_310_ecc_p256
|
||||
PSEUDOMODULES += psa_cryptocell_310_error_conversion
|
||||
PSEUDOMODULES += psa_cryptocell_310_hashes_common
|
||||
PSEUDOMODULES += psa_cryptocell_310_hashes_sha1
|
||||
PSEUDOMODULES += psa_cryptocell_310_hashes_sha224
|
||||
PSEUDOMODULES += psa_cryptocell_310_hashes_sha256
|
||||
PSEUDOMODULES += psa_cryptocell_310_hashes_sha512
|
||||
PSEUDOMODULES += psa_cryptocell_310_hmac
|
3
pkg/driver_cryptocell_310/contrib/Makefile
Normal file
3
pkg/driver_cryptocell_310/contrib/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = driver_cryptocell_310_contrib
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
83
pkg/driver_cryptocell_310/contrib/cryptocell_util.c
Normal file
83
pkg/driver_cryptocell_310/contrib/cryptocell_util.c
Normal file
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2020 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Setup function necessary to enable ARM CryptoCell module
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*/
|
||||
|
||||
#include "vendor/nrf52840.h"
|
||||
#include "sns_silib.h"
|
||||
#include "kernel_defines.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
CRYS_RND_WorkBuff_t *rndWorkBuff_ptr;
|
||||
CRYS_RND_State_t *rndState_ptr;
|
||||
|
||||
CRYS_RND_State_t rndState = { 0 };
|
||||
CRYS_RND_WorkBuff_t rndWorkBuff = { 0 };
|
||||
|
||||
/* Defined by the CryptoCell Library */
|
||||
extern void CRYPTOCELL_IRQHandler(void);
|
||||
|
||||
/* This function must be defined to use the CryptoCell module on the NRF52840 board */
|
||||
void isr_cryptocell(void)
|
||||
{
|
||||
CRYPTOCELL_IRQHandler();
|
||||
}
|
||||
|
||||
void cryptocell_310_enable(void)
|
||||
{
|
||||
NRF_CRYPTOCELL->ENABLE = 1;
|
||||
NVIC_EnableIRQ(CRYPTOCELL_IRQn);
|
||||
}
|
||||
|
||||
void cryptocell_310_disable(void)
|
||||
{
|
||||
NRF_CRYPTOCELL->ENABLE = 0;
|
||||
NVIC_DisableIRQ(CRYPTOCELL_IRQn);
|
||||
}
|
||||
|
||||
void driver_cryptocell_310_setup(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
rndState_ptr = &rndState;
|
||||
rndWorkBuff_ptr = &rndWorkBuff;
|
||||
|
||||
cryptocell_310_enable();
|
||||
|
||||
ret = SaSi_LibInit();
|
||||
if (ret != SA_SILIB_RET_OK) {
|
||||
DEBUG("SaSi_LibInit failed: 0x%x\n", ret);
|
||||
}
|
||||
|
||||
ret = CRYS_RndInit(rndState_ptr, rndWorkBuff_ptr);
|
||||
if (ret != SA_SILIB_RET_OK) {
|
||||
DEBUG("CRYS_RndInit failed: 0x%x\n", ret);
|
||||
}
|
||||
}
|
||||
|
||||
void driver_cryptocell_310_terminate(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
SaSi_LibFini();
|
||||
|
||||
ret = CRYS_RND_UnInstantiation(rndState_ptr);
|
||||
if (ret != SA_SILIB_RET_OK) {
|
||||
DEBUG("CRYS_RND_UnInstatiation failed: 0x%x\n", ret);
|
||||
}
|
||||
}
|
10
pkg/driver_cryptocell_310/doc.txt
Normal file
10
pkg/driver_cryptocell_310/doc.txt
Normal file
@ -0,0 +1,10 @@
|
||||
/**
|
||||
* @defgroup pkg_driver_cryptocell_310 ARM CryptoCell 310 Driver
|
||||
* @ingroup pkg drivers_misc
|
||||
* @brief Provides the driver for the ARM CryptoCell 310 hardware accelerator
|
||||
* @see https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.1.0/group__cryptocell__api.html
|
||||
*
|
||||
* @note The source of this package is not a git repository, but a zip file downloaded
|
||||
* from the Nordic Semiconductor software center. It is quite large and takes a
|
||||
* while to download.
|
||||
*/
|
3
pkg/driver_cryptocell_310/driver_cryptocell_310.mk
Normal file
3
pkg/driver_cryptocell_310/driver_cryptocell_310.mk
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE = driver_cryptocell_310
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
61
pkg/driver_cryptocell_310/include/cryptocell_310_util.h
Normal file
61
pkg/driver_cryptocell_310/include/cryptocell_310_util.h
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Utility functions to setup and terminate the CryptoCell 310 driver
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
#ifndef CRYPTOCELL_310_UTIL_H
|
||||
#define CRYPTOCELL_310_UTIL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Enable CryptoCell module and IRQs.
|
||||
*
|
||||
* Must be called before using crypto functions.
|
||||
* CryptoCell peripheral will be enabled after this call.
|
||||
*/
|
||||
void cryptocell_310_enable(void);
|
||||
|
||||
/**
|
||||
* @brief Disable CryptoCell module and IRQs.
|
||||
*
|
||||
* Should be called after using crypto functions.
|
||||
* CryptoCell peripheral will be disabled after this call.
|
||||
*/
|
||||
void cryptocell_310_disable(void);
|
||||
|
||||
/**
|
||||
* @brief Enables CryptoCell module, IRQs and crypto libraries on nrf52840.
|
||||
*
|
||||
* Must be called once before using the CryptoCell lib.
|
||||
*/
|
||||
void driver_cryptocell_310_setup(void);
|
||||
|
||||
/**
|
||||
* @brief Finishes the use of the CryptoCell library.
|
||||
*
|
||||
* Should be called after using the CryptoCell lib.
|
||||
*/
|
||||
void driver_cryptocell_310_terminate(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CRYPTOCELL_310_UTIL_H */
|
||||
/** @} */
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Common AES functions used by all PSA Crypto wrappers
|
||||
* for the CryptoCell 310 AES APIs.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTOCELL_310_AES_COMMON_H
|
||||
#define PSA_CRYPTOCELL_310_AES_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
/**
|
||||
* @brief Common setup function for AES operations
|
||||
*
|
||||
* @param ctx Driver specific AES context of the type @c SaSiAesUserContext_t
|
||||
* @param direction Encrypt or decrypt direction of type @c SaSiAesEncryptMode_t
|
||||
* @param mode Operation mode (e.g. CBC, CCM) of type @c SaSiAesOperationMode_t
|
||||
* @param padding Operation padding type of type @c SaSiAesPaddingType_t
|
||||
* @param iv Constant buffer containing the IV for the operation
|
||||
* @param key_buffer Constant buffer containing an AES key
|
||||
* @param key_size Size of AES key in use.
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t cryptocell_310_common_aes_setup(SaSiAesUserContext_t *ctx,
|
||||
SaSiAesEncryptMode_t direction,
|
||||
SaSiAesOperationMode_t mode,
|
||||
SaSiAesPaddingType_t padding,
|
||||
const uint8_t *iv,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_size);
|
||||
|
||||
/**
|
||||
* @brief Common function for an AES encryption
|
||||
*
|
||||
* @param ctx AES context of the type @c SaSiAesUserContext_t
|
||||
* @param input Constant input buffer of plain text to encrypt
|
||||
* @param input_length Length of the input buffer
|
||||
* @param output Output buffer to write the cipher
|
||||
* @param output_buffer_size Size of the output buffer. Must be at least @c input_length
|
||||
* @param output_length Pointer to output length. Will contain actual length of cipher
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t cryptocell_310_common_aes_encrypt_decrypt(SaSiAesUserContext_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_buffer_size,
|
||||
size_t *output_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTOCELL_310_AES_COMMON_H */
|
||||
/** @} */
|
@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Common ECC functions used by all PSA Crypto wrappers
|
||||
* for the CryptoCell 310 ECC APIs.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTOCELL_310_ECC_COMMON_H
|
||||
#define PSA_CRYPTOCELL_310_ECC_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
|
||||
#include "sns_silib.h"
|
||||
#include "crys_ecpki_build.h"
|
||||
#include "crys_ecpki_ecdsa.h"
|
||||
#include "crys_ecpki_kg.h"
|
||||
#include "crys_ecpki_domain.h"
|
||||
|
||||
/**
|
||||
* @brief Map PSA hash encodings to CryptoCell specific hash encodings
|
||||
*
|
||||
* @param hash psa_algorithm_t
|
||||
*/
|
||||
#define MAP_PSA_HASH_TO_CRYS_HASH(hash) \
|
||||
((hash == PSA_ALG_SHA_1) ? CRYS_ECPKI_AFTER_HASH_SHA1_mode : \
|
||||
(hash == PSA_ALG_SHA_224) ? CRYS_ECPKI_AFTER_HASH_SHA224_mode : \
|
||||
(hash == PSA_ALG_SHA_256) ? CRYS_ECPKI_AFTER_HASH_SHA256_mode : \
|
||||
(hash == PSA_ALG_SHA_384) ? CRYS_ECPKI_AFTER_HASH_SHA384_mode : \
|
||||
(hash == PSA_ALG_SHA_512) ? CRYS_ECPKI_AFTER_HASH_SHA512_mode : \
|
||||
0)
|
||||
|
||||
/**
|
||||
* @brief Common ECC key generation function
|
||||
*
|
||||
* @param priv_key_buffer Output buffer to write ECC private key
|
||||
* @param pub_key_buffer Output buffer to write ECC public key
|
||||
* @param priv_key_buffer_length Output pointer to write private key length
|
||||
* @param pub_key_buffer_length Output pointer to write public key length
|
||||
* @param domain ECC domain of type @c CRYS_ECPKI_DomainID_t
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t cryptocell_310_common_ecc_generate_key_pair(uint8_t *priv_key_buffer,
|
||||
uint8_t *pub_key_buffer,
|
||||
uint32_t *priv_key_buffer_length,
|
||||
uint32_t *pub_key_buffer_length,
|
||||
CRYS_ECPKI_DomainID_t domain);
|
||||
|
||||
/**
|
||||
* @brief Common ECC hash signature function
|
||||
*
|
||||
* @param priv_key Pointer to ECC private key
|
||||
* @param priv_key_size Size of private key
|
||||
* @param hash Hash of the message to sign
|
||||
* @param hash_length Length of the message hash
|
||||
* @param signature Output buffer to write the generated signature
|
||||
* @param signature_length Pointer to store the actual length of the signature
|
||||
* @param hash_mode Mode used to hash the message of type @c CRYS_ECPKI_HASH_OpMode_t
|
||||
* @param domain ECC domain of type @c CRYS_ECPKI_DomainID_t
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t cryptocell_310_common_ecc_sign_hash(const uint8_t *priv_key,
|
||||
uint32_t priv_key_size,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
uint8_t *signature,
|
||||
size_t *signature_length,
|
||||
CRYS_ECPKI_HASH_OpMode_t hash_mode,
|
||||
CRYS_ECPKI_DomainID_t domain);
|
||||
|
||||
/**
|
||||
* @brief Common ECC hash verification function
|
||||
*
|
||||
* @param pub_key Pointer to ECC public key
|
||||
* @param pub_key_size Size of public key
|
||||
* @param hash Hash of the message to sign
|
||||
* @param hash_length Length of the message hash
|
||||
* @param signature Buffer containing the signature to be verified
|
||||
* @param signature_length Actual length of the signature
|
||||
* @param hash_mode Mode used to hash the message of type
|
||||
* @c CRYS_ECPKI_HASH_OpMode_t
|
||||
* @param domain ECC domain of type @c CRYS_ECPKI_DomainID_t
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t cryptocell_310_common_ecc_verify_hash(const uint8_t *pub_key,
|
||||
size_t pub_key_size,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length,
|
||||
CRYS_ECPKI_HASH_OpMode_t hash_mode,
|
||||
CRYS_ECPKI_DomainID_t domain);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTOCELL_310_ECC_COMMON_H */
|
||||
/** @} */
|
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Common hash functions used by all PSA Crypto wrappers
|
||||
* for the CryptoCell 310 hash APIs.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
#ifndef PSA_CRYPTOCELL_310_HASHES_COMMON_H
|
||||
#define PSA_CRYPTOCELL_310_HASHES_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "crys_hash.h"
|
||||
|
||||
/**
|
||||
* @brief Common hash setup function
|
||||
*
|
||||
* @param ctx Driver specific hash context of type @c CRYS_HASHUserContext_t
|
||||
* @param mode Hash mode of type @c CRYS_HASH_OperationMode_t
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t cryptocell_310_common_hash_setup(CRYS_HASHUserContext_t *ctx,
|
||||
CRYS_HASH_OperationMode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Common hash update function
|
||||
*
|
||||
* @param ctx Driver specific hash context of type @c CRYS_HASHUserContext_t
|
||||
* @param input Input that is going to be hashed
|
||||
* @param input_length Length of @p input
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t cryptocell_310_common_hash_update(CRYS_HASHUserContext_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length);
|
||||
|
||||
/**
|
||||
* @brief Common hash finish function
|
||||
*
|
||||
* @param ctx Driver specific hash context of type @c CRYS_HASHUserContext_t
|
||||
* @param hash Output buffer to write the computated hash
|
||||
* @param hash_size Size of @p hash
|
||||
* @param hash_length Pointer where the actual length of the hash will be stored
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t cryptocell_310_common_hash_finish(CRYS_HASHUserContext_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTOCELL_310_HASHES_COMMON_H */
|
||||
/** @} */
|
60
pkg/driver_cryptocell_310/include/psa_error.h
Normal file
60
pkg/driver_cryptocell_310/include/psa_error.h
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Glue code translating between PSA Crypto and the CryptoCell 310 driver APIs
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
#ifndef PSA_ERROR_H
|
||||
#define PSA_ERROR_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "crys_ecpki_error.h"
|
||||
#include "crys_hash_error.h"
|
||||
#include "ssi_aes_error.h"
|
||||
|
||||
/**
|
||||
* @brief Convert CryptoCell CRYS errors to PSA status values
|
||||
*
|
||||
* @param error Error value of type @c CRYSError_t
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t CRYS_to_psa_error(CRYSError_t error);
|
||||
|
||||
/**
|
||||
* @brief Convert CryptoCell SaSi errors to PSA status values
|
||||
*
|
||||
* @param error Error value of type @c SaSiStatus
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t SaSi_to_psa_error(SaSiStatus error);
|
||||
|
||||
/**
|
||||
* @brief Function to print CryptoCell Error values in clear text.
|
||||
*
|
||||
* @param status Error value of type @c SaSiStatus or @c CRYSError_t
|
||||
* @return const char*
|
||||
*/
|
||||
const char *cryptocell310_status_to_humanly_readable(uint32_t status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_ERROR_H */
|
||||
/** @} */
|
41
pkg/driver_cryptocell_310/include/psa_periph_aes_ctx.h
Normal file
41
pkg/driver_cryptocell_310/include/psa_periph_aes_ctx.h
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief CryptoCell 310 driver specific AES contexts
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
#ifndef PSA_PERIPH_AES_CTX_H
|
||||
#define PSA_PERIPH_AES_CTX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ssi_aes.h"
|
||||
#include "kernel_defines.h"
|
||||
|
||||
#if IS_USED(MODULE_PERIPH_CIPHER_AES_128_CBC) || DOXYGEN
|
||||
/**
|
||||
* @brief Map driver specific AES context to PSA context
|
||||
*/
|
||||
typedef SaSiAesUserContext_t psa_cipher_aes_128_ctx_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_PERIPH_AES_CTX_H */
|
||||
/** @} */
|
64
pkg/driver_cryptocell_310/include/psa_periph_hashes_ctx.h
Normal file
64
pkg/driver_cryptocell_310/include/psa_periph_hashes_ctx.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief CryptoCell 310 driver specific hash contexts
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_PERIPH_HASHES_CTX_H
|
||||
#define PSA_PERIPH_HASHES_CTX_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "kernel_defines.h"
|
||||
#include "crys_hash.h"
|
||||
|
||||
#if IS_USED(MODULE_PERIPH_HASH_SHA_1) || DOXYGEN
|
||||
/**
|
||||
* @brief Map driver specific SHA1 context to PSA context
|
||||
*/
|
||||
typedef CRYS_HASHUserContext_t psa_hashes_sha1_ctx_t;
|
||||
#endif
|
||||
|
||||
#if IS_USED(MODULE_PERIPH_HASH_SHA_224) || DOXYGEN
|
||||
/**
|
||||
* @brief Map driver specific SHA224 context to PSA context
|
||||
*/
|
||||
typedef CRYS_HASHUserContext_t psa_hashes_sha224_ctx_t;
|
||||
#endif
|
||||
|
||||
#if IS_USED(MODULE_PERIPH_HASH_SHA_256) || DOXYGEN
|
||||
/**
|
||||
* @brief Map driver specific SHA256 context to PSA context
|
||||
*/
|
||||
typedef CRYS_HASHUserContext_t psa_hashes_sha256_ctx_t;
|
||||
#endif
|
||||
|
||||
#if IS_USED(MODULE_PERIPH_HASH_SHA_512) || DOXYGEN
|
||||
/**
|
||||
* @brief Map driver specific SHA512 context to PSA context
|
||||
*/
|
||||
typedef CRYS_HASHUserContext_t psa_hashes_sha512_ctx_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_PERIPH_HASHES_CTX_H */
|
||||
/** @} */
|
77
pkg/driver_cryptocell_310/psa_cryptocell_310/Kconfig
Normal file
77
pkg/driver_cryptocell_310/psa_cryptocell_310/Kconfig
Normal file
@ -0,0 +1,77 @@
|
||||
# Copyright (c) 2021 HAW Hamburg
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU Lesser
|
||||
# General Public License v2.1. See the file LICENSE in the top level
|
||||
# directory for more details.
|
||||
#
|
||||
|
||||
# Hashes
|
||||
|
||||
config MODULE_PSA_CRYPTOCELL_310_HASHES_SHA1
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_HASHES_COMMON
|
||||
|
||||
config MODULE_PSA_CRYPTOCELL_310_HASHES_SHA224
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_HASHES_COMMON
|
||||
|
||||
config MODULE_PSA_CRYPTOCELL_310_HASHES_SHA256
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_HASHES_COMMON
|
||||
|
||||
config MODULE_PSA_CRYPTOCELL_310_HASHES_SHA512
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_HASHES_COMMON
|
||||
|
||||
# MAC
|
||||
|
||||
config MODULE_PSA_CRYPTOCELL_310_HMAC
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_CRYPTOCELL_310
|
||||
|
||||
# AES
|
||||
|
||||
config MODULE_PSA_CRYPTOCELL_310_AES_CBC
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_AES_COMMON
|
||||
|
||||
# ECC
|
||||
|
||||
config MODULE_PSA_CRYPTOCELL_310_ECC_P192
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_ECC_COMMON
|
||||
|
||||
config MODULE_PSA_CRYPTOCELL_310_ECC_P256
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_CRYPTOCELL_310
|
||||
select MODULE_PSA_CRYPTOCELL_310_ECC_COMMON
|
||||
|
||||
config MODULE_PSA_CRYPTOCELL_310
|
||||
bool "PSA CryptoCell Wrapper"
|
||||
select MODULE_PSA_CRYPTOCELL_310_ERROR_CONVERSION
|
||||
|
||||
config MODULE_PSA_CRYPTOCELL_310_HASHES_COMMON
|
||||
bool
|
||||
|
||||
config MODULE_PSA_CRYPTOCELL_310_ECC_COMMON
|
||||
bool
|
||||
|
||||
config MODULE_PSA_CRYPTOCELL_310_AES_COMMON
|
||||
bool
|
||||
|
||||
config MODULE_PSA_CRYPTOCELL_310_ERROR_CONVERSION
|
||||
bool
|
4
pkg/driver_cryptocell_310/psa_cryptocell_310/Makefile
Normal file
4
pkg/driver_cryptocell_310/psa_cryptocell_310/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
BASE_MODULE := psa_cryptocell_310
|
||||
SUBMODULES := 1
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
30
pkg/driver_cryptocell_310/psa_cryptocell_310/Makefile.dep
Normal file
30
pkg/driver_cryptocell_310/psa_cryptocell_310/Makefile.dep
Normal file
@ -0,0 +1,30 @@
|
||||
USEMODULE += psa_cryptocell_310
|
||||
USEMODULE += psa_cryptocell_310_error_conversion
|
||||
|
||||
ifneq (,$(filter psa_cryptocell_310_hashes_sha1,$(USEMODULE)))
|
||||
USEMODULE += psa_cryptocell_310_hashes_common
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_cryptocell_310_hashes_sha224,$(USEMODULE)))
|
||||
USEMODULE += psa_cryptocell_310_hashes_common
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_cryptocell_310_hashes_sha256,$(USEMODULE)))
|
||||
USEMODULE += psa_cryptocell_310_hashes_common
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_cryptocell_310_hashes_sha512,$(USEMODULE)))
|
||||
USEMODULE += psa_cryptocell_310_hashes_common
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_cryptocell_310_aes_cbc,$(USEMODULE)))
|
||||
USEMODULE += psa_cryptocell_310_aes_common
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_cryptocell_310_ecc_p192,$(USEMODULE)))
|
||||
USEMODULE += psa_cryptocell_310_ecc_common
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_cryptocell_310_ecc_p256,$(USEMODULE)))
|
||||
USEMODULE += psa_cryptocell_310_ecc_common
|
||||
endif
|
131
pkg/driver_cryptocell_310/psa_cryptocell_310/aes_cbc.c
Normal file
131
pkg/driver_cryptocell_310/psa_cryptocell_310/aes_cbc.c
Normal file
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the CryptoCell 310 AES 128 CBC APIs
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa_error.h"
|
||||
#include "psa_cryptocell_310_aes_common.h"
|
||||
#include "ssi_aes.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
psa_status_t psa_cipher_cbc_aes_128_encrypt(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
if ((alg != PSA_ALG_CBC_PKCS7) && (alg != PSA_ALG_CBC_NO_PADDING)) {
|
||||
DEBUG("%s : Invalid CBC padding type\n", __FILE__);
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (key_buffer_size < PSA_BITS_TO_BYTES(attributes->bits)) {
|
||||
DEBUG("%s : Key buffer too small\n", __FILE__);
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t iv_length = 0;
|
||||
size_t key_size = PSA_BITS_TO_BYTES(attributes->bits);
|
||||
|
||||
psa_cipher_operation_t operation = psa_cipher_operation_init();
|
||||
operation.iv_required = 1;
|
||||
operation.default_iv_length = PSA_CIPHER_IV_LENGTH(attributes->type, alg);
|
||||
|
||||
SaSiAesPaddingType_t padding =
|
||||
(alg == PSA_ALG_CBC_PKCS7) ? SASI_AES_PADDING_PKCS7 : SASI_AES_PADDING_NONE;
|
||||
|
||||
status = psa_cipher_generate_iv(&operation, output, operation.default_iv_length, &iv_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = cryptocell_310_common_aes_setup((SaSiAesUserContext_t *)&operation.backend_ctx.cipher_ctx.aes_128,
|
||||
SASI_AES_ENCRYPT, SASI_AES_MODE_CBC, padding, output, key_buffer,
|
||||
key_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = cryptocell_310_common_aes_encrypt_decrypt(
|
||||
(SaSiAesUserContext_t *)&operation.backend_ctx.cipher_ctx.aes_128,
|
||||
input, input_length, output + iv_length, output_size - iv_length,
|
||||
output_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
*output_length = output_size;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_cipher_cbc_aes_128_decrypt(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
if ((alg != PSA_ALG_CBC_PKCS7) && (alg != PSA_ALG_CBC_NO_PADDING)) {
|
||||
DEBUG("%s : Invalid CBC padding type\n", __FILE__);
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (key_buffer_size < PSA_BITS_TO_BYTES(attributes->bits)) {
|
||||
DEBUG("%s : Key buffer too small\n", __FILE__);
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
size_t key_size = PSA_BITS_TO_BYTES(attributes->bits);
|
||||
|
||||
psa_cipher_operation_t operation = psa_cipher_operation_init();
|
||||
operation.iv_required = 1;
|
||||
operation.default_iv_length = PSA_CIPHER_IV_LENGTH(attributes->type, alg);
|
||||
|
||||
SaSiAesPaddingType_t padding =
|
||||
(alg == PSA_ALG_CBC_PKCS7) ? SASI_AES_PADDING_PKCS7 : SASI_AES_PADDING_NONE;
|
||||
|
||||
status = cryptocell_310_common_aes_setup((SaSiAesUserContext_t *)&operation.backend_ctx.cipher_ctx.aes_128,
|
||||
SASI_AES_DECRYPT, SASI_AES_MODE_CBC, padding, input, key_buffer,
|
||||
key_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
status = cryptocell_310_common_aes_encrypt_decrypt(
|
||||
(SaSiAesUserContext_t *)&operation.backend_ctx.cipher_ctx.aes_128,
|
||||
input + operation.default_iv_length, input_length - operation.
|
||||
default_iv_length, output, output_size, output_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
*output_length = PSA_CIPHER_DECRYPT_OUTPUT_SIZE(attributes->type, alg, input_length);
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
112
pkg/driver_cryptocell_310/psa_cryptocell_310/aes_common.c
Normal file
112
pkg/driver_cryptocell_310/psa_cryptocell_310/aes_common.c
Normal file
@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @brief Common AES functions used by all PSA Crypto wrappers
|
||||
* for the CryptoCell 310 AES APIs.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "vendor/nrf52840.h"
|
||||
#include "ssi_aes.h"
|
||||
#include "sns_silib.h"
|
||||
#include "psa_error.h"
|
||||
#include "cryptocell_310_util.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define CC310_MAX_AES_INPUT_BLOCK (0xFFF0)
|
||||
|
||||
psa_status_t cryptocell_310_common_aes_setup(SaSiAesUserContext_t *ctx,
|
||||
SaSiAesEncryptMode_t direction,
|
||||
SaSiAesOperationMode_t mode,
|
||||
SaSiAesPaddingType_t padding,
|
||||
const uint8_t *iv,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_size)
|
||||
{
|
||||
SaSiAesUserKeyData_t key;
|
||||
|
||||
SaSiStatus ret = SaSi_AesInit(ctx, direction, mode, padding);
|
||||
if (ret != SASI_OK) {
|
||||
DEBUG("SaSi_AesInit failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return SaSi_to_psa_error(ret);
|
||||
}
|
||||
|
||||
key.keySize = key_size;
|
||||
key.pKey = (uint8_t *)key_buffer;
|
||||
|
||||
ret = SaSi_AesSetKey(ctx, SASI_AES_USER_KEY, &key, sizeof(key));
|
||||
if (ret != SASI_OK) {
|
||||
DEBUG("SaSi_AesSetKey failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return SaSi_to_psa_error(ret);
|
||||
}
|
||||
|
||||
ret = SaSi_AesSetIv(ctx, (uint8_t *)iv);
|
||||
if (ret != SASI_OK) {
|
||||
DEBUG("SaSi_AesSetIv failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return SaSi_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t cryptocell_310_common_aes_encrypt_decrypt(SaSiAesUserContext_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
SaSiStatus ret = 0;
|
||||
size_t offset = 0;
|
||||
size_t size;
|
||||
size_t length = input_length;
|
||||
*output_length = output_size;
|
||||
|
||||
do {
|
||||
if (length > CC310_MAX_AES_INPUT_BLOCK) {
|
||||
size = CC310_MAX_AES_INPUT_BLOCK;
|
||||
length -= CC310_MAX_AES_INPUT_BLOCK;
|
||||
}
|
||||
else {
|
||||
size = length;
|
||||
length = 0;
|
||||
}
|
||||
|
||||
cryptocell_310_enable();
|
||||
ret = SaSi_AesBlock(ctx, (uint8_t *)(input + offset), size, output + offset);
|
||||
cryptocell_310_disable();
|
||||
if (ret != SASI_OK) {
|
||||
DEBUG("SaSi_AesBlock failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return SaSi_to_psa_error(ret);
|
||||
}
|
||||
|
||||
offset += size;
|
||||
} while ((length > 0) && (ret == SASI_OK));
|
||||
|
||||
cryptocell_310_enable();
|
||||
ret = SaSi_AesFinish(ctx, length, (uint8_t *)(input + offset), input_length, output,
|
||||
output_length);
|
||||
cryptocell_310_disable();
|
||||
|
||||
if (ret != SASI_OK) {
|
||||
DEBUG("SaSi_AesFinish failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return SaSi_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
143
pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c
Normal file
143
pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_common.c
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @brief Common ECC functions used by all PSA Crypto wrappers
|
||||
* for the CryptoCell 310 ECC APIs.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa_error.h"
|
||||
#include "psa_cryptocell_310_ecc_common.h"
|
||||
#include "cryptocell_310_util.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
extern CRYS_RND_State_t *rndState_ptr;
|
||||
|
||||
CRYS_ECPKI_Domain_t *pDomain;
|
||||
SaSiRndGenerateVectWorkFunc_t rndGenerateVectFunc;
|
||||
|
||||
psa_status_t cryptocell_310_common_ecc_generate_key_pair(uint8_t *priv_key_buffer,
|
||||
uint8_t *pub_key_buffer,
|
||||
uint32_t *priv_key_buffer_length,
|
||||
uint32_t *pub_key_buffer_length,
|
||||
CRYS_ECPKI_DomainID_t domain)
|
||||
{
|
||||
CRYS_ECPKI_UserPrivKey_t priv_key;
|
||||
CRYS_ECPKI_UserPublKey_t pub_key;
|
||||
CRYS_ECPKI_KG_FipsContext_t FipsBuff;
|
||||
CRYS_ECPKI_KG_TempData_t TempECCKGBuff;
|
||||
CRYSError_t ret;
|
||||
|
||||
rndGenerateVectFunc = CRYS_RND_GenerateVector;
|
||||
pDomain = (CRYS_ECPKI_Domain_t *)CRYS_ECPKI_GetEcDomain(domain);
|
||||
|
||||
cryptocell_310_enable();
|
||||
ret = CRYS_ECPKI_GenKeyPair(rndState_ptr, rndGenerateVectFunc, pDomain, &priv_key, &pub_key,
|
||||
&TempECCKGBuff, &FipsBuff);
|
||||
cryptocell_310_disable();
|
||||
if (ret != CRYS_OK) {
|
||||
DEBUG("CRYS_ECPKI_GenKeyPair failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return CRYS_to_psa_error(ret);
|
||||
}
|
||||
|
||||
ret = CRYS_ECPKI_ExportPrivKey(&priv_key, priv_key_buffer, priv_key_buffer_length);
|
||||
if (ret != CRYS_OK) {
|
||||
DEBUG("CRYS_ECPKI_ExportPrivKey failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return CRYS_to_psa_error(ret);
|
||||
}
|
||||
|
||||
ret = CRYS_ECPKI_ExportPublKey(&pub_key, CRYS_EC_PointUncompressed, pub_key_buffer,
|
||||
pub_key_buffer_length);
|
||||
if (ret != CRYS_OK) {
|
||||
DEBUG("CRYS_ECPKI_ExportPubKey failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return CRYS_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t cryptocell_310_common_ecc_sign_hash(const uint8_t *priv_key,
|
||||
uint32_t priv_key_size,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
uint8_t *signature,
|
||||
size_t *signature_length,
|
||||
CRYS_ECPKI_HASH_OpMode_t hash_mode,
|
||||
CRYS_ECPKI_DomainID_t domain)
|
||||
{
|
||||
CRYS_ECDSA_SignUserContext_t SignUserContext;
|
||||
CRYS_ECPKI_UserPrivKey_t user_priv_key;
|
||||
CRYSError_t ret = 0;
|
||||
|
||||
rndGenerateVectFunc = CRYS_RND_GenerateVector;
|
||||
pDomain = (CRYS_ECPKI_Domain_t *)CRYS_ECPKI_GetEcDomain(domain);
|
||||
|
||||
ret = CRYS_ECPKI_BuildPrivKey(pDomain, priv_key, priv_key_size, &user_priv_key);
|
||||
if (ret != CRYS_OK) {
|
||||
DEBUG("CRYS_ECPKI_BuildPrivKey failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return CRYS_to_psa_error(ret);
|
||||
}
|
||||
|
||||
cryptocell_310_enable();
|
||||
ret = CRYS_ECDSA_Sign(rndState_ptr, rndGenerateVectFunc,
|
||||
&SignUserContext, &user_priv_key, hash_mode, (uint8_t *)hash, hash_length,
|
||||
signature, (uint32_t *)signature_length);
|
||||
cryptocell_310_disable();
|
||||
if (ret != CRYS_OK) {
|
||||
DEBUG("CRYS_ECDSA_Sign failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return CRYS_to_psa_error(ret);
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t cryptocell_310_common_ecc_verify_hash(const uint8_t *pub_key,
|
||||
size_t pub_key_size,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length,
|
||||
CRYS_ECPKI_HASH_OpMode_t hash_mode,
|
||||
CRYS_ECPKI_DomainID_t domain)
|
||||
{
|
||||
CRYS_ECDSA_VerifyUserContext_t VerifyUserContext;
|
||||
CRYS_ECPKI_UserPublKey_t user_pub_key;
|
||||
CRYSError_t ret = 0;
|
||||
|
||||
pDomain = (CRYS_ECPKI_Domain_t *)CRYS_ECPKI_GetEcDomain(domain);
|
||||
|
||||
/**
|
||||
* For more security, use CRYS_ECPKI_BuildPublKeyPartlyCheck or
|
||||
* CRYS_ECPKI_BuildPublKeyFullCheck -> Those take longer and use more memory space
|
||||
* */
|
||||
ret = CRYS_ECPKI_BuildPublKey(pDomain, (uint8_t *)pub_key, pub_key_size, &user_pub_key);
|
||||
if (ret != CRYS_OK) {
|
||||
DEBUG("CRYS_ECPKI_BuildPublKey failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return CRYS_to_psa_error(ret);
|
||||
}
|
||||
|
||||
cryptocell_310_enable();
|
||||
ret = CRYS_ECDSA_Verify(&VerifyUserContext, &user_pub_key, hash_mode, (uint8_t *)signature,
|
||||
signature_length, (uint8_t *)hash, hash_length);
|
||||
cryptocell_310_disable();
|
||||
|
||||
if (ret != CRYS_OK) {
|
||||
DEBUG("CRYS_ECDSA_Verify failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return CRYS_to_psa_error(ret);
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
76
pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p192.c
Normal file
76
pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p192.c
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Glue code translating between PSA Crypto and the CryptoCell 310 ECC P192 APIs
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa_cryptocell_310_ecc_common.h"
|
||||
|
||||
psa_status_t psa_generate_ecc_p192r1_key_pair(const psa_key_attributes_t *attributes,
|
||||
uint8_t *priv_key_buffer,
|
||||
uint8_t *pub_key_buffer,
|
||||
size_t *priv_key_buffer_length,
|
||||
size_t *pub_key_buffer_length)
|
||||
{
|
||||
*priv_key_buffer_length = PSA_BITS_TO_BYTES(attributes->bits);
|
||||
*pub_key_buffer_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(attributes->type, attributes->bits);
|
||||
|
||||
return cryptocell_310_common_ecc_generate_key_pair(priv_key_buffer, pub_key_buffer,
|
||||
(uint32_t *)priv_key_buffer_length,
|
||||
(uint32_t *)pub_key_buffer_length,
|
||||
CRYS_ECPKI_DomainID_secp192r1);
|
||||
}
|
||||
|
||||
psa_status_t psa_ecc_p192r1_sign_hash( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
uint8_t *signature,
|
||||
size_t signature_size,
|
||||
size_t *signature_length)
|
||||
{
|
||||
CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH(PSA_ALG_GET_HASH(alg));
|
||||
|
||||
(void)signature_size;
|
||||
(void)key_buffer_size;
|
||||
|
||||
return cryptocell_310_common_ecc_sign_hash(key_buffer,
|
||||
PSA_BITS_TO_BYTES(attributes->bits),
|
||||
hash, hash_length, signature,
|
||||
signature_length, hash_mode,
|
||||
CRYS_ECPKI_DomainID_secp192r1);
|
||||
}
|
||||
|
||||
psa_status_t psa_ecc_p192r1_verify_hash(const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length)
|
||||
{
|
||||
CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH(PSA_ALG_GET_HASH(alg));
|
||||
|
||||
(void)attributes;
|
||||
return cryptocell_310_common_ecc_verify_hash(key_buffer, key_buffer_size,
|
||||
hash, hash_length, signature,
|
||||
signature_length, hash_mode,
|
||||
CRYS_ECPKI_DomainID_secp192r1);
|
||||
}
|
74
pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p256.c
Normal file
74
pkg/driver_cryptocell_310/psa_cryptocell_310/ecc_p256.c
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Glue code translating between PSA Crypto and the CryptoCell 310 ECC P256 APIs
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa_cryptocell_310_ecc_common.h"
|
||||
|
||||
psa_status_t psa_generate_ecc_p256r1_key_pair( const psa_key_attributes_t *attributes,
|
||||
uint8_t *priv_key_buffer,
|
||||
uint8_t *pub_key_buffer,
|
||||
size_t *priv_key_buffer_length,
|
||||
size_t *pub_key_buffer_length)
|
||||
{
|
||||
*priv_key_buffer_length = PSA_BITS_TO_BYTES(attributes->bits);
|
||||
*pub_key_buffer_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(attributes->type, attributes->bits);
|
||||
|
||||
return cryptocell_310_common_ecc_generate_key_pair(priv_key_buffer, pub_key_buffer,
|
||||
(uint32_t *)priv_key_buffer_length,
|
||||
(uint32_t *)pub_key_buffer_length,
|
||||
CRYS_ECPKI_DomainID_secp256r1);
|
||||
}
|
||||
|
||||
psa_status_t psa_ecc_p256r1_sign_hash( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
uint8_t *signature,
|
||||
size_t signature_size,
|
||||
size_t *signature_length)
|
||||
{
|
||||
(void)key_buffer_size;
|
||||
CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH(PSA_ALG_GET_HASH(alg));
|
||||
*signature_length = signature_size;
|
||||
return cryptocell_310_common_ecc_sign_hash(key_buffer,
|
||||
PSA_BITS_TO_BYTES(attributes->bits),
|
||||
hash, hash_length, signature,
|
||||
signature_length, hash_mode,
|
||||
CRYS_ECPKI_DomainID_secp256r1);
|
||||
}
|
||||
|
||||
psa_status_t psa_ecc_p256r1_verify_hash(const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length)
|
||||
{
|
||||
CRYS_ECPKI_HASH_OpMode_t hash_mode = MAP_PSA_HASH_TO_CRYS_HASH(PSA_ALG_GET_HASH(alg));
|
||||
|
||||
(void)attributes;
|
||||
return cryptocell_310_common_ecc_verify_hash(key_buffer, key_buffer_size,
|
||||
hash, hash_length, signature,
|
||||
signature_length, hash_mode,
|
||||
CRYS_ECPKI_DomainID_secp256r1);
|
||||
}
|
413
pkg/driver_cryptocell_310/psa_cryptocell_310/error_conversion.c
Normal file
413
pkg/driver_cryptocell_310/psa_cryptocell_310/error_conversion.c
Normal file
@ -0,0 +1,413 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Glue code translating between PSA Crypto and the CryptoCell 310 driver APIs
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa_error.h"
|
||||
|
||||
psa_status_t CRYS_to_psa_error(CRYSError_t error)
|
||||
{
|
||||
switch (error) {
|
||||
case CRYS_HASH_ILLEGAL_OPERATION_MODE_ERROR:
|
||||
case CRYS_HASH_IS_NOT_SUPPORTED:
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
case CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR:
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
case CRYS_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR:
|
||||
case CRYS_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR:
|
||||
case CRYS_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR:
|
||||
case CRYS_ECDSA_VERIFY_SIGNER_PUBL_KEY_VALIDATION_TAG_ERROR:
|
||||
case CRYS_ECDSA_VERIFY_INVALID_SIGNATURE_IN_PTR_ERROR:
|
||||
case CRYS_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_PTR_ERROR:
|
||||
case CRYS_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_SIZE_ERROR:
|
||||
case CRYS_ECDSA_VERIFY_INVALID_DOMAIN_ID_ERROR:
|
||||
case CRYS_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR:
|
||||
case CRYS_ECDSA_VERIFY_INVALID_SIGNER_PUBL_KEY_PTR_ERROR:
|
||||
case CRYS_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR:
|
||||
case CRYS_HASH_DATA_IN_POINTER_INVALID_ERROR:
|
||||
case CRYS_ECDSA_VERIFY_INVALID_SIGNATURE_SIZE_ERROR:
|
||||
case CRYS_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_PTR_ERROR:
|
||||
case CRYS_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR:
|
||||
case CRYS_ECDSA_SIGN_INVALID_EPHEMERAL_KEY_PTR_ERROR:
|
||||
case CRYS_ECDSA_SIGN_INVALID_RND_CONTEXT_PTR_ERROR:
|
||||
case CRYS_ECDSA_SIGN_INVALID_RND_FUNCTION_PTR_ERROR:
|
||||
case CRYS_ECDSA_SIGN_INVALID_DOMAIN_ID_ERROR:
|
||||
case CRYS_ECDSA_SIGN_INVALID_USER_CONTEXT_PTR_ERROR:
|
||||
case CRYS_ECDSA_SIGN_INVALID_USER_PRIV_KEY_PTR_ERROR:
|
||||
case CRYS_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR:
|
||||
case CRYS_ECDSA_SIGN_INVALID_SIGNATURE_OUT_PTR_ERROR:
|
||||
case CRYS_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_PTR_ERROR:
|
||||
case CRYS_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_ERROR:
|
||||
case CRYS_ECC_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR:
|
||||
case CRYS_ECC_ILLEGAL_HASH_MODE_ERROR:
|
||||
case CRYS_ECPKI_ILLEGAL_DOMAIN_ID_ERROR:
|
||||
case CRYS_ECPKI_DOMAIN_PTR_ERROR:
|
||||
case CRYS_ECPKI_RND_CONTEXT_PTR_ERROR:
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_COMPRESSION_MODE_ERROR:
|
||||
case CRYS_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR:
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_IN_PTR_ERROR:
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR:
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_SIZE_ERROR:
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_DATA_ERROR:
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_IN_PTR_ERROR:
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR:
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_SIZE_ERROR:
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR:
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_CHECK_MODE_ERROR:
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_TEMP_BUFF_PTR_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_COMPRESSION_MODE_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_EXTERN_PUBL_KEY_PTR_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_PTR_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_DOMAIN_ID_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_VALIDATION_TAG_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_DATA_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_EXTERN_PRIV_KEY_PTR_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PRIV_KEY_ILLEGAL_VALIDATION_TAG_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_PRIV_KEY_SIZE_PTR_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_PRIV_KEY_SIZE_ERROR:
|
||||
case CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_PRIV_KEY_DATA_ERROR:
|
||||
case CRYS_ECPKI_BUILD_DOMAIN_ID_IS_NOT_VALID_ERROR:
|
||||
case CRYS_ECPKI_BUILD_DOMAIN_DOMAIN_PTR_ERROR:
|
||||
case CRYS_ECPKI_BUILD_DOMAIN_EC_PARAMETR_PTR_ERROR:
|
||||
case CRYS_ECPKI_BUILD_DOMAIN_EC_PARAMETR_SIZE_ERROR:
|
||||
case CRYS_ECPKI_BUILD_DOMAIN_COFACTOR_PARAMS_ERROR:
|
||||
case CRYS_ECPKI_BUILD_DOMAIN_SECURITY_STRENGTH_ERROR:
|
||||
case CRYS_ECPKI_BUILD_SCA_RESIST_ILLEGAL_MODE_ERROR:
|
||||
case CRYS_ECDH_SVDP_DH_INVALID_PARTNER_PUBL_KEY_PTR_ERROR:
|
||||
case CRYS_ECDH_SVDP_DH_PARTNER_PUBL_KEY_VALID_TAG_ERROR:
|
||||
case CRYS_ECDH_SVDP_DH_INVALID_USER_PRIV_KEY_PTR_ERROR:
|
||||
case CRYS_ECDH_SVDP_DH_USER_PRIV_KEY_VALID_TAG_ERROR:
|
||||
case CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_PTR_ERROR:
|
||||
case CRYS_ECDH_SVDP_DH_INVALID_TEMP_DATA_PTR_ERROR:
|
||||
case CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_PTR_ERROR:
|
||||
case CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR:
|
||||
case CRYS_ECDH_SVDP_DH_ILLEGAL_DOMAIN_ID_ERROR:
|
||||
case CRYS_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR:
|
||||
case CRYS_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR:
|
||||
case CRYS_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR:
|
||||
case CRYS_ECPKI_INVALID_RND_FUNC_PTR_ERROR:
|
||||
case CRYS_ECPKI_INVALID_RND_CTX_PTR_ERROR:
|
||||
case CRYS_ECPKI_INVALID_DOMAIN_ID_ERROR:
|
||||
case CRYS_ECPKI_INVALID_PRIV_KEY_TAG_ERROR:
|
||||
case CRYS_ECPKI_INVALID_PUBL_KEY_TAG_ERROR:
|
||||
case CRYS_ECPKI_INVALID_DATA_IN_PASSED_STRUCT_ERROR:
|
||||
case CRYS_HASH_DATA_SIZE_ILLEGAL:
|
||||
case CRYS_HASH_INVALID_RESULT_BUFFER_POINTER_ERROR:
|
||||
case CRYS_HASH_ILLEGAL_PARAMS_ERROR:
|
||||
case CRYS_HASH_INVALID_USER_CONTEXT_POINTER_ERROR:
|
||||
case CRYS_HASH_LAST_BLOCK_ALREADY_PROCESSED_ERROR:
|
||||
case CRYS_HASH_CTX_SIZES_ERROR:
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
default:
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t SaSi_to_psa_error(SaSiStatus error)
|
||||
{
|
||||
switch (error) {
|
||||
case SASI_AES_INVALID_USER_CONTEXT_POINTER_ERROR:
|
||||
case SASI_AES_INVALID_IV_OR_TWEAK_PTR_ERROR:
|
||||
case SASI_AES_ILLEGAL_OPERATION_MODE_ERROR:
|
||||
case SASI_AES_ILLEGAL_KEY_SIZE_ERROR:
|
||||
case SASI_AES_INVALID_KEY_POINTER_ERROR:
|
||||
case SASI_AES_INVALID_ENCRYPT_MODE_ERROR:
|
||||
case SASI_AES_DATA_IN_POINTER_INVALID_ERROR:
|
||||
case SASI_AES_DATA_OUT_POINTER_INVALID_ERROR:
|
||||
case SASI_AES_DATA_IN_SIZE_ILLEGAL:
|
||||
case SASI_AES_DATA_OUT_DATA_IN_OVERLAP_ERROR:
|
||||
case SASI_AES_DATA_OUT_SIZE_POINTER_INVALID_ERROR:
|
||||
case SASI_AES_CTX_SIZES_ERROR:
|
||||
case SASI_AES_ILLEGAL_PARAMS_ERROR:
|
||||
case SASI_AES_CTR_ILLEGAL_BLOCK_OFFSET_ERROR:
|
||||
case SASI_AES_CTR_ILLEGAL_COUNTER_ERROR:
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
case SASI_AES_DATA_IN_BUFFER_SIZE_ERROR:
|
||||
case SASI_AES_DATA_OUT_BUFFER_SIZE_ERROR:
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
case SASI_AES_ILLEGAL_PADDING_TYPE_ERROR:
|
||||
case SASI_AES_INCORRECT_PADDING_ERROR:
|
||||
return PSA_ERROR_INVALID_PADDING;
|
||||
case SASI_AES_CORRUPTED_OUTPUT_ERROR:
|
||||
case SASI_AES_USER_CONTEXT_CORRUPTED_ERROR:
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
case SASI_AES_DECRYPTION_NOT_ALLOWED_ON_THIS_MODE:
|
||||
case SASI_AES_ADDITIONAL_BLOCK_NOT_PERMITTED_ERROR:
|
||||
return PSA_ERROR_NOT_PERMITTED;
|
||||
case SASI_AES_KEY_TYPE_NOT_SUPPORTED_ERROR:
|
||||
case SASI_AES_IS_NOT_SUPPORTED:
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
case SASI_OUT_OF_RESOURCE_ERROR:
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
default:
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
const char *cryptocell310_status_to_humanly_readable(uint32_t status)
|
||||
{
|
||||
switch(status) {
|
||||
case CRYS_ECDH_SVDP_DH_NOT_CONCENT_PUBL_AND_PRIV_DOMAIN_ID_ERROR:
|
||||
return "CRYS_ECDH_SVDP_DH_NOT_CONCENT_PUBL_AND_PRIV_DOMAIN_ID_ERROR";
|
||||
case CRYS_ECDSA_SIGN_INVALID_IS_EPHEMER_KEY_INTERNAL_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_INVALID_IS_EPHEMER_KEY_INTERNAL_ERROR";
|
||||
case CRYS_ECDSA_SIGN_SIGNING_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_SIGNING_ERROR";
|
||||
case CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR:
|
||||
return "CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR";
|
||||
case CRYS_ECPKI_PKI_INTERNAL_ERROR:
|
||||
return "CRYS_ECPKI_PKI_INTERNAL_ERROR";
|
||||
case CRYS_HASH_ILLEGAL_OPERATION_MODE_ERROR:
|
||||
return "CRYS_HASH_ILLEGAL_OPERATION_MODE_ERROR";
|
||||
case CRYS_HASH_IS_NOT_SUPPORTED:
|
||||
return "CRYS_HASH_IS_NOT_SUPPORTED";
|
||||
case CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR:
|
||||
return "CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR";
|
||||
case CRYS_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_USER_CONTEXT_VALIDATION_TAG_ERROR";
|
||||
case CRYS_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_USER_PRIV_KEY_VALIDATION_TAG_ERROR";
|
||||
case CRYS_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR:
|
||||
return "CRYS_ECDSA_VERIFY_USER_CONTEXT_VALIDATION_TAG_ERROR";
|
||||
case CRYS_ECDSA_VERIFY_SIGNER_PUBL_KEY_VALIDATION_TAG_ERROR:
|
||||
return "CRYS_ECDSA_VERIFY_SIGNER_PUBL_KEY_VALIDATION_TAG_ERROR";
|
||||
case CRYS_ECDSA_VERIFY_INVALID_SIGNATURE_IN_PTR_ERROR:
|
||||
return "CRYS_ECDSA_VERIFY_INVALID_SIGNATURE_IN_PTR_ERROR";
|
||||
case CRYS_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_PTR_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_PTR_ERROR";
|
||||
case CRYS_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_SIZE_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_INVALID_MESSAGE_DATA_IN_SIZE_ERROR";
|
||||
case CRYS_ECDSA_VERIFY_INVALID_DOMAIN_ID_ERROR:
|
||||
return "CRYS_ECDSA_VERIFY_INVALID_DOMAIN_ID_ERROR";
|
||||
case CRYS_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR:
|
||||
return "CRYS_ECDSA_VERIFY_INVALID_USER_CONTEXT_PTR_ERROR";
|
||||
case CRYS_ECDSA_VERIFY_INVALID_SIGNER_PUBL_KEY_PTR_ERROR:
|
||||
return "CRYS_ECDSA_VERIFY_INVALID_SIGNER_PUBL_KEY_PTR_ERROR";
|
||||
case CRYS_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR:
|
||||
return "CRYS_ECDSA_VERIFY_ILLEGAL_HASH_OP_MODE_ERROR";
|
||||
case CRYS_HASH_DATA_IN_POINTER_INVALID_ERROR:
|
||||
return "CRYS_HASH_DATA_IN_POINTER_INVALID_ERROR";
|
||||
case CRYS_ECDSA_VERIFY_INVALID_SIGNATURE_SIZE_ERROR:
|
||||
return "CRYS_ECDSA_VERIFY_INVALID_SIGNATURE_SIZE_ERROR";
|
||||
case CRYS_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_PTR_ERROR:
|
||||
return "CRYS_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_PTR_ERROR";
|
||||
case CRYS_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR:
|
||||
return "CRYS_ECDSA_VERIFY_INVALID_MESSAGE_DATA_IN_SIZE_ERROR";
|
||||
case CRYS_ECDSA_SIGN_INVALID_EPHEMERAL_KEY_PTR_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_INVALID_EPHEMERAL_KEY_PTR_ERROR";
|
||||
case CRYS_ECDSA_SIGN_INVALID_RND_CONTEXT_PTR_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_INVALID_RND_CONTEXT_PTR_ERROR";
|
||||
case CRYS_ECDSA_SIGN_INVALID_RND_FUNCTION_PTR_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_INVALID_RND_FUNCTION_PTR_ERROR";
|
||||
case CRYS_ECDSA_SIGN_INVALID_DOMAIN_ID_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_INVALID_DOMAIN_ID_ERROR";
|
||||
case CRYS_ECDSA_SIGN_INVALID_USER_CONTEXT_PTR_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_INVALID_USER_CONTEXT_PTR_ERROR";
|
||||
case CRYS_ECDSA_SIGN_INVALID_USER_PRIV_KEY_PTR_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_INVALID_USER_PRIV_KEY_PTR_ERROR";
|
||||
case CRYS_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_ILLEGAL_HASH_OP_MODE_ERROR";
|
||||
case CRYS_ECDSA_SIGN_INVALID_SIGNATURE_OUT_PTR_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_INVALID_SIGNATURE_OUT_PTR_ERROR";
|
||||
case CRYS_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_PTR_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_PTR_ERROR";
|
||||
case CRYS_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_ERROR:
|
||||
return "CRYS_ECDSA_SIGN_INVALID_SIGNATURE_OUT_SIZE_ERROR";
|
||||
case CRYS_ECC_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR:
|
||||
return "CRYS_ECC_ILLEGAL_PARAMS_ACCORDING_TO_PRIV_ERROR";
|
||||
case CRYS_ECC_ILLEGAL_HASH_MODE_ERROR:
|
||||
return "CRYS_ECC_ILLEGAL_HASH_MODE_ERROR";
|
||||
case CRYS_ECPKI_ILLEGAL_DOMAIN_ID_ERROR:
|
||||
return "CRYS_ECPKI_ILLEGAL_DOMAIN_ID_ERROR";
|
||||
case CRYS_ECPKI_DOMAIN_PTR_ERROR:
|
||||
return "CRYS_ECPKI_DOMAIN_PTR_ERROR";
|
||||
case CRYS_ECPKI_RND_CONTEXT_PTR_ERROR:
|
||||
return "CRYS_ECPKI_RND_CONTEXT_PTR_ERROR";
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_COMPRESSION_MODE_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_KEY_INVALID_COMPRESSION_MODE_ERROR";
|
||||
case CRYS_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_KEY_ILLEGAL_DOMAIN_ID_ERROR";
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_IN_PTR_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_IN_PTR_ERROR";
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR";
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_SIZE_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_SIZE_ERROR";
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_DATA_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_KEY_INVALID_PRIV_KEY_DATA_ERROR";
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_IN_PTR_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_IN_PTR_ERROR";
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR";
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_SIZE_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_SIZE_ERROR";
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_KEY_INVALID_PUBL_KEY_DATA_ERROR";
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_CHECK_MODE_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_KEY_INVALID_CHECK_MODE_ERROR";
|
||||
case CRYS_ECPKI_BUILD_KEY_INVALID_TEMP_BUFF_PTR_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_KEY_INVALID_TEMP_BUFF_PTR_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_USER_PUBL_KEY_PTR_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_COMPRESSION_MODE_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_COMPRESSION_MODE_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_EXTERN_PUBL_KEY_PTR_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_EXTERN_PUBL_KEY_PTR_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_PTR_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_PTR_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_SIZE_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_DOMAIN_ID_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_DOMAIN_ID_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_VALIDATION_TAG_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PUBL_KEY_ILLEGAL_VALIDATION_TAG_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_DATA_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PUBL_KEY_INVALID_PUBL_KEY_DATA_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_USER_PRIV_KEY_PTR_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_EXTERN_PRIV_KEY_PTR_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_EXTERN_PRIV_KEY_PTR_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PRIV_KEY_ILLEGAL_VALIDATION_TAG_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PRIV_KEY_ILLEGAL_VALIDATION_TAG_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_PRIV_KEY_SIZE_PTR_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_PRIV_KEY_SIZE_PTR_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_PRIV_KEY_SIZE_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_PRIV_KEY_SIZE_ERROR";
|
||||
case CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_PRIV_KEY_DATA_ERROR:
|
||||
return "CRYS_ECPKI_EXPORT_PRIV_KEY_INVALID_PRIV_KEY_DATA_ERROR";
|
||||
case CRYS_ECPKI_BUILD_DOMAIN_ID_IS_NOT_VALID_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_DOMAIN_ID_IS_NOT_VALID_ERROR";
|
||||
case CRYS_ECPKI_BUILD_DOMAIN_DOMAIN_PTR_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_DOMAIN_DOMAIN_PTR_ERROR";
|
||||
case CRYS_ECPKI_BUILD_DOMAIN_EC_PARAMETR_PTR_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_DOMAIN_EC_PARAMETR_PTR_ERROR";
|
||||
case CRYS_ECPKI_BUILD_DOMAIN_EC_PARAMETR_SIZE_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_DOMAIN_EC_PARAMETR_SIZE_ERROR";
|
||||
case CRYS_ECPKI_BUILD_DOMAIN_COFACTOR_PARAMS_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_DOMAIN_COFACTOR_PARAMS_ERROR";
|
||||
case CRYS_ECPKI_BUILD_DOMAIN_SECURITY_STRENGTH_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_DOMAIN_SECURITY_STRENGTH_ERROR";
|
||||
case CRYS_ECPKI_BUILD_SCA_RESIST_ILLEGAL_MODE_ERROR:
|
||||
return "CRYS_ECPKI_BUILD_SCA_RESIST_ILLEGAL_MODE_ERROR";
|
||||
case CRYS_ECDH_SVDP_DH_INVALID_PARTNER_PUBL_KEY_PTR_ERROR:
|
||||
return "CRYS_ECDH_SVDP_DH_INVALID_PARTNER_PUBL_KEY_PTR_ERROR";
|
||||
case CRYS_ECDH_SVDP_DH_PARTNER_PUBL_KEY_VALID_TAG_ERROR:
|
||||
return "CRYS_ECDH_SVDP_DH_PARTNER_PUBL_KEY_VALID_TAG_ERROR";
|
||||
case CRYS_ECDH_SVDP_DH_INVALID_USER_PRIV_KEY_PTR_ERROR:
|
||||
return "CRYS_ECDH_SVDP_DH_INVALID_USER_PRIV_KEY_PTR_ERROR";
|
||||
case CRYS_ECDH_SVDP_DH_USER_PRIV_KEY_VALID_TAG_ERROR:
|
||||
return "CRYS_ECDH_SVDP_DH_USER_PRIV_KEY_VALID_TAG_ERROR";
|
||||
case CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_PTR_ERROR:
|
||||
return "CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_PTR_ERROR";
|
||||
case CRYS_ECDH_SVDP_DH_INVALID_TEMP_DATA_PTR_ERROR:
|
||||
return "CRYS_ECDH_SVDP_DH_INVALID_TEMP_DATA_PTR_ERROR";
|
||||
case CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_PTR_ERROR:
|
||||
return "CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_PTR_ERROR";
|
||||
case CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR:
|
||||
return "CRYS_ECDH_SVDP_DH_INVALID_SHARED_SECRET_VALUE_SIZE_ERROR";
|
||||
case CRYS_ECDH_SVDP_DH_ILLEGAL_DOMAIN_ID_ERROR:
|
||||
return "CRYS_ECDH_SVDP_DH_ILLEGAL_DOMAIN_ID_ERROR";
|
||||
case CRYS_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR:
|
||||
return "CRYS_ECPKI_GEN_KEY_INVALID_PRIVATE_KEY_PTR_ERROR";
|
||||
case CRYS_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR:
|
||||
return "CRYS_ECPKI_GEN_KEY_INVALID_PUBLIC_KEY_PTR_ERROR";
|
||||
case CRYS_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR:
|
||||
return "CRYS_ECPKI_GEN_KEY_INVALID_TEMP_DATA_PTR_ERROR";
|
||||
case CRYS_ECPKI_INVALID_RND_FUNC_PTR_ERROR:
|
||||
return "CRYS_ECPKI_INVALID_RND_FUNC_PTR_ERROR";
|
||||
case CRYS_ECPKI_INVALID_RND_CTX_PTR_ERROR:
|
||||
return "CRYS_ECPKI_INVALID_RND_CTX_PTR_ERROR";
|
||||
case CRYS_ECPKI_INVALID_DOMAIN_ID_ERROR:
|
||||
return "CRYS_ECPKI_INVALID_DOMAIN_ID_ERROR";
|
||||
case CRYS_ECPKI_INVALID_PRIV_KEY_TAG_ERROR:
|
||||
return "CRYS_ECPKI_INVALID_PRIV_KEY_TAG_ERROR";
|
||||
case CRYS_ECPKI_INVALID_PUBL_KEY_TAG_ERROR:
|
||||
return "CRYS_ECPKI_INVALID_PUBL_KEY_TAG_ERROR";
|
||||
case CRYS_ECPKI_INVALID_DATA_IN_PASSED_STRUCT_ERROR:
|
||||
return "CRYS_ECPKI_INVALID_DATA_IN_PASSED_STRUCT_ERROR";
|
||||
case CRYS_HASH_DATA_SIZE_ILLEGAL:
|
||||
return "CRYS_HASH_DATA_SIZE_ILLEGAL";
|
||||
case CRYS_HASH_INVALID_RESULT_BUFFER_POINTER_ERROR:
|
||||
return "CRYS_HASH_INVALID_RESULT_BUFFER_POINTER_ERROR";
|
||||
case CRYS_HASH_ILLEGAL_PARAMS_ERROR:
|
||||
return "CRYS_HASH_ILLEGAL_PARAMS_ERROR";
|
||||
case CRYS_HASH_INVALID_USER_CONTEXT_POINTER_ERROR:
|
||||
return "CRYS_HASH_INVALID_USER_CONTEXT_POINTER_ERROR";
|
||||
case CRYS_HASH_LAST_BLOCK_ALREADY_PROCESSED_ERROR:
|
||||
return "CRYS_HASH_LAST_BLOCK_ALREADY_PROCESSED_ERROR";
|
||||
case CRYS_HASH_CTX_SIZES_ERROR:
|
||||
return "CRYS_HASH_CTX_SIZES_ERROR";
|
||||
case SASI_AES_INVALID_USER_CONTEXT_POINTER_ERROR:
|
||||
return "SASI_AES_INVALID_USER_CONTEXT_POINTER_ERROR";
|
||||
case SASI_AES_INVALID_IV_OR_TWEAK_PTR_ERROR:
|
||||
return "SASI_AES_INVALID_IV_OR_TWEAK_PTR_ERROR";
|
||||
case SASI_AES_ILLEGAL_OPERATION_MODE_ERROR:
|
||||
return "SASI_AES_ILLEGAL_OPERATION_MODE_ERROR";
|
||||
case SASI_AES_ILLEGAL_KEY_SIZE_ERROR:
|
||||
return "SASI_AES_ILLEGAL_KEY_SIZE_ERROR";
|
||||
case SASI_AES_INVALID_KEY_POINTER_ERROR:
|
||||
return "SASI_AES_INVALID_KEY_POINTER_ERROR";
|
||||
case SASI_AES_INVALID_ENCRYPT_MODE_ERROR:
|
||||
return "SASI_AES_INVALID_ENCRYPT_MODE_ERROR";
|
||||
case SASI_AES_DATA_IN_POINTER_INVALID_ERROR:
|
||||
return "SASI_AES_DATA_IN_POINTER_INVALID_ERROR";
|
||||
case SASI_AES_DATA_OUT_POINTER_INVALID_ERROR:
|
||||
return "SASI_AES_DATA_OUT_POINTER_INVALID_ERROR";
|
||||
case SASI_AES_DATA_IN_SIZE_ILLEGAL:
|
||||
return "SASI_AES_DATA_IN_SIZE_ILLEGAL";
|
||||
case SASI_AES_DATA_OUT_DATA_IN_OVERLAP_ERROR:
|
||||
return "SASI_AES_DATA_OUT_DATA_IN_OVERLAP_ERROR";
|
||||
case SASI_AES_DATA_OUT_SIZE_POINTER_INVALID_ERROR:
|
||||
return "SASI_AES_DATA_OUT_SIZE_POINTER_INVALID_ERROR";
|
||||
case SASI_AES_CTX_SIZES_ERROR:
|
||||
return "SASI_AES_CTX_SIZES_ERROR";
|
||||
case SASI_AES_ILLEGAL_PARAMS_ERROR:
|
||||
return "SASI_AES_ILLEGAL_PARAMS_ERROR";
|
||||
case SASI_AES_CTR_ILLEGAL_BLOCK_OFFSET_ERROR:
|
||||
return "SASI_AES_CTR_ILLEGAL_BLOCK_OFFSET_ERROR";
|
||||
case SASI_AES_CTR_ILLEGAL_COUNTER_ERROR:
|
||||
return "SASI_AES_CTR_ILLEGAL_COUNTER_ERROR";
|
||||
case SASI_AES_DATA_IN_BUFFER_SIZE_ERROR:
|
||||
return "SASI_AES_DATA_IN_BUFFER_SIZE_ERROR";
|
||||
case SASI_AES_DATA_OUT_BUFFER_SIZE_ERROR:
|
||||
return "SASI_AES_DATA_OUT_BUFFER_SIZE_ERROR";
|
||||
case SASI_AES_ILLEGAL_PADDING_TYPE_ERROR:
|
||||
return "SASI_AES_ILLEGAL_PADDING_TYPE_ERROR";
|
||||
case SASI_AES_INCORRECT_PADDING_ERROR:
|
||||
return "SASI_AES_INCORRECT_PADDING_ERROR";
|
||||
case SASI_AES_CORRUPTED_OUTPUT_ERROR:
|
||||
return "SASI_AES_CORRUPTED_OUTPUT_ERROR";
|
||||
case SASI_AES_USER_CONTEXT_CORRUPTED_ERROR:
|
||||
return "SASI_AES_USER_CONTEXT_CORRUPTED_ERROR";
|
||||
case SASI_AES_DECRYPTION_NOT_ALLOWED_ON_THIS_MODE:
|
||||
return "SASI_AES_DECRYPTION_NOT_ALLOWED_ON_THIS_MODE";
|
||||
case SASI_AES_ADDITIONAL_BLOCK_NOT_PERMITTED_ERROR:
|
||||
return "SASI_AES_ADDITIONAL_BLOCK_NOT_PERMITTED_ERROR";
|
||||
case SASI_AES_KEY_TYPE_NOT_SUPPORTED_ERROR:
|
||||
return "SASI_AES_KEY_TYPE_NOT_SUPPORTED_ERROR";
|
||||
case SASI_AES_IS_NOT_SUPPORTED:
|
||||
return "SASI_AES_IS_NOT_SUPPORTED";
|
||||
case SASI_OUT_OF_RESOURCE_ERROR:
|
||||
return "SASI_OUT_OF_RESOURCE_ERROR";
|
||||
default:
|
||||
return "Error value not recognized";
|
||||
}
|
||||
}
|
87
pkg/driver_cryptocell_310/psa_cryptocell_310/hashes_common.c
Normal file
87
pkg/driver_cryptocell_310/psa_cryptocell_310/hashes_common.c
Normal file
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @brief Common hash functions used by all PSA Crypto wrappers
|
||||
* for the CryptoCell 310 hash APIs.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_error.h"
|
||||
#include "cryptocell_310_util.h"
|
||||
#include "crys_hash.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define CC310_MAX_HASH_INPUT_BLOCK (0xFFF0)
|
||||
|
||||
psa_status_t cryptocell_310_common_hash_setup(CRYS_HASHUserContext_t *ctx,
|
||||
CRYS_HASH_OperationMode_t mode)
|
||||
{
|
||||
CRYSError_t ret = CRYS_HASH_Init(ctx, mode);
|
||||
|
||||
if (ret != CRYS_OK) {
|
||||
DEBUG("CRYS_HASH_Init failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return CRYS_to_psa_error(ret);
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t cryptocell_310_common_hash_update(CRYS_HASHUserContext_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
CRYSError_t ret = 0;
|
||||
size_t offset = 0;
|
||||
size_t size;
|
||||
|
||||
do {
|
||||
if (input_length > CC310_MAX_HASH_INPUT_BLOCK) {
|
||||
size = CC310_MAX_HASH_INPUT_BLOCK;
|
||||
input_length -= CC310_MAX_HASH_INPUT_BLOCK;
|
||||
}
|
||||
else {
|
||||
size = input_length;
|
||||
input_length = 0;
|
||||
}
|
||||
|
||||
cryptocell_310_enable();
|
||||
ret = CRYS_HASH_Update(ctx, (uint8_t *)(input + offset), size);
|
||||
cryptocell_310_disable();
|
||||
|
||||
offset += size;
|
||||
} while ((input_length > 0) && (ret == CRYS_OK));
|
||||
|
||||
if (ret != CRYS_OK) {
|
||||
DEBUG("CRYS_HASH_Update failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return CRYS_to_psa_error(ret);
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t cryptocell_310_common_hash_finish(CRYS_HASHUserContext_t *ctx, uint8_t *hash, size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
cryptocell_310_enable();
|
||||
CRYSError_t ret = CRYS_HASH_Finish(ctx, (uint32_t *)hash);
|
||||
cryptocell_310_disable();
|
||||
if (ret != CRYS_OK) {
|
||||
DEBUG("CRYS_HASH_Finish failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return CRYS_to_psa_error(ret);
|
||||
}
|
||||
*hash_length = hash_size;
|
||||
return PSA_SUCCESS;
|
||||
}
|
43
pkg/driver_cryptocell_310/psa_cryptocell_310/hashes_sha1.c
Normal file
43
pkg/driver_cryptocell_310/psa_cryptocell_310/hashes_sha1.c
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the CryptoCell 310 SHA1 APIs
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "kernel_defines.h"
|
||||
#include "psa_periph_hashes_ctx.h"
|
||||
#include "psa_cryptocell_310_hashes_common.h"
|
||||
|
||||
psa_status_t psa_hashes_sha1_setup(psa_hashes_sha1_ctx_t *ctx)
|
||||
{
|
||||
return cryptocell_310_common_hash_setup((CRYS_HASHUserContext_t *)ctx, CRYS_HASH_SHA1_mode);
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha1_update(psa_hashes_sha1_ctx_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
return cryptocell_310_common_hash_update((CRYS_HASHUserContext_t *)ctx, input, input_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha1_finish(psa_hashes_sha1_ctx_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
return cryptocell_310_common_hash_finish((CRYS_HASHUserContext_t *)ctx, hash, hash_size, hash_length);
|
||||
}
|
43
pkg/driver_cryptocell_310/psa_cryptocell_310/hashes_sha224.c
Normal file
43
pkg/driver_cryptocell_310/psa_cryptocell_310/hashes_sha224.c
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the CryptoCell 310 SHA224 APIs
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "kernel_defines.h"
|
||||
#include "psa_periph_hashes_ctx.h"
|
||||
#include "psa_cryptocell_310_hashes_common.h"
|
||||
|
||||
psa_status_t psa_hashes_sha224_setup(psa_hashes_sha224_ctx_t *ctx)
|
||||
{
|
||||
return cryptocell_310_common_hash_setup((CRYS_HASHUserContext_t *)ctx, CRYS_HASH_SHA224_mode);
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha224_update(psa_hashes_sha224_ctx_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
return cryptocell_310_common_hash_update((CRYS_HASHUserContext_t *)ctx, input, input_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha224_finish(psa_hashes_sha224_ctx_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
return cryptocell_310_common_hash_finish((CRYS_HASHUserContext_t *)ctx, hash, hash_size, hash_length);
|
||||
}
|
42
pkg/driver_cryptocell_310/psa_cryptocell_310/hashes_sha256.c
Normal file
42
pkg/driver_cryptocell_310/psa_cryptocell_310/hashes_sha256.c
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the CryptoCell 310 SHA256 APIs
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "kernel_defines.h"
|
||||
#include "psa_periph_hashes_ctx.h"
|
||||
#include "psa_cryptocell_310_hashes_common.h"
|
||||
|
||||
psa_status_t psa_hashes_sha256_setup(psa_hashes_sha256_ctx_t *ctx)
|
||||
{
|
||||
return cryptocell_310_common_hash_setup((CRYS_HASHUserContext_t *)ctx, CRYS_HASH_SHA256_mode);
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha256_update(psa_hashes_sha256_ctx_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
return cryptocell_310_common_hash_update((CRYS_HASHUserContext_t *)ctx, input, input_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha256_finish(psa_hashes_sha256_ctx_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
return cryptocell_310_common_hash_finish((CRYS_HASHUserContext_t *)ctx, hash, hash_size, hash_length);
|
||||
}
|
43
pkg/driver_cryptocell_310/psa_cryptocell_310/hashes_sha512.c
Normal file
43
pkg/driver_cryptocell_310/psa_cryptocell_310/hashes_sha512.c
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the CryptoCell 310 SHA512 APIs
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "kernel_defines.h"
|
||||
#include "psa_periph_hashes_ctx.h"
|
||||
#include "psa_cryptocell_310_hashes_common.h"
|
||||
|
||||
psa_status_t psa_hashes_sha512_setup(psa_hashes_sha512_ctx_t *ctx)
|
||||
{
|
||||
return cryptocell_310_common_hash_setup((CRYS_HASHUserContext_t *)ctx, CRYS_HASH_SHA512_mode);
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha512_update(psa_hashes_sha512_ctx_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
return cryptocell_310_common_hash_update((CRYS_HASHUserContext_t *)ctx, input, input_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha512_finish( psa_hashes_sha512_ctx_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
return cryptocell_310_common_hash_finish((CRYS_HASHUserContext_t *)ctx, hash, hash_size, hash_length);
|
||||
}
|
58
pkg/driver_cryptocell_310/psa_cryptocell_310/hmac.c
Normal file
58
pkg/driver_cryptocell_310/psa_cryptocell_310/hmac.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup pkg_driver_cryptocell_310
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the CryptoCell 310 driver APIs
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "kernel_defines.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_error.h"
|
||||
|
||||
#include "crys_hmac.h"
|
||||
#include "crys_hmac_error.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
psa_status_t psa_mac_compute_hmac_sha256(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length)
|
||||
{
|
||||
CRYSError_t ret;
|
||||
size_t required_mac_length =
|
||||
PSA_MAC_LENGTH(attributes->type, attributes->bits, PSA_ALG_SHA_256);
|
||||
|
||||
if (mac_size < required_mac_length) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
ret = CRYS_HMAC(CRYS_HASH_SHA256_mode, (uint8_t *)key_buffer, key_buffer_size, (uint8_t *)input,
|
||||
input_length, (uint32_t *)mac);
|
||||
if (ret != CRYS_OK) {
|
||||
DEBUG("CRYS_HMAC failed with %s\n", cryptocell310_status_to_humanly_readable(ret));
|
||||
return CRYS_to_psa_error(ret);
|
||||
}
|
||||
|
||||
*mac_length = required_mac_length;
|
||||
|
||||
(void)mac_size;
|
||||
return PSA_SUCCESS;
|
||||
}
|
@ -15,3 +15,5 @@ config PACKAGE_MICRO-ECC
|
||||
https://github.com/kmackay/micro-ecc and adds `hwrng_read` as
|
||||
the default RNG function if it is available on the target
|
||||
platform.
|
||||
|
||||
rsource "psa_uecc/Kconfig"
|
||||
|
@ -6,3 +6,10 @@ CFLAGS += -Wno-unused-variable
|
||||
|
||||
# llvm fails to allocate registers for inline assembly :/
|
||||
TOOLCHAINS_BLACKLIST += llvm
|
||||
|
||||
ifneq (,$(filter psa_uecc_%, $(USEMODULE)))
|
||||
PSEUDOMODULES += psa_uecc_p192
|
||||
PSEUDOMODULES += psa_uecc_p256
|
||||
DIRS += $(RIOTPKG)/micro-ecc/psa_uecc
|
||||
INCLUDES += -I$(RIOTBASE)/sys/psa_crypto/include
|
||||
endif
|
||||
|
19
pkg/micro-ecc/psa_uecc/Kconfig
Normal file
19
pkg/micro-ecc/psa_uecc/Kconfig
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2021 HAW Hamburg
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU Lesser
|
||||
# General Public License v2.1. See the file LICENSE in the top level
|
||||
# directory for more details.
|
||||
#
|
||||
|
||||
config MODULE_PSA_UECC_P192
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_UECC
|
||||
|
||||
config MODULE_PSA_UECC_P256
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_UECC
|
||||
|
||||
config MODULE_PSA_UECC
|
||||
bool
|
4
pkg/micro-ecc/psa_uecc/Makefile
Normal file
4
pkg/micro-ecc/psa_uecc/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
BASE_MODULE := psa_uecc
|
||||
SUBMODULES := 1
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
84
pkg/micro-ecc/psa_uecc/p192.c
Normal file
84
pkg/micro-ecc/psa_uecc/p192.c
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_psa_crypto pkg_micro-ecc
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the Micro-ECC APIs
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "uECC.h"
|
||||
|
||||
psa_status_t psa_generate_ecc_p192r1_key_pair( const psa_key_attributes_t *attributes,
|
||||
uint8_t *priv_key_buffer, uint8_t *pub_key_buffer,
|
||||
size_t *priv_key_buffer_length,
|
||||
size_t *pub_key_buffer_length)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
*priv_key_buffer_length = PSA_BITS_TO_BYTES(attributes->bits);
|
||||
*pub_key_buffer_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(attributes->type, attributes->bits);
|
||||
|
||||
const struct uECC_Curve_t *curve = uECC_secp192r1();
|
||||
|
||||
ret = uECC_make_key(pub_key_buffer, priv_key_buffer, curve);
|
||||
if (!ret) {
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_ecc_p192r1_sign_hash( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg, const uint8_t *key_buffer,
|
||||
size_t key_buffer_size, const uint8_t *hash,
|
||||
size_t hash_length, uint8_t *signature,
|
||||
size_t signature_size, size_t *signature_length)
|
||||
{
|
||||
int ret = 0;
|
||||
const struct uECC_Curve_t *curve = uECC_secp192r1();
|
||||
|
||||
ret = uECC_sign(key_buffer, hash, hash_length, signature, curve);
|
||||
if (!ret) {
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
*signature_length = signature_size;
|
||||
|
||||
(void)alg;
|
||||
(void)attributes;
|
||||
(void)key_buffer_size;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_ecc_p192r1_verify_hash(const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg, const uint8_t *key_buffer,
|
||||
size_t key_buffer_size, const uint8_t *hash,
|
||||
size_t hash_length, const uint8_t *signature,
|
||||
size_t signature_length)
|
||||
{
|
||||
int ret = 0;
|
||||
const struct uECC_Curve_t *curve = uECC_secp192r1();
|
||||
|
||||
ret = uECC_verify(key_buffer, hash, hash_length, signature, curve);
|
||||
if (!ret) {
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
(void)alg;
|
||||
(void)attributes;
|
||||
(void)key_buffer_size;
|
||||
(void)signature_length;
|
||||
return PSA_SUCCESS;
|
||||
}
|
84
pkg/micro-ecc/psa_uecc/p256.c
Normal file
84
pkg/micro-ecc/psa_uecc/p256.c
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_psa_crypto pkg_micro-ecc
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the Micro-ECC APIs
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "uECC.h"
|
||||
|
||||
psa_status_t psa_generate_ecc_p256r1_key_pair( const psa_key_attributes_t *attributes,
|
||||
uint8_t *priv_key_buffer, uint8_t *pub_key_buffer,
|
||||
size_t *priv_key_buffer_length,
|
||||
size_t *pub_key_buffer_length)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
*priv_key_buffer_length = PSA_BITS_TO_BYTES(attributes->bits);
|
||||
*pub_key_buffer_length = PSA_EXPORT_PUBLIC_KEY_OUTPUT_SIZE(attributes->type, attributes->bits);
|
||||
|
||||
const struct uECC_Curve_t *curve = uECC_secp256r1();
|
||||
|
||||
ret = uECC_make_key(pub_key_buffer, priv_key_buffer, curve);
|
||||
if (!ret) {
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_ecc_p256r1_sign_hash( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg, const uint8_t *key_buffer,
|
||||
size_t key_buffer_size, const uint8_t *hash,
|
||||
size_t hash_length, uint8_t *signature,
|
||||
size_t signature_size, size_t *signature_length)
|
||||
{
|
||||
int ret = 0;
|
||||
const struct uECC_Curve_t *curve = uECC_secp256r1();
|
||||
|
||||
ret = uECC_sign(key_buffer, hash, hash_length, signature, curve);
|
||||
if (!ret) {
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
*signature_length = signature_size;
|
||||
|
||||
(void)alg;
|
||||
(void)attributes;
|
||||
(void)key_buffer_size;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_ecc_p256r1_verify_hash(const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg, const uint8_t *key_buffer,
|
||||
size_t key_buffer_size, const uint8_t *hash,
|
||||
size_t hash_length, const uint8_t *signature,
|
||||
size_t signature_length)
|
||||
{
|
||||
int ret = 0;
|
||||
const struct uECC_Curve_t *curve = uECC_secp256r1();
|
||||
|
||||
ret = uECC_verify(key_buffer, hash, hash_length, signature, curve);
|
||||
if (!ret) {
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
(void)alg;
|
||||
(void)attributes;
|
||||
(void)key_buffer_size;
|
||||
(void)signature_length;
|
||||
return PSA_SUCCESS;
|
||||
}
|
@ -93,6 +93,7 @@ rsource "posix/Kconfig"
|
||||
rsource "preprocessor/Kconfig"
|
||||
rsource "progress_bar/Kconfig"
|
||||
rsource "ps/Kconfig"
|
||||
rsource "psa_crypto/Kconfig"
|
||||
rsource "random/Kconfig"
|
||||
rsource "rtc_utils/Kconfig"
|
||||
rsource "rust_riotmodules/Kconfig"
|
||||
|
@ -173,6 +173,9 @@ endif
|
||||
ifneq (,$(filter posix_sleep,$(USEMODULE)))
|
||||
DIRS += posix/sleep
|
||||
endif
|
||||
ifneq (,$(filter psa_crypto,$(USEMODULE)))
|
||||
DIRS += psa_crypto
|
||||
endif
|
||||
ifneq (,$(filter pthread,$(USEMODULE)))
|
||||
DIRS += posix/pthread
|
||||
endif
|
||||
|
@ -686,6 +686,14 @@ ifneq (,$(filter fido2_ctap%,$(USEMODULE)))
|
||||
USEMODULE += fido2
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_crypto,$(USEMODULE)))
|
||||
include $(RIOTBASE)/sys/psa_crypto/Makefile.dep
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_riot_cipher_aes_%,$(USEMODULE)))
|
||||
USEMODULE += psa_riot_cipher_aes_common
|
||||
endif
|
||||
|
||||
ifneq (,$(filter rust_riotmodules,$(USEMODULE)))
|
||||
include $(RIOTBASE)/sys/rust_riotmodules/Makefile.dep
|
||||
endif
|
||||
|
@ -163,6 +163,10 @@ ifneq (,$(filter prng,$(USEMODULE)))
|
||||
include $(RIOTBASE)/sys/random/Makefile.include
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_crypto,$(USEMODULE)))
|
||||
include $(RIOTBASE)/sys/psa_crypto/Makefile.include
|
||||
endif
|
||||
|
||||
ifneq (,$(filter test_utils_netdev_eth_minimal,$(USEMODULE)))
|
||||
CFLAGS += -DCONFIG_NETDEV_REGISTER_SIGNAL
|
||||
endif
|
||||
|
@ -278,11 +278,14 @@ AUTO_INIT(auto_init_mbedtls,
|
||||
AUTO_INIT_PRIO_MOD_MBEDTLS);
|
||||
#endif
|
||||
#if IS_USED(MODULE_AUTO_INIT_SECURITY)
|
||||
#if IS_USED(MODULE_CRYPTOAUTHLIB)
|
||||
extern void auto_init_atca(void);
|
||||
AUTO_INIT(auto_init_atca,
|
||||
AUTO_INIT_PRIO_MOD_CRYPTOAUTHLIB);
|
||||
extern void auto_init_security(void);
|
||||
AUTO_INIT(auto_init_security,
|
||||
AUTO_INIT_PRIO_MOD_SECURITY);
|
||||
#endif
|
||||
#if IS_USED(MODULE_DRIVER_CRYPTOCELL_310)
|
||||
extern void driver_cryptocell_310_setup(void);
|
||||
AUTO_INIT(driver_cryptocell_310_setup,
|
||||
AUTO_INIT_PRIO_MOD_DRIVER_CRYPTOCELL_310);
|
||||
#endif
|
||||
#if IS_USED(MODULE_TEST_UTILS_INTERACTIVE_SYNC) && !IS_USED(MODULE_SHELL)
|
||||
extern void test_utils_interactive_sync(void);
|
||||
|
@ -317,11 +317,11 @@ extern "C" {
|
||||
*/
|
||||
#define AUTO_INIT_PRIO_MOD_MBEDTLS 1440
|
||||
#endif
|
||||
#ifndef AUTO_INIT_PRIO_MOD_CRYPTOAUTHLIB
|
||||
#ifndef AUTO_INIT_PRIO_MOD_SECURITY
|
||||
/**
|
||||
* @brief CryptoAuthLib priority
|
||||
*/
|
||||
#define AUTO_INIT_PRIO_MOD_CRYPTOAUTHLIB 1450
|
||||
#define AUTO_INIT_PRIO_MOD_SECURITY 1450
|
||||
#endif
|
||||
#ifndef AUTO_INIT_PRIO_MOD_TEST_UTILS_INTERACTIVE_SYNC
|
||||
/**
|
||||
@ -389,6 +389,12 @@ extern "C" {
|
||||
*/
|
||||
#define AUTO_INIT_PRIO_MOD_GNRC_IPV6_STATIC_ADDR 1560
|
||||
#endif
|
||||
#ifndef AUTO_INIT_PRIO_MOD_DRIVER_CRYPTOCELL_310
|
||||
/**
|
||||
* @brief CryptoCell Driver Priority
|
||||
*/
|
||||
#define AUTO_INIT_PRIO_MOD_DRIVER_CRYPTOCELL_310 1570
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -19,18 +19,62 @@
|
||||
#include "log.h"
|
||||
#include "atca.h"
|
||||
#include "atca_params.h"
|
||||
#include "kernel_defines.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#define ATCA_NUMOF (ARRAY_SIZE(atca_params))
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A)
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_se_management.h"
|
||||
|
||||
extern psa_drv_se_t atca_methods;
|
||||
|
||||
psa_se_config_t atca_config_list[] = { ATCA_CONFIG_LIST };
|
||||
#endif
|
||||
|
||||
ATCADevice atca_devs_ptr[ATCA_NUMOF];
|
||||
|
||||
static struct atca_device atca_devs[ATCA_NUMOF];
|
||||
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A)
|
||||
void auto_init_atca(void)
|
||||
{
|
||||
DEBUG("[auto_init_atca] Number of secure elements: %d\n", ATCA_NUMOF);
|
||||
for (unsigned i = 0; i < ATCA_NUMOF; i++) {
|
||||
if (atcab_init((ATCAIfaceCfg *)&atca_params[i]) != ATCA_SUCCESS) {
|
||||
LOG_ERROR("[auto_init_atca] error initializing cryptoauth device #%u\n", i);
|
||||
int status = initATCADevice((ATCAIfaceCfg *)&atca_params[i].cfg, (ATCADevice)&atca_devs[i]);
|
||||
if (status != ATCA_SUCCESS) {
|
||||
LOG_ERROR("[auto_init_atca] error initializing cryptoauth device #%u, status: %d\n",
|
||||
i, status);
|
||||
continue;
|
||||
}
|
||||
atca_devs_ptr[i] = &atca_devs[i];
|
||||
|
||||
DEBUG("[auto_init_atca] Registering Driver with address: %x and location: %lx\n", atca_params[i].cfg.atcai2c.address, atca_params[i].atca_loc);
|
||||
status = psa_register_secure_element(atca_params[i].atca_loc,
|
||||
&atca_methods,
|
||||
&atca_config_list[i],
|
||||
&atca_devs[i]);
|
||||
if (status != PSA_SUCCESS) {
|
||||
LOG_ERROR(
|
||||
"[auto_init_atca] PSA Crypto – error registering cryptoauth PSA driver\
|
||||
for device #%u, status: %s\n", i, psa_status_to_humanly_readable(status));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void auto_init_atca(void)
|
||||
{
|
||||
DEBUG("[auto_init_atca] Number of secure elements: %d\n", ATCA_NUMOF);
|
||||
for (unsigned i = 0; i < ATCA_NUMOF; i++) {
|
||||
int status = initATCADevice((ATCAIfaceCfg *)&atca_params[i], (ATCADevice)&atca_devs[i]);
|
||||
if (status != ATCA_SUCCESS) {
|
||||
LOG_ERROR("[auto_init_atca] error initializing cryptoauth device #%u, status: %d\n",
|
||||
i, status);
|
||||
continue;
|
||||
}
|
||||
atca_devs_ptr[i] = &atca_devs[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
30
sys/auto_init/security/init.c
Normal file
30
sys/auto_init/security/init.c
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2023 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_auto_init
|
||||
* @{
|
||||
* @file
|
||||
* @brief Initializes security modules
|
||||
*
|
||||
* @author Bennet Blischke <bennet.blischke@haw-hamburg.de>
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg,de>
|
||||
* @}
|
||||
*/
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
void auto_init_security(void)
|
||||
{
|
||||
#if IS_USED(MODULE_CRYPTOAUTHLIB)
|
||||
extern void auto_init_atca(void);
|
||||
DEBUG("auto_init_security: atca\n");
|
||||
auto_init_atca();
|
||||
#endif
|
||||
}
|
@ -33,6 +33,7 @@ config MODULE_CRYPTO_AES_UNROLL
|
||||
|
||||
endmenu # Crypto AES options
|
||||
|
||||
rsource "psa_riot_cipher/Kconfig"
|
||||
rsource "modes/Kconfig"
|
||||
|
||||
endif # Crypto
|
||||
|
@ -4,4 +4,8 @@ endif
|
||||
|
||||
CFLAGS += -DRIOT_CHACHA_PRNG_DEFAULT="$(RIOT_CHACHA_PRNG_DEFAULT)"
|
||||
|
||||
ifneq (,$(filter psa_riot_cipher_%,$(USEMODULE)))
|
||||
DIRS += psa_riot_cipher
|
||||
endif
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
38
sys/crypto/psa_riot_cipher/Kconfig
Normal file
38
sys/crypto/psa_riot_cipher/Kconfig
Normal file
@ -0,0 +1,38 @@
|
||||
# Copyright (c) 2021 HAW Hamburg
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU Lesser
|
||||
# General Public License v2.1. See the file LICENSE in the top level
|
||||
# directory for more details.
|
||||
#
|
||||
|
||||
config MODULE_PSA_RIOT_CIPHER_AES_128_ECB
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_CRYPTO_AES_128
|
||||
select MODULE_PSA_RIOT_CIPHER
|
||||
|
||||
config MODULE_PSA_RIOT_CIPHER_AES_128_CBC
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_CRYPTO_AES_128
|
||||
select MODULE_PSA_RIOT_CIPHER
|
||||
|
||||
config MODULE_PSA_RIOT_CIPHER_AES_192_CBC
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_CRYPTO_AES_192
|
||||
select MODULE_PSA_RIOT_CIPHER
|
||||
|
||||
config MODULE_PSA_RIOT_CIPHER_AES_256_CBC
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_CRYPTO_AES_192
|
||||
select MODULE_PSA_RIOT_CIPHER
|
||||
|
||||
config MODULE_PSA_RIOT_CIPHER
|
||||
bool
|
||||
select MODULE_PSA_RIOT_CIPHER_AES_COMMON
|
||||
select MODULE_CIPHER_MODES
|
||||
|
||||
config MODULE_PSA_RIOT_CIPHER_AES_COMMON
|
||||
bool
|
4
sys/crypto/psa_riot_cipher/Makefile
Normal file
4
sys/crypto/psa_riot_cipher/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
BASE_MODULE := psa_riot_cipher
|
||||
SUBMODULES := 1
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
91
sys/crypto/psa_riot_cipher/aes_128_cbc.c
Normal file
91
sys/crypto/psa_riot_cipher/aes_128_cbc.c
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_psa_crypto
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Glue code translating between PSA Crypto and the RIOT Cipher module
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "crypto/modes/cbc.h"
|
||||
#include "aes_common.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
psa_status_t psa_cipher_cbc_aes_128_encrypt(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
DEBUG("RIOT AES 128 Cipher");
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_cipher_operation_t operation = psa_cipher_operation_init();
|
||||
size_t iv_length = 0;
|
||||
size_t required_output_buf_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_AES,
|
||||
PSA_ALG_CBC_NO_PADDING, input_length);
|
||||
|
||||
if (output_size < required_output_buf_size) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
operation.iv_required = 1;
|
||||
operation.default_iv_length = PSA_CIPHER_IV_LENGTH(attributes->type, alg);
|
||||
*output_length = 0;
|
||||
|
||||
status = psa_cipher_generate_iv(&operation, output, operation.default_iv_length, &iv_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return cbc_aes_common_encrypt_decrypt(&operation.backend_ctx.cipher_ctx.aes_128, key_buffer,
|
||||
key_buffer_size, output, input, input_length,
|
||||
output + iv_length, output_length, PSA_CRYPTO_DRIVER_ENCRYPT);
|
||||
}
|
||||
|
||||
psa_status_t psa_cipher_cbc_aes_128_decrypt(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
DEBUG("RIOT AES 128 Cipher");
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_cipher_operation_t operation = psa_cipher_operation_init();
|
||||
size_t required_output_buf_size = PSA_CIPHER_DECRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_AES,
|
||||
PSA_ALG_CBC_NO_PADDING, input_length);
|
||||
|
||||
if (output_size < required_output_buf_size) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
operation.iv_required = 1;
|
||||
operation.default_iv_length = PSA_CIPHER_IV_LENGTH(attributes->type, alg);
|
||||
*output_length = 0;
|
||||
|
||||
return cbc_aes_common_encrypt_decrypt(&operation.backend_ctx.cipher_ctx.aes_128, key_buffer,
|
||||
key_buffer_size, input, input + operation.default_iv_length,
|
||||
input_length - operation.default_iv_length, output,
|
||||
output_length, PSA_CRYPTO_DRIVER_DECRYPT);
|
||||
}
|
61
sys/crypto/psa_riot_cipher/aes_256_cbc.c
Normal file
61
sys/crypto/psa_riot_cipher/aes_256_cbc.c
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (C) 2021 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_psa_crypto
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Glue code translating between PSA Crypto and the RIOT Cipher module
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "crypto/modes/cbc.h"
|
||||
#include "aes_common.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
psa_status_t psa_cipher_cbc_aes_256_encrypt(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
psa_algorithm_t alg,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
DEBUG("RIOT AES 256 Cipher");
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_cipher_operation_t operation = psa_cipher_operation_init();
|
||||
size_t iv_length = 0;
|
||||
size_t required_output_buf_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_AES,
|
||||
PSA_ALG_CBC_NO_PADDING, input_length);
|
||||
|
||||
if (output_size < required_output_buf_size) {
|
||||
return PSA_ERROR_BUFFER_TOO_SMALL;
|
||||
}
|
||||
|
||||
operation.iv_required = 1;
|
||||
operation.default_iv_length = PSA_CIPHER_IV_LENGTH(attributes->type, alg);
|
||||
*output_length = 0;
|
||||
|
||||
status = psa_cipher_generate_iv(&operation, output, operation.default_iv_length, &iv_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
status = cbc_aes_common(&operation.backend_ctx.cipher_ctx.aes_256, key_buffer, key_buffer_size,
|
||||
output, input, input_length, output + operation.default_iv_length,
|
||||
output_length);
|
||||
return status;
|
||||
}
|
68
sys/crypto/psa_riot_cipher/aes_common.c
Normal file
68
sys/crypto/psa_riot_cipher/aes_common.c
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_psa_crypto
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Glue code translating between PSA Crypto and the RIOT Cipher module
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "crypto/modes/cbc.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
psa_status_t cipher_to_psa_error(int error)
|
||||
{
|
||||
switch (error) {
|
||||
case CIPHER_ERR_INVALID_KEY_SIZE:
|
||||
case CIPHER_ERR_INVALID_LENGTH:
|
||||
case CIPHER_ERR_BAD_CONTEXT_SIZE:
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
default:
|
||||
return PSA_ERROR_GENERIC_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t cbc_aes_common_encrypt_decrypt(cipher_t *ctx,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *iv,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t *output_length,
|
||||
psa_encrypt_or_decrypt_t direction)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = cipher_init(ctx, CIPHER_AES, key_buffer, key_buffer_size);
|
||||
if (ret != CIPHER_INIT_SUCCESS) {
|
||||
return cipher_to_psa_error(ret);
|
||||
}
|
||||
|
||||
if (direction == PSA_CRYPTO_DRIVER_ENCRYPT) {
|
||||
ret = cipher_encrypt_cbc(ctx, (uint8_t *)iv, input, input_length, output);
|
||||
}
|
||||
else {
|
||||
ret = cipher_decrypt_cbc(ctx, (uint8_t *)iv, input, input_length, output);
|
||||
}
|
||||
if (ret <= 0) {
|
||||
return cipher_to_psa_error(ret);
|
||||
}
|
||||
|
||||
*output_length = ret;
|
||||
return PSA_SUCCESS;
|
||||
}
|
59
sys/crypto/psa_riot_cipher/aes_common.h
Normal file
59
sys/crypto/psa_riot_cipher/aes_common.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @cond
|
||||
* @ingroup sys_crypto
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the RIOT Cipher module
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef AES_COMMON_H
|
||||
#define AES_COMMON_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "crypto/modes/cbc.h"
|
||||
|
||||
/**
|
||||
* @brief Converts errors of the RIOT cipher module to PSA status values
|
||||
*
|
||||
* @param error
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t cipher_to_psa_error(int error);
|
||||
|
||||
/**
|
||||
* @brief Common AES CBC Encrypt function
|
||||
*
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t cbc_aes_common_encrypt_decrypt(cipher_t *ctx,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *iv,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t *output_length,
|
||||
psa_encrypt_or_decrypt_t direction);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* AES_COMMON_H */
|
||||
/** @} */
|
||||
/** @endcond */
|
@ -9,3 +9,5 @@ config MODULE_HASHES
|
||||
bool "Hash algorithms"
|
||||
depends on TEST_KCONFIG
|
||||
select MODULE_CRYPTO
|
||||
|
||||
rsource "psa_riot_hashes/Kconfig"
|
||||
|
@ -1 +1,7 @@
|
||||
MODULE := hashes
|
||||
|
||||
ifneq (,$(filter psa_riot_hashes_%,$(USEMODULE)))
|
||||
DIRS += psa_riot_hashes
|
||||
endif
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
|
39
sys/hashes/psa_riot_hashes/Kconfig
Normal file
39
sys/hashes/psa_riot_hashes/Kconfig
Normal file
@ -0,0 +1,39 @@
|
||||
# Copyright (c) 2021 HAW Hamburg
|
||||
#
|
||||
# This file is subject to the terms and conditions of the GNU Lesser
|
||||
# General Public License v2.1. See the file LICENSE in the top level
|
||||
# directory for more details.
|
||||
#
|
||||
|
||||
config MODULE_PSA_RIOT_HASHES_MD5
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_RIOT_HASHES
|
||||
select MODULE_HASHES
|
||||
|
||||
config MODULE_PSA_RIOT_HASHES_SHA_1
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_RIOT_HASHES
|
||||
select MODULE_HASHES
|
||||
|
||||
config MODULE_PSA_RIOT_HASHES_SHA_224
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_RIOT_HASHES
|
||||
select MODULE_HASHES
|
||||
|
||||
config MODULE_PSA_RIOT_HASHES_SHA_256
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_RIOT_HASHES
|
||||
select MODULE_HASHES
|
||||
|
||||
config MODULE_PSA_RIOT_HASHES_HMAC_SHA256
|
||||
bool
|
||||
depends on MODULE_PSA_CRYPTO
|
||||
select MODULE_PSA_RIOT_HASHES
|
||||
select MODULE_HASHES
|
||||
|
||||
config MODULE_PSA_RIOT_HASHES
|
||||
bool
|
4
sys/hashes/psa_riot_hashes/Makefile
Normal file
4
sys/hashes/psa_riot_hashes/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
BASE_MODULE := psa_riot_hashes
|
||||
SUBMODULES := 1
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
38
sys/hashes/psa_riot_hashes/hmac_sha256.c
Normal file
38
sys/hashes/psa_riot_hashes/hmac_sha256.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_psa_crypto
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the RIOT Hash module
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "hashes/psa/riot_hashes.h"
|
||||
|
||||
psa_status_t psa_mac_compute_hmac_sha256(const psa_key_attributes_t *attributes,
|
||||
const uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length)
|
||||
{
|
||||
hmac_sha256(key_buffer, key_buffer_size, input, input_length, mac);
|
||||
*mac_length = 32;
|
||||
|
||||
(void)mac_size;
|
||||
(void)attributes;
|
||||
return PSA_SUCCESS;
|
||||
}
|
47
sys/hashes/psa_riot_hashes/md5.c
Normal file
47
sys/hashes/psa_riot_hashes/md5.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_psa_crypto
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the RIOT Hash module
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "hashes/psa/riot_hashes.h"
|
||||
|
||||
psa_status_t psa_hashes_md5_setup(psa_hashes_md5_ctx_t *ctx)
|
||||
{
|
||||
md5_init((md5_ctx_t *)ctx);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_md5_update(psa_hashes_md5_ctx_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
md5_update((md5_ctx_t *)ctx, input, input_length);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_md5_finish(psa_hashes_md5_ctx_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
md5_final((md5_ctx_t *)ctx, hash);
|
||||
|
||||
(void)hash_size;
|
||||
(void)hash_length;
|
||||
return PSA_SUCCESS;
|
||||
}
|
47
sys/hashes/psa_riot_hashes/sha_1.c
Normal file
47
sys/hashes/psa_riot_hashes/sha_1.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_psa_crypto
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the RIOT Hash module
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "hashes/psa/riot_hashes.h"
|
||||
|
||||
psa_status_t psa_hashes_sha1_setup(psa_hashes_sha1_ctx_t *ctx)
|
||||
{
|
||||
sha1_init((sha1_context *)ctx);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha1_update(psa_hashes_sha1_ctx_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
sha1_update((sha1_context *)ctx, input, input_length);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha1_finish(psa_hashes_sha1_ctx_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
sha1_final((sha1_context *)ctx, hash);
|
||||
|
||||
(void)hash_size;
|
||||
(void)hash_length;
|
||||
return PSA_SUCCESS;
|
||||
}
|
47
sys/hashes/psa_riot_hashes/sha_224.c
Normal file
47
sys/hashes/psa_riot_hashes/sha_224.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_psa_crypto
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the RIOT Hash module
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "hashes/psa/riot_hashes.h"
|
||||
|
||||
psa_status_t psa_hashes_sha224_setup(psa_hashes_sha224_ctx_t *ctx)
|
||||
{
|
||||
sha224_init((sha224_context_t *)ctx);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha224_update(psa_hashes_sha224_ctx_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
sha224_update((sha224_context_t *)ctx, input, input_length);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha224_finish(psa_hashes_sha224_ctx_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
sha224_final((sha224_context_t *)ctx, hash);
|
||||
|
||||
(void)hash_size;
|
||||
(void)hash_length;
|
||||
return PSA_SUCCESS;
|
||||
}
|
47
sys/hashes/psa_riot_hashes/sha_256.c
Normal file
47
sys/hashes/psa_riot_hashes/sha_256.c
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_psa_crypto
|
||||
* @{
|
||||
*
|
||||
* @brief Glue code translating between PSA Crypto and the RIOT Hash module
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "hashes/psa/riot_hashes.h"
|
||||
|
||||
psa_status_t psa_hashes_sha256_setup(psa_hashes_sha256_ctx_t *ctx)
|
||||
{
|
||||
sha256_init((sha256_context_t *)ctx);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha256_update(psa_hashes_sha256_ctx_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
sha256_update((sha256_context_t *)ctx, input, input_length);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_hashes_sha256_finish(psa_hashes_sha256_ctx_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
sha256_final((sha256_context_t *)ctx, hash);
|
||||
|
||||
(void)hash_size;
|
||||
(void)hash_length;
|
||||
return PSA_SUCCESS;
|
||||
}
|
44
sys/include/crypto/psa/riot_ciphers.h
Normal file
44
sys/include/crypto/psa/riot_ciphers.h
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (C) 2022 HAW Hamburg
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU Lesser
|
||||
* General Public License v2.1. See the file LICENSE in the top level
|
||||
* directory for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ingroup sys_psa_crypto
|
||||
* @{
|
||||
*
|
||||
* @brief Contexts for the RIOT cipher module
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CRYPTO_PSA_RIOT_CIPHERS_H
|
||||
#define CRYPTO_PSA_RIOT_CIPHERS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "crypto/ciphers.h"
|
||||
#include "kernel_defines.h"
|
||||
|
||||
#if IS_USED(MODULE_PSA_RIOT_CIPHER_AES_128_CBC)
|
||||
typedef cipher_t psa_cipher_aes_128_ctx_t;
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_RIOT_CIPHER_AES_192_CBC)
|
||||
typedef cipher_t psa_cipher_aes_192_ctx_t;
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_RIOT_CIPHER_AES_256_CBC)
|
||||
typedef cipher_t psa_cipher_aes_256_ctx_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CRYPTO_PSA_RIOT_CIPHERS_H */
|
||||
/** @} */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user