mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-15 17:43:51 +01:00
sys: Add PSA Crypto Module
This commit is contained in:
parent
5cf32002f5
commit
d4c73d6a30
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, \
|
||||
d09GRk9UVE8AAEqUAAwAAAAAYcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAANyAAAPMwA \
|
||||
AEs6DMM0+EdQT1MAAApUAAACYAAABC6M9nifR1NVQgAADLQAAAETAAAB2lMBWKdPUy8yAAABfAAA \
|
||||
AE8AAABgU+v8UGNtYXAAAAOAAAAC0gAAA456sj3GaGVhZAAAARwAAAA0AAAANu2lsXloaGVhAAAB \
|
||||
UAAAACMAAAAkBf8H/GhtdHgAAAZUAAACAQAAA3pRqyk9a2VybgAACHAAAAHjAAAERBcFFf9tYXhw \
|
||||
AAABdAAAAAYAAAAGAN9QAG5hbWUAAAHMAAABtAAAA3iH46cycG9zdAAACFgAAAAVAAAAIAA9AGB4 \
|
||||
2mNgZGBgYGRwWl20niOe3+YrAzPzC6AIw9Fgs7sw+v+D/yYsHMyZQC4zAxNIFABjfAyLeNpjYGRg \
|
||||
YJr034zBiPnF/wf/H7BwAOkABgsGBLgHAM+fCgIAAABQAADfAAB42mNgYmxlnMDAysjCtIepi4GB \
|
||||
oQdCM95lMGL4xYAEGhgY1gMpLhjf39cxiMGBQUFRiWnSfzMGI+ZMhjNAYUaQHOMppkYgtYCBBQDF \
|
||||
/A5/AHjajZLdShtBGIbfSVaTgJRaKPREGEopUWSy8UBhKUUR2qP1QMTz1R2TJZtsmBlNvQlvwVto \
|
||||
b6J34n303cnUDtQDd9j5nu/3nf0B8EF8hsD6+sJ7zQIJvTV30MNx4C528D1wEtVsYBtl4M0o3sMe \
|
||||
bgP38Q6PgQcRb+E9fgV+G/Vue90uRDKg9wO/Awv0xdfAHbwR3wJ3kYmLwElUs4GP4iHwZhTv4UL8 \
|
||||
DNzHp04SeBDxFvY6w9NmeW+qydTJ4fWuzJ+M0wt5pp3T9VVdlG5fHqTpoZIndS19nZVGW23udKny \
|
||||
yjbnenJbFyYv2saoL5NtNvPdl9rYqlnIsUrHbeCoTcnKykI6U5R6XpiZbG5eUFf/h6bOLbPRaLVa \
|
||||
qWY+M9pZZTVO0WCJexhUmGAKB4khrrFLm+OJcQeNBb0zWue9Gle8C35bh31mDpByHUKRT5ipaf/N \
|
||||
s97TtJr2jnvJypx5S+1z+hP+De08w2jxrPiyXubPte7NIu1LP90y0/jTjqmRcv9bcfTcJb2VnCc5 \
|
||||
z/i5GnOvPGOswc0rn129qmrqY0uedsS18ktRZU414zssfb6dP5jDmrx42l2SiVPNURTHP7eeLSLt \
|
||||
kfzeo1LSIlshKtkiEbJUWh4VWUORFmuLFMlWCdlCUlLWmmwv2WbsaUL+DSbP9ZAZZ+Z75pw793vm \
|
||||
3O/3AsYYIDQIfoW97IShR/TkXyz8g/9iYe5B3b3HD4rPnH54/fh0v5tjxo4bP8HHd+KkyceOXq66 \
|
||||
kjPFztbG2srSwnyg2YD+pv1Eh5GxqkfPXr37mPStaDhVe7vSe7SXp4f7KLeRri4jnJ0chw/TqJVB \
|
||||
g+2HOAw9W1/+icCAjRuSpmXFaWODYqZGrYiMmD8vNGRu8MxZM/xnLw5fsrS1rrGpPb9lZfa+vZcu \
|
||||
sGkH16D5lWG1to9EL8rbX8MTKC05EbYlOS0l/u6dgsKiw9Ws2sX9k2Xw9MihA482r9u6dv2axITV \
|
||||
qdvZlp6ZseDi+VtywLlfU1RGSTL7oaDCAQ98CGUZm9lOBlV84wd64SUCRJiIEakiQxQZ6Yw6jHWK \
|
||||
pTJIcVA0ipPiqfgqVWqNXi/nKHjiy3yWs4U0TlPNdwPfXywQ0ZKf3s23UGwVe0Ux8H26+SrQ10qc \
|
||||
/62+PlIfr1frCwy1icS4rq9drV1Wf93pTO4sltnqS5z01E8eLJPYI3GDO7z+e0vECq3M2u4+Su6i \
|
||||
FQmGOqHb/1wOouMej3lAMWfk9g+5znGmy8k3OcZRLktFrpDDFOywxQZrrLDEAnMGYsYA+mNKP7lJ \
|
||||
BxU0cIpablOJN6Pxkrp44M4o3BiJKy6MwBknHBnOMDSopXJnqaecT4Sxn0aa+EyzfEc7F9hHG6XU \
|
||||
kM0t6uQPeM8HLvGKFo5IE9/xkRLe8Fa+OE/qvlW6l0wgAWxiI+vZwDrWspo1JJLAbpLYRqr0N41p \
|
||||
XGWH9DmdTLLYKZVbiZY4YokhiKlEE0UkK4iQjoYyjxDmModgZjGTGczGX/q7iHAWk0I8z3jBc15y \
|
||||
V2pfxGEOUUAhB2jlKfmcpOwngzrgbwAAeNpdk7trk2EUxp/zRlBQoV7A0LRSUk3TemkztMa0SMT6 \
|
||||
acFChSJFHLIIukUt6OClXobgJJ1FAlUp0sHBQV3MWBykf0JHqVaXjEL8nS+fNTr8eL73dt7nnPd8 \
|
||||
akhWVzFh0u7rqN1Vjy1rwhrqCx912F4zXoQF5W1dk2EH+67AK5hWWqvoe3hOjGtoFVbgIWPXtzpg \
|
||||
NZ2ym+oP3cqxJ2c3tN/mNGR5dduUhu2IInuiEkR2B60pCjOKiH0GP5HWWht8T/g8PkrxuWq8v4Tv \
|
||||
9rmKDiZ5zMA4HINBOAenYTRZH1ZDY+EXnvyM3+ceHV//E8fnO6m1vWm19R028TMAch9oREw59kjp \
|
||||
ON9OPF/36J6riWc09HJX5T9W2Mf+UIzvIu/WN+Lvcbz+cX07eapiuK6urRwSwuzWu/7ljUL8tp0s \
|
||||
qjd+3w9K2TPe94Uy4YsGHLuqHu4toflYhb95FewWuFZU1ieNkHcBXMte22QcayjruC3xHkus/9Q4 \
|
||||
jBCnC9K2m7rswpfIw+eaegcPYCFhOabOmbrKSR4X/smpSQ6uJ5XTms7DNOMTMc3WupP62lbmzsJl \
|
||||
OARZ6Ie9tkkP0hepe8qFi/TnZ+2j1llib7eX5O085t/wf2AK9d69rW36oZ3ULArzyoZL1G1WGW0o \
|
||||
Y4Mao0dHrYA69GTo4yz15XtI2d9WDLqqAAAAeNpjYGZgYOACYgOGBAYsAAANuwCeAAAAeNod0rFv \
|
||||
2kAUx/FDKbXlATpEqAR6SaxcK4QaN9xu2YP584IUJPDQuXOlbsyeM3fwxMzM6vzed/no6b3zu3d3 \
|
||||
ds6NnPtUyX83ziWjjaLxcJHJcJUpcYZzZW5UNS0zdiPFY+Xf5d1wkkv0mGPANesL4jj8lSVWfFsP \
|
||||
Z9nglvxh6OQRW2U+s3vCjoni//IOgzok6mxGLIffsqJqnRM6J+ps1QPxEVutTNXzIq1nSs9U859l \
|
||||
IC4wYjn8kVviAx6xVT6jT8ZtZOrTyQXxN3zU2TP3RD4Qfyf+gWu+/Um+wIglnbd4oM8RbceJ3qKT \
|
||||
CaaYoddUE7fTvU3cXiun3NtUU5lee001g1lgLb9oL7OVt9zGrV7wKgOZNXFBHInL4U1WxDU22Co/ \
|
||||
4/+ZaSrT/pYZL/gV55r8XSbaZa41ZkZmQXWJHne6h7lOcXILTXKVBUYsyVfENTbYKr/UnV9lwAIj \
|
||||
lrqlpdZ0zlP1VD1VT09Ph3uq91QfmSpXb92L6uYDBvIvGNH+7ZypcqbKmSrXO56l/c9PnC5w3kDn \
|
||||
QGZFtxU7rvj22e20y7Pb2+2zvmB9wfoX3JDfEEfiyJpIpiJTY4OveoWTe8O9bqmTvzRVz7v3zNAz \
|
||||
Q68TXaS9da8TWVyTb4j11h+zVIAWAHjaZZO9axRBGMafmTWXD8MpGsR8eObropJoTK5Sw5GISWHl \
|
||||
vyB+IBhCUKvUqVIYuIBekfrqYLmkENlOWS23CBapRLbeQgLrb+aWMxdZnnl35n2fZ973nRkZSQMa \
|
||||
132Z9afvNtSnc6woz2UxRvbZ5ttNlV+/eLOhIb8iP+JRSWU/N7pYRF+SCdbVo17nCXa81pSe6KU2 \
|
||||
Feqz/pg5s2Wa5pM5NL/NibX2pn1sn9stu2137KH9Yn/Yn/aXzexJUAqGgpFgPJgJ5oLFYAnVnjxV \
|
||||
b56pDzsAhvm3rGZ+xt78DeexRvJQY6ACJkEVzBIxj63lB6qDZeJW8mOtgjXmH/JIH0GTf+OVy4Ve \
|
||||
gl6CRgw/hh/D34efnOLH8I/hH8Pf1yDMtMOssFrFzoMaqOctGAmMBEYCo6XLBcPlHmkUew1MkO80 \
|
||||
c5f/DPYGcHXcZt6uJSzUWqjFqMVerZeeRHQqolMRvYnIIdEule3hLfm6RkAFrarvS0otKb2sMzbB \
|
||||
eZ/9JDHOP4t1MTVsPW9Qe0Z8Ru0Z0Q1OuX0qWedU2h3sJ48YX4IvwRdTWcbJuJ0z8gnJJ+TGVb1+ \
|
||||
VuiHZ/RDMp7wmZyOcicVcSfOcl287awav9ugRrm7FTAOnG+hwzjo2m3Nn6C7AS7DoCvfoKO64u/d \
|
||||
Llp7oDuqzbR+7X8N42fd4zAZt0dLnZHusn+/7/+/2tKi72mRaer77l4gTN7YQz3CvtK2xvRV33RP \
|
||||
3/ke6IhviZgpENCtEnejj/de1gXe7JCu6Cq8UVgVXdeEJjWtqm7pjua1oEXVtKwVreq9GtR69Bdu \
|
||||
z5FceNpdkbFKA0EURc/b2UgISwqxEhEbGysxyRoE/QJLP8CgWEmEkI+wsLK0sLAQy3SxsLBQELFS \
|
||||
C/UDxMpKrMR452UJMSz3vnln78zszGJAhQXWsP1Wt02ZVITBgETFSPY6rR2qB53dNjNOcDdKZMyx \
|
||||
xIrmTomVyNlkmy6H3qcccUqPG1/RuC/qr69hViHElGU2LWXF2onTwDc/0pCFgn3ywddE7o1n3ifY \
|
||||
C9c8jLG4tyk3JKmTS+lujCRcca6u949dcKzubMSME/GMWZY1Tv1sfep6Ep25qj2C+pwnr03PPI7G \
|
||||
81LZ2a2zOGtLetUXxxutu/fdG+5N99x9VcmYWS/uv+a+6L4hBb1rKKV/Jlr7AwJcMSYAeNqFfAt8 \
|
||||
E1Xa96RtZsYZjNowmKacSQWUqihXAQWvXBXkLiJUKFJoKQUCDUmaTJM0SZP0lubWJE3StITeuJcW \
|
||||
AaEiithqWQFhXVZ2hV2Wd3F1xd313ZM65f2+M0mLvO/3fb/v94PmMjPPec5znvM8/+dyIsLSUjCR \
|
||||
SCR+c3PxduHNs/GHsfjjovgTKfEnUuMZaXXDUqqGpX4/LG0Ln/tLpP+ueCT1ykMj6buPHB35Gp+O \
|
||||
DROJyIdGgDHZ46e++Apn2rVt84QJkyYkXmbPFV4mzZ6VeJk1NfHlq3PXTXx+Ino7acKriQsTn5+U \
|
||||
uPDac8qCzbO2K0t2bs4vUGVlb3gy681bO1Ubt2Ut2qhSbSx6r2h9nmpc1qQJE6Y+m/VqUVFW4r7i \
|
||||
rJ0bizfuVG/MezYxgTCaDLZRhItoEScqE9lEVaKTotOiv4l+Ev1bxKdgKekpI1IUKZNSXkl5M2VZ \
|
||||
yvqUTSmOlL0pR1K+TLmTAlOHpT6cmpG6IHV56tupjtSa1PrUj1I/Tf08FaaJ0oi0YWlZadPSXkmb \
|
||||
l7YwbU0al1aRFklrTjuQ9kHa6bTzaXfEKeIHxXLxKPF48RTxi+JXxavEGnGZuE7cKN4vPi0+K74u \
|
||||
vin+TvwP8b/Fv+A4rsCn4y/is/H5+DL8bTwHX48X4FvxnbgDr8WDeAMew9vwg/hJvBe/hF/F/4jf \
|
||||
xL/D/47/C/8F/19EGkESDxMjiJHEM8RzxMvEPGIBsYbYQOwk1ISeMBMVRC3hJQJEhGgi9hHvEx8Q \
|
||||
nxF9xFXiFvE3AhK/kCkkQQ4jHyaHk3Iyi8wmnyGnM/yU+FVxyG70cZmc0czZFfyUgas2XZ0uYsuI \
|
||||
2sJ1roizzul3BjxNrjb/IRKuxH0Fnu0etdPoNDnLXLpIWcQVdfkitgjJp0FEbxLe+uM++EDT5eis \
|
||||
A/wDrdmkBM5S755FNWlEZ6dQMA/OZva1+UIxRUe+2OreQXmdHrfC466mvFY3m98hDsV8bfvk+8xt \
|
||||
XIw93CEeuuIut6wE5YpN+eKQaruvKLNou5lTKTYdFg9esJY7LMeBp5w9vEnMqczbi+RFvu0hFZu/ \
|
||||
SXzv0r3hOg6LuVibeV/mTTiOWU1HDUEtzYRitc3lreVtXFNxUFW/o1ZZrrRq9KXFFkNtScgSsoRr \
|
||||
vSFPndftd5J+p7/SZ/Vb3ZYak9NUabKa+WH8UpnDXmGzyW3VNqeNLXP5bP5M+CgeDgbDYUNQr3gR \
|
||||
DzfHDkX3+SP+Bn8DST9NzQa01mDQ0tqgIUobXGUOi3nSZJmt3GG1yC1Oq8vG2lwehzfT63G63Ipa \
|
||||
Z21trcvj8dX5/ST9DEilTeXlZsPgeF7OW+oxBFT1Oz0mq5Hbbii2lpo5s550WCttDjkdDQajLE08 \
|
||||
AZ4C9FThTw/M6qG7NR/7OztI1/OUzYVEPAfQeBZFMy9Ql/isIxQdo/gVTVR8ZNol/sYRCq54m5LA \
|
||||
08RHRR+saWTXNK4w0S1t8kvwJWIFdWc1ResMBh19qpyy2SjdZDB7ydJZLK0NGSK0sPABMO/CtOlz \
|
||||
501ju6hpF+d92wx46wh4O4fiby+m6Ea9N0Pv0ZZb9Hwqv1PGp8KdlrDGzVkz9BarxsvRqqg2Ngaw \
|
||||
tBqUL6Dc5Wy5ewnldiuijW3uVhPZbIoUb5fTcABmMzbw7cUL11l+3GTGQin2glOdXd2lFMvfVlK0 \
|
||||
sqIH3n6NorfgulKDTldfGlFU6/Ayu9XsQLIZBeg51Bw+69LbFD0enrOHdD69PUNvM+tcevjAQKYs \
|
||||
nx8mLjIrtUWZ7wBdvSHc3uKLxBSxSHi3t43eQq3Z0NmNyIwDtD5oCMcaSlSshtCa9Fobq7XpvKaw \
|
||||
JaSv5SycxV7iNcTyTmiPB8hj/r2dJ+S0SqtV0S9S5QqNZlu5Ei1vyOONWMPWkM6rt5JFBu3WQvka \
|
||||
YhPF7sffAJUNuK/W7XOxCanQEUNQRxctJfytDcfDnb7ddbG6ZrK6ttpZKw+W+4wulvMgIXKTeKXM \
|
||||
bq42u80kHamvj0RKgzoFvRQsoxR0CBTl0fHcsdRAbjVIvhLTLsy7ThvcZn85GzI3ur3hC/Ahmbuu \
|
||||
qq7cL6hRJCToE1pL4bZZS5fOonk9sQnAM0RyUJp5D/R9fOY359/6eIGCn59WoGw5dKi15dCBth0F \
|
||||
Bdt3FCpoFuaMB/xMyMFsnP4ARJ3+oD9UEeE2g/JOMHEO7TRnmq2Octpq0Xn0Hg7xNx7xtZgSXmk9 \
|
||||
Wj8aDouPcYXNEb0rQ19LV5orLDVoS7plmpDKtdO+0641cGqLwVkSNActDU5fkK7w2LzlskYuZmuu \
|
||||
ba6NBkNNdJ3H5/V5QoGGelp6O4uS/sRnw4IQRasiulgJxdLGOxNlQWNjVSAUCNIwpwrQr698643X \
|
||||
z6z8Df0yktz7wO/zm6OlIaPP6rPUWQPmSI0/gNgrsWmdGifnN0UsoZKhVeeihfvUndaEfgh2gaVt \
|
||||
NeVOK2t2+2yBTB3abXi4gx7cO05A+ydekrls1hprppVmolxQx/LWPeAJoIDWGFBIYpFIjFYWcwXO \
|
||||
Tc78CCJ9+3VZxOjTV2tqNFYdV0rD2X20BkxB+6bc6rAeB2564GIpoIldgH4cKAbGPA3iY2op2lJo \
|
||||
2WIp5Jbr5nBLuM/0l7izlgOW/eYD9J8Lv1nUy/YsnnFgSubUFwoXL1YsWlQ4c4qcXr0hbw19Bw/X \
|
||||
lyNq8wG9H5R7dlAep5uGM8cDuoqyKmjRpWxAG4OaGoNRUBiWlvscHlrn5zL8hqgj6G9tkoX8kfqA \
|
||||
L2CmZ1JwSQ1D893ErM+WfsXSeirkoy+fO3eZtiI1oDdSmzaRdCuYe2H6tHnIhCwBtNllyuRz8Pco \
|
||||
BXwap5kDVCwajSGtmw32omWJy1+n6NXUUjTqDmBBy7gHKOijYOX+HFpz1t/RQdJ9sKCPRntAT0co \
|
||||
VjKkhsTlJedm035tpclI54Zy9xXBKfx0WVRbt8OhTJqXVkCbjNXagAnpBS3oKWeqoIm8IprYsGNz \
|
||||
nonNM22IaA6ZQ7QpoK02nAA0d3DxV9t+00BeiJ747KKcXkK5aHPDboqu6oOcC9A1VhfSWBoX9hON \
|
||||
Pw7oDYhb0YW+VHovuE5rAoaMANdYQ9FffXbusgKu8KEZwdsEzTmD5lBmKOAL1Sro7cDK0pzLZ0Hf \
|
||||
+L0hp4LusHXUtbW2NYcOOTrp+FW0YXquXUs/17P41rVbi3vosZTEGiz1cA6SRh5LQYfrgxGazyFo \
|
||||
5l1ABx0NBh9tlpudVto0dqLM6EP2GQRN9GrlSrLCVmmzy2kMm4BNwiZjU7DnsKnYNGw69jz2AjYD \
|
||||
G489iz2DjcOexp7CnsSysbHYE9jj2BhsNDYKW4m9ja3C3sFWY2uwt7AV2HJsGbYUW4ItxhZhb2IL \
|
||||
sQXYG9jr2HxsHjYXm4PNxmZhr2GPYOmYFBuOMdgI7FFMhmVgcuwh7DHsPPYNdhg7iH2IfYFJsN9j \
|
||||
V7Fr2B+w32Ft2G+xK9hl7GvsEuZGuNaOebFvsT9h17Eb2J+xGHYR+wr7EruAubDfYJ9jvVifyIHd \
|
||||
xHzYCew49gF2DDuJHcW6sPexTuwIVol1YAewQ9h+zImdwk5j3dhHWA32MfYp9gl2FjuHfYaFsAas \
|
||||
HtuHtWBZWAqmx3IxFabGNmMaLBXbhb2KkVgBthMbiWViD2IlmBYrxIqwLdha7CWMwh7AZmI5WLmo \
|
||||
ArOIKjEOK8UApsBYrB1rxCJYAHsZG4btxpqwd7EXsYdFVdgrWAW2HRNj67H3RNVYnqgGIzAa02E4 \
|
||||
loYVi5yYEtuBncF6sD9if8GqMY+oFtuDRbEw5seasb1YFVaLbRK5sInYOiwfuy7A5TTsYST8egSZ \
|
||||
p4pWiw6kPJAyPyU/xZ9yHcHgbakdqT+nSRDsNaS1pHWnfSeWIVi7QewQf46PwpX4MfzfCICuIWxE \
|
||||
jLhM/J3gyZHkPNJBfkreekD6wPIHbA+ceOAyRVHPUa9T71IV1L/o2fSxYdiwF4b5hn37oOLBcQ9+ \
|
||||
J1kjsUk+lfzHQ9KHljy0+qGyh9of+ubhhx7e8fA3jzz4yIpH9I+0PXLtkX888vMjMF2ZHkj/OP1H \
|
||||
6ZPSxdIq6cfSn4fnDW9i5jJVTDfz9xFPjTg04tajUx7Nf/TIo9/KUmVbZHtlP2Y8k7E247z8Wflq \
|
||||
ebm8XX42c3Lmgkx7ZkcmP9IwsnXkNQDAXGAGbSzOLmL/rdiu+FPWG1mFWV9n/fzYuMfmPJbzWO1j \
|
||||
nY9dGfXQqImj3hyVM8o6Kjrqg1E3RpOjR46ePPrl0XWjvxiTNUY9Jjrm7uNjHy953PX47x7/1xP4 \
|
||||
E2ufeP+JS2MfGfvSWNPYPWP/lT0pe1b2mmxtdlP259nXs39+kngy88krT6meuvbU356e8/R343Y/ \
|
||||
88Az3DMfPjv52bJn/z5+9Hjt+NsTwISVE/ZP+HHiqxOtE3+c9OqkdZOKJxkn7ZmcMvmNKelTOqb8 \
|
||||
+blnnpvJ50vsffGgm4K31dSbVC51Ns4xS0A47KwNsSdm+rhGW8ibEfK5G82hd7+R7WuLdp2QC/cm \
|
||||
zCccd5PZRSkE5AVvm5H5g+3IGEWpOBl/hTmrRmBpGD6VUgxceQ3A6j8S3/MBj67BHPZkRDy+Bmt4 \
|
||||
PKyWnY0d+bhPLoCsyZC7iSNqy5sRITW0fsPs0u20KV1K166wIWYOa1wcwqE2rVcfyzuiPG4+SdWe \
|
||||
IJ0n9MeL9vNT4POykqglVtNS0+pvago1hfe4WmwttsbSoMqrocI+F+Jf1VnQnOsjc33rygqUBcpd \
|
||||
eY51dj+o2G7cpdKRElVEHb/Sl94GVy7oWwBXSm/AK/0PM3wQf4KSXvz7wFF8HIgf/Tsh7bVTTUhk \
|
||||
VzWiHhSFPIwseWECuyTAYiElODTkJyQnImrRwfj3DERRkNhQGygTjGxd0KmAKE5yRcoadK4MXW1J \
|
||||
mV2nW6RbrF+qfLKQp7Sv7bpSBB9Q/qg/p+vR9dojJXU6u85WVuJCDMJTiOSR+A8MzEIk94Hg2fqz \
|
||||
wU+abrdDIno1+lIzT+x5Nriifnn9cnIfgFnxq7VRU1hXi0bRme3arRQZsZV59ZmcoYxzKLZS9miJ \
|
||||
DxG3l+lrtaQkerKSCVkaPd4wfBDaZPBB3ubVR61hb0bY60av/GjYKYMZMOoJlU8HMIOPyvjRfKcF \
|
||||
Ye2wJUNSiViDL/alwhfhFYY/8TSAJwgIYKs3ZJ0OSIm2qi/u6hN17WfywcdQdgY+tPfygW8O3yCr \
|
||||
XdW1Tvk71NZZhS8WTCUr7JV2u1xy9UIfLOpLjT/qYELOumBIHr+KkORCYtPV5ZBYe1v5ifJT5adH \
|
||||
AOcoM3DygasIfCwkOl76hCdOPNu6onVZ2zKPod4SqkUiewDxhYj5+lLv2BnBMyrirxOxVc1vRzf4 \
|
||||
VX5V3S7S6Korr88M+twBj6Jutz/mj0W79ny05zQ58PpiEL9KhMqCnJPlnKVWq0G3SZevK9i2ZMts \
|
||||
7Xuao1sube/RHdId1nX8ykopkKxAc72iaQF3RjRQ8aO4ALYeB+zAFXSpAXnjeMb7KLSFf4Tj4TZ/ \
|
||||
yBHl/BmcX+swcfxavkMGGxA0vYp2y3ri7O/hGP5Dz9AieKKWMCmZk9Q8uB6JendC9Yp0W5Ucaynl \
|
||||
7GhpuVqvQaH3acvRRuFcmrCZNMRarK2ZrS2eYExxsrX9w0/kEn5dRN0vEzi0M0IwpzgEBq4SUwEr \
|
||||
6Yio4Zk+eEAjuoBUuzf+M8NX87Nh9SBPTXA23/QaOAQkPruwQOln+34Hpy/ok/6UNBrNAE6ppcYK \
|
||||
G+b2BX44/irYC7paD3b62U5/ly5aoB/chx5qvvbdJXPlktwmNex2gfQLaMM5pD/dGZFgB0ZgNrEW \
|
||||
CHbjYoKttdSF+E8M+iCEtyvAWiDEugpJs6BUUQoqhW067FUKDsM3IBB3A5mdm/w4hr+B7MjkuCth \
|
||||
UyQlZwXlrGZ+U/JV+8Eeb8jWyPk4r8Zm5jZT6ygPNU+7FnHURc09seSClhVoQw4hu2hiaCVI0j7b \
|
||||
Th1OGLUaAK0DWcxyJZUwWqVo2Pa0fOFTQeKTpIWKL9SI4k8fzgKmmp54lkb0eTaAK2qYO/gKKp61 \
|
||||
DQykzCE2ANi9DfDdTZSkMKoWHY5PY+CwgTFiY23AHMwMIjxbq1gNdGYbV8inyrQLVa/ol+vO7vpa \
|
||||
+0UhTJXZUFSJFh0FlbV6pOmZiEJn/HnmDiJwAPgOePd7D4TOhi+GekKLI3NDy72F3i3eQvIAuIOQ \
|
||||
etgc1guGQV9m1xcDMuQweblMzmzhbIpiYA/r6/R2vWAYEOHcj2uY0DHqBpwg+xM/gaMyQl4XikRG \
|
||||
w2WyO/B1JMgGzpvBeUtsFu55Plv2AsxGYYqLs2RwFhuKU+7wr8tG88ssnEsXQnZiM7+2R/Qhv5ZJ \
|
||||
Rry7w+HdvvYjcLhMmKedG8+fk02A52wh/f8zYEY4XbKkpgfe6BG9v58pT6QszC4h6oE5eBdwg/1U \
|
||||
c3frGdKJLItL7qpwO1ysz2YHJZvXTtrwkurdnSeBJAtF73/pgbmaOoqP4ssoVvqXedR8oJD+hJYk \
|
||||
eom493EOfA2fD1jp7SlAwb/2DiH9SRj+Vbj2a2YjOAhIR2fJ/qLYs+dler85VBldRZH5rnyTcmcR \
|
||||
snmj91CiSz2pdyoYtOIpl4hAwFHuV4TMDS5vyBuyRzgf6Ver3apMD+D419UwV5iTCVziX8MnUPHb \
|
||||
hBuwY/GJ913TgztIcF0oZnvtEtEOxjqpgdvvUyx8KR5j+BUdFLxxCZ9DSWYCuKSCSaL8HB9AkctK \
|
||||
io2PSXuFMpkogR1EIZ/yALjURMGsnuHT4Yg4K/iUFDRuPsWfQXSziAkUshP9T2hEX/akQklCBXyJ \
|
||||
tSY5X1koKo+3PUUNtBF5u/MPaFiJSrgTTRb+iIxbOtRBCRzpD1RGjf4MQx3gZ/CLZfFU4i1q4AdE \
|
||||
GI4mTp2BBJ9/T5lICf82Uoz+mdfSd8Epi3uQ78XihxghKh1DKcbe1TIWoIg7NGglLr6Dwk3HQvTu \
|
||||
RjJ1opB0UvGOawlR//rM3gEPEx+DWByzjZKY9lBorZH4hpZiDsV3b6Ng92qKTa7wO8hA/0AI5FiJ \
|
||||
tmZwIV7Ft+t3KE2s0rTNrWkk3eVCWqXcJuTUUETjLmc7N31s6m4kuxv3nTwjj1s1yQXLQqON6amj \
|
||||
kDwXUvOQ6FPuV6jf4i9QyU8x6tUhhSqAq3tg1msUZL1MdzKsnP5rCkfp108WlhFFnftyujXsh5VA \
|
||||
wiWYRLMygTtI6xVIX96i+NfmEBPBKyg4gzrpKwKxZ4GVai9vVJM29wlK+oqQnXOzeR1v+VdryNWa \
|
||||
opyV8iGiv1JEchLMVDsQRPNWUsf2xkcygnIJaoZL5lJohUPMHHwBeAHwWfzqCUCSS8E8OyNgIAWK \
|
||||
Kq+j+PpNSsAEOcjsyuMbmd/8RjxQlXSo1jqDizXWllaYhWTnMJkWuBWSqj7R7+IRRkgQ+UL+xob6 \
|
||||
mCfm3u1oMjWZ6ks8Ko+qYpdJzW8aGCMrL6syeUykkBYNZkLVDIp/GY8e/uDm+9f2nGzpbjsT7ajt \
|
||||
NHaaOnfsK4gWRDe4UBxdtlWl3mTm3JqQGVnK7j4RjCG21n/BDMXYCFpaOHO5xtcAetqpLuLi2s/m \
|
||||
Rdn50blFBUuSzyUZa6M27ACPgydAKcUuHozTJXaYKyDG3HRoQy9jpEt+C0cycCaP4VKXkCWVLoHY \
|
||||
KULqyKKkrjUQfTthFKLBSl08xj9M1B3c/2P7f0TORM9FvyCra6qdLjmSEOdidR6dyarnswYWyhym \
|
||||
arPHTEqXmD1euz9TEr/YJ/qqD07pS/0b7GJC9nq3J9hG8SlhkJyITeNtADBlcBp5dZvsBVoSzoez \
|
||||
iSyKz6sBfCfB+YwhO+K9DyF20Xnk7bfaGeTh7qipwm1m7Q4WkkRXS9J1H0Wu2wzc9znuJaCAipvg \
|
||||
mAV96Wf6pE034qYkkJDmnoIzCUvBFl6+hX+k5DXNC+rJpKOywiHn6gwhBxuxR+pqIwiaXpE5fRV1 \
|
||||
Vh/ptVpqyzJ5qxAlzCCkTYK7RzyZELxwUz1Et+pYQRt7qC12rFvepaYSWd8NxOpY7uHtbP52Ve5q \
|
||||
+WJCyAEjP7+K6cqhNqA4ZDZvZRYvpnpyKIlAB03vJJreGmhiDrb7os0KngwDrUufEJOPO7T4wtYL \
|
||||
UfLLRE5FiGsSY4xNUC2g+Hz7ddHH11M/PjIZUbvLv9EDH34GwIs9os974DC0Z7NB/D/jR5meRTMP \
|
||||
TsmcOmPz4kWKxYs2z5gq5+cTUw7O7FnELu69VngjE6bg86iwoV6n4FPwuW+0dq9WrOre0feVHM4n \
|
||||
LracP93Nnu4+33Ix86u+Hau6Fd2rW9+YK+cXIZvehH+05eTqKLsmuqJs0yayfAHlEnLWJ6jGxnYh \
|
||||
Yd1qChcr5fPmELOXLJktpLyQ0ceRtYSLiBuF1xb3snzPwAS0P1fVIL5tpy6fSt/b40Yvm3uk/wUj \
|
||||
8RvMyU0dOTmbNuXkdGw6ebKj4yRCNyMaw+HGxrBeo9EL/8ONrPTun/hvEhv+Dh4JbqTyE5wI2XPX \
|
||||
YPZ8r7tZYCZUvF0+aBESKfLDQPoDzI5/zYyhtgAWThmReK0bWMmsB4cpfsQcRvrPxymElipPXzwt \
|
||||
go+iv6nwk/525uTGI2tyNm5EbOWdOnWkM8FWNBSKRsOcVqvXa7VcOMrCXXetWQA9feC66Lvrv7ue \
|
||||
Crv7VYyQvzuAgtIp1ysA3HO3OQsIEW7f99cRXt2M7trcJ/3nDIEvSf97jDaZ7uOnjBh8l5RU+zUk \
|
||||
p63XbvVIf75n64QsZTCieIxKThC5zWXMOsAP28BIfxh0OxIUaYjgADxaCJAbJuIBZj41cY7MaK4o \
|
||||
8Rn8xkhFwEcu4xczh6n16PlLzCsUuo2Mhxi/MVoZqKSEVJ/xBCAvD0QEl7ceDLludBsV/ydzZ2LA \
|
||||
FK32BzKSznXsLZmxDhiN1dqgiYQ5AzvvSfVx4QlJ/CTj8nlqfdW+am8O8AXtDQafwVviMBvsFqut \
|
||||
bA0g4aqBF+57SEAIMIoGspmtdvOveXB1SOUqtu+0awylarOh9l4evNbrcQnUfTnAewxwXj0iTR4c \
|
||||
+DmBUrp9gI1QXYAdcrnIkQjo5Cs4nIE5xHnu86JPWVPU1GCItDbIgr7aBjOiW+I0WDarZCWRklBJ \
|
||||
gPOV2M0GM5cYEY3pNxWoZAazo8SLJtLgCHqPtcsad4S3B7aS7lK9U5cZo4amkkQFmmt1PXXXhk9v \
|
||||
/BUaICUcfMen8CnMwBgESeJjkPtEQKI/XSP6qifViDxRcrXeBQGf39xwLysfNIdr/AG/kNlcQxnN \
|
||||
9hK/IQOOHjAxCQoJWoiMAEYuxV+5jzYCREomSBl8lLDSwUqKHLwNPiOs/tBqIrAUBMHEEpPTJzIC \
|
||||
ehFQzCBAQJvp53PwD4wTIIf9XEKBpP98GWnyBjh/cIMhZRxSRSSAXM2vnAxS4vOFfzphb/aIvsgG \
|
||||
XyB6R0GJU+fh2LUvJyuUGcFj1P6PZZpYW9n+TMGW5BBhR9gaYU9c9aCZI7xv8JQ4LNyWt2SNqu11 \
|
||||
W5DU4Qg+xuzSecMGBZrqRjE/DUE0eDutKWLR1yt4Cb9RDKe9jaBYTU8iEpoaDzJ3bgX91VFTICMC \
|
||||
EurvJ/cO+JlxVBm4d9uw/pGMIJCG6kBAEJJhUOXJy3fl9+6Mf5WMrobFA3nAj5TceG9p/MZwRdBH \
|
||||
Lp3ClIFxidHjymvpnw9mr6VXLyPLtA5FrSPWgQ0DVwaDMwFm/kWAmYMh2lPCOInABaYNblW0gBFA \
|
||||
XhkYwbwCktGLHkVppCQB1nME2cIcBKSQVF5h4EuXiIQQE2jzJYQ2pwD27tH3E9jwyzQBVm2n5uDC \
|
||||
GiPDM1czk4IKL/McSBQZ0EJ3V4JZ8IE8tH0rhJkJ2o9m5jM2CDP7FToeOMxMo06h22vBePhfr1OX \
|
||||
4FRm7C0kq4wgSBqNQEKApGSWABD1UhNk4yuYNZotCAU6AXrS7fBUeCrIzYTWrNeb2WSdiaPIQ42N \
|
||||
HZ3yg0Szp9EfiZDSV6ZTNoWB01tLMivxStxqrnGWKazU3gTOdAk40/08Ve5mN3UsF3DmryyiaZ1K \
|
||||
ottpVHJie6GLGTvR6KMykhpw55YsqRPGQEm1wYTAGitIRQT1aH3rTzBBXcTYaHkWIEg8WDBGhuaO \
|
||||
D2zIL9lWzBoiuoDau6ZxuUnwlOUOq1kofiMvZXNHgUvR2LR30GPu2C6fM4dYmbNljUahXl23vHNT \
|
||||
x6azplONTd5IIBgh98LNzCUv1bmvKI+dQ/BX+PmMpqm83d9Ktvqbw+2Zl+bciwy2CpGBAIinCJg5 \
|
||||
Ekz4B+SNFwCYk3aJz5qDv4zo7OtUwPT4BCZpexO2dQ24zzIj20nej6r/h6e5HLcxE+cknUhG0i7N \
|
||||
pxIPHNvPDA6XiAL4nDsTQE98ONpageTWSpicgLGhMugfYvMF8H/j7xb8BakLsj8ZpoQ7uTNRltSa \
|
||||
pG0iJc0VPemXenrgfCE8i+Mwm4FTiLNFJ9e2so1NgRbnXrLaWeVyyY/tOpq/h93Q+o4zV0Xmqnas \
|
||||
WyMfcAhm0EG01u+OBdlYoKUyxjVxQZVD6VDqNcUmrVVmsFqMTo7knAFzKFN68XRn3irkwIlVeXmr \
|
||||
UKT3HvXtl19+q0hsQhQkis5fu3YtFZ4bghV8zj2rd+luJoM2ZHI/TuDPyV5BkoXPI3OXhdToXOJl \
|
||||
OPLP/z9Vai/Ob9iA7NpKqutwQ/se9g78z9cpPoe/jTxLIn+mvS7add3d576O4ued/VEH4NeuH0Ie \
|
||||
11DAmsDDibSlkBNMPHJd0wJgYf8Gxh9yRAybgVUo+hlMjmQhM+II+X0er8fnCfkb6pHXaQQhU8Tp \
|
||||
D5L8E3wqk8hyXu0AAiVE5uV+p7BcAU2F0ZBhNFRpQrmgotEQIPPu7mSSwz6dHLYFXIj/PPj4WGo9 \
|
||||
FDGJMmAwUNNoDIaRGg0mW2/3S5mhLOZryYTq2aGEautQQjWZjT0EErnYFUO52O2fHgFd/2AQu7X+ \
|
||||
0GzKshtoQzvcxXYlwguGXSbkvYW4q6AJ3LkupPq+ewY6Xv1O2g9l8YtMiEok8wYuEk+AFUD6TxQk \
|
||||
9fPZ+H/Gp06mECibh2zxf44BCuFpuE4zmCmMwxv7k1VsL3KJoyhpXKi1T0QevbJ/FuMXkEGyKJwQ \
|
||||
5FtgUMiStdT9D94eNVikFx7M7UcOaWLQ2FTlD2UEgpVIloI/TgjYaKjWBI2k8LjA8kRKoNBIDRHA \
|
||||
v0fxz9iJBmNlGwgGqpFYTUF1jQE9YBaSjjOrmcrqmqrqTPSnslqxmdCZ9ZyZRQqq9el9XNQW8iET \
|
||||
u7ujC5nYLt/h5lhnXUTmC9ui6KJPazPry3SyzVSdTubTC/eGfa6oOVwWkQnB2L2c5ZdaVgILq/ou \
|
||||
933vAunwYlJM8YcRuyWAL8e5snKDTcH7B65YhYy9NSNsjXq84Vq/y+8O+Jrq94YPk3DhaHyqsAg/ \
|
||||
ZyUkii/gpzD8ePwsZK7ASS29pKSFEsFx/WXMbMq6G2gSayxgQm6XmatBa5xUABJ6774roPJ+qUYE \
|
||||
3+m/wiS03Agiu6mkRv+q/3DT3Q7hVhEc1X+LuU+P78mehA13P07eUtF/G4mZM1a1gVCgKkCRcOrd \
|
||||
T7MAfKuqL0cNz7hArSb97CxKmLlaSEYc2FeHwj3pMc4ZLAtlNlD/wuFwmE1I30fLdgytO4b/C0Wr \
|
||||
o9C2xpM1Eem26M6iusJMobSlWIJw69W0UkqhIfgzhKYaJBuA2ES5rG8aCMV/wxiosRNlaN01AQMp \
|
||||
yU12Jg22FTQDoaQlNPIokr1JzRT7av9exiToUi64p19qYY5JmnCNZhqIxL9gWpuS7QwZgbcAZ6r4 \
|
||||
tdFBGGQG4Mn+fOYg5fJ6ar3V3mpP5WAvSkv5ntrm2sZgaLcvVNHA+Ti/zm7ibNZym6XSUoF2JULx \
|
||||
7h2DK0ZKYolBRb1TqPjT/dOYZAp3w6uyfds3NK5NyqCLKq02Ok3sEh6zcC4tQoYhS4PLF+r6rayo \
|
||||
9ajmROYGoS/KXxF0BNkeiHlD5VEEDvmV2cyhds22kIKfwfeIYRORENxAMK1gW2M7p4AzYI+Yb1JS \
|
||||
kiZ7n1BEi2PIm7wpiOx1NHsECxO2KSNMIUtVFQyQQ/fBgkSO4k3AftXvud/8CdsTOayQMVoVCPkT \
|
||||
mzfxUH9jokjXIxjAXCLZLLYKAQn4LDPxkniwH6a8HhgBQvimVrUMIc0h/fQnKUy/nt4zFDX+ZZCB \
|
||||
VWCQGiu9eqQ/tpS6V/16Nz6GeYnitnHbDcrinB0rtPnkdvhlYkqCXcjgwKDC+A0BLloVQmxWJp3J \
|
||||
74ecyfn+FGb9NFXOdvRwxksU+SqcsJQ6UtUHS3thYV+6E44Skk3TrvZJ//aH+E8MX7mGkP5TSIWW \
|
||||
hhXSv53iG9AeZu8rhSQrsNDKDxusiMDSC7j0P95AtnYeLEwWRxx2WLhAyLosgMvSL8yipAegMu5h \
|
||||
Jn+HSyP36leLgbQIUjeJRI6vJ5HiY/kzaZOhKVHyWIzWEzbC02rY3ZveCp9b1LsIPvdZL1T0Sv8j \
|
||||
/kQ/zpj9xlqDnUShp9EgR1vqDQquJ/x6P+c1uqy1Vlc5KWS36jLrvLU+j6LW7fK4PN4AWs8wya8X \
|
||||
7j5DBM0BYy1bWmu0m00oLDSYjZyqZCen4RpLmrmYOSDEiCRfwf+DEfrSFLDhIiH98g2ANrj0P/yU \
|
||||
9OtLSDqbhCr1BUdvPNwr6uyFT/bCz3tT4Z34fKbJEzP5tT6uAVnZkNfVYA7tPLZq9xoDucawOXeV \
|
||||
nM8iVh3MPWVgTxlONzUfT2bDUYBqM3Mmrcqk9pAqT2lDTA6ziFh9Q8zDwj/xFKMCKor/LR9kdlLF \
|
||||
VHJguvfbxNCTe38UxJMK34cgyfDPB4mL/DCv4BOEmnttgyW09B+yjmjz4ePy3lXdi9kZOIpL+G5C \
|
||||
WG0WjoBVjHKXaju7+sduvG33LqVi4OHXGRWlAvAKDDDF1E5K8q79etXvRFCGlHNb/BOmkfMXO3fW \
|
||||
KC27tNpVq2Tbt+k3bpDPeA1cI/b4miIR9sPT+/aFjzmOZziO7eoqaC1oXVeXa841F+xU5QkFxZA5 \
|
||||
bI66faFgrLG+xdXi2mNr0pPGgYhDwBr26/GOZFVxEAdtif8FBZ4ITIwZjxiBZ35XdV10tO/E9VT4 \
|
||||
lODe3xm4wBxSHi875jvmPdwS60QSbdQninIWzqDaVVps22ErdqnD6rCxqbKVrGj17o5GPzwta28P \
|
||||
HemSXxtPzSBUFrWuhF21qqiIy3Wuy3DmNm04pCQRL/xodbzjOmImnlsB+ClpQjExwUktCoHHwgXn \
|
||||
/nhOtPfTbz9NhcPjjzBvrXt35fJjuZ+cPXbs7JncD5Yr+Kw0VUlDLNaA/kdLVCptiUohKYr0irpv \
|
||||
//l26l9fZt6lWik44SzTSr1LSbbEdw1egWfjV5m5gJ8/Yi6QFMUv9Yo+FL6+ED/APEttwf1UjQ4v \
|
||||
swlNonDqBQap4r3P6LKTkqyKK+F0UV/f92i5fP3DmceBYuzT4E4txa/YwgjvEAAs+L0GDZYK037P \
|
||||
vAj0bwOkJB5yX7Bx7wH5KaFohOL7eKU6cctDiJvwYP8niuWE/k9Nov9TaFhl96Mooz7iBoqKoTZQ \
|
||||
9Gi/JEFd4Pj/pG0U8geDLAqSczF3iEH7MHYxUoF8+GMyXRqXTU7cOuw6EkCC1f82+WcpPTw9pCUS \
|
||||
IckKuxMPQvZIBbU+/gIzGyxKXEFzRQQuaP6n+CTwVft10QfXISn8G668eS35CLStr6AgOULoZ92H \
|
||||
dnoYWuBMZhFYAElZog/YTD4pLM//+AbdF4+PY56jnkSS5puYJ6nnEP/T4WLYw6Abk/dlPAkWoWgC \
|
||||
fT178F6kStOQizhOSS9+D6sZXkko1WolCliEEkHv6dO9CqgkWpuaWllpLwIdN5TqplYhm9K76vQi \
|
||||
4RZWerG1Sa1UHAWF/h271ewutWlHoRxRndHXP6EvfU+iuH4DTujPZcYmujWlFy/cnTAPTw6guBMD \
|
||||
in5lYgXQ0slhNlqUAvgH5ivTBdV5VvWbws/XnjOFtNWcCeEvrZ/rWrV3edNisnFJ3aKF8oVlizRL \
|
||||
WPXircs3rDJxThTyhYR4L3T87MHPYxfI2Hn/ha8QK5kChC3vn4CClooo5+eEjkZu3bLCRap5pOoN \
|
||||
07zZ8tn+ebE32N3zD7x5Ypmfi1aG/CF/TdQU2nB661l1D6n5rKz3C/kXdb2Nn7FNPXvPdp0m701Q \
|
||||
QPPTpRfvzGDujAfSG/P6JyDXdDGLGlsD7iqFsAmJF2FZ2I0kfBtOQVJHwkvK8y9CgDUKLFq1ahES \
|
||||
X1LsPyWkIr2dkClajEWnV/WiO4Ve3KTklcQ+Q7u6kW1qDLbvk0t+6EEAVYnmp2xjFhFaS6mQ9Ug0 \
|
||||
GCXangRY3oRgeW8H+AGu7E9jim27Sjm1GQkrZAqZo05/yOl21/qcvmpPhVvAYE1crLy1ttXVWF/f \
|
||||
5E+2GPi1NhNnLy+3IwRWaU1iMKWdlPwg5Kzh8ETS+mj860Sw8zyQ/NA/HPE0P17HoFjQLcSCyb7W \
|
||||
CMInPquv3GdNrlJyNYSm3vIEiLHWA60AExPyR9Th1/HPEghJwJcZ94FO4dr+/qxkvCI0hRpQCAh/ \
|
||||
+JJxeZwej9xn91k8bFHL1j3KWE7nyuO7orujZ46f7GyN7d2zr4UUIGed3ONw2zxsUrN4K58js1rt \
|
||||
ZrPcVGvxlLMIaeQgHmv8wQxJ303GXCOcPggYGiuCfmiFOTKvu9brHxyHR18Y/JpKI5dhs1UIddVa \
|
||||
s8fK7t+xt7hVdWrDh7l7tMXad3LXbFCqthZv2UEmx5FsBd/3ieAfoJXhrfgTlI6CU9IG30ngHDWM \
|
||||
IBFej49ndOClF1/6vVgH9oPfo3diLfAorv7+6oviwRZjj8JdRpV72BfRl+LkWwmyJmf7zqKleeH6 \
|
||||
8BvwBTiJUTVo9zxNFZdoVez7cFvCammRoRk3uRCgeKuISj9bREl74R/6ktxAKy79JIuCvjRp7+Sb \
|
||||
uNSXTUk/nTyZkLY/QUmbb07Gpb3jgLT95k1C+omdgiPhwgV96bC7T5qLZnRlkEYeuq1pHIDDkLtK \
|
||||
qMRX8WwGwduaQLChqaEpEm0/sP9ItDGiObixvTCibVA3qAOGaEUoIOBMU5CfBOfLPOVCaa3MYreW \
|
||||
K/hJ/PyEEhgzJHDkIM+uxIACj9mDRlzqEBhdktxG8wVeXYP9+dIlAsPWUZRkYnx0PSU6Uk+lwvZ4 \
|
||||
aDkllO4XqH/p1ogu96X+CyKgA+I/pO0Ev35/Fe0wUf9PgjP7L+5p8AuHJgV/qURT7c+2hnV1OmuG \
|
||||
3lqm8+ig9W62LNkgGPH4ItYI0sy/9r/A6D0lZVY9L1y1otvDVnTJ54lA9LzMEzFHdB6k1f25faK4 \
|
||||
o7+JGXAkTGXcMQPJjh8jfDvjv30Z/y5RpfGl/cKNB//FIXmjPeET7kPiGHCgz3EHbqdU6v4CTfrX \
|
||||
fXv71vQd7JP+AD+Apxg+/Z9iLdr7zfLKPb7GaJgMhsLuaGY17sadKLyvUTTbGwx+9TpKc2hLLM9H \
|
||||
fjTkH98mVDZNmY4rVJZsqM4lc6MbDyhZ+MgYtItV1cUZO8rUWj1r4EqsmsxK3IpXVFRVVyh21mqD \
|
||||
hth95WmOlP7clH9wZ5eFfHsxOE3EPI0+xMSBtujRY/LK4yVHC1pJyUJ1f5om/RayrQZe3ie9CFfF \
|
||||
Mxmnz1vjRXxW4w1hqyGoKHfftwXcrPS2Lqr2qTz3M2x12KqsDnK1esu7K+RHwYr973arWbfDXeGp \
|
||||
FEb/CI3e5ItESelFt7ua8qDdU0WVKwyGocSwxVLjNCNzrPRze9rkyHK3hfa0+llJorUq/bBQPkbO \
|
||||
7Se0b5bjoWZva7scPn2TyKImw2x8X2PrPi/b7t1vCCnXUUUfLWleokcDLePee3uxnM9GMc8NoS3z \
|
||||
FP80vklVWGBgOQTDnRypdyI/lgkPoPV7DCQ6MQdP7SSr9N/3pffA+UIAtURaAGfDkQyPEdKORJVe \
|
||||
CbG/EtJm5C06xn//V1x4NwuHD0BDsuPxAd4gW4BLO5Kbo/3609NwqTLxQQLfEwg3CBNaABfyC6EK \
|
||||
CV0Tv8QIbW+NBYOpm7AvNJS6KeiZt3eelkzmb5YKk0lSvXjq6TX4rx+W4snMzgXthb2HegazQpxP \
|
||||
P5QV0hRs0OX5yTz/joNd8nNofyZAxuTv4XBc+qnwlh9+Dk9W8SW34leQzv/jDvPF80knkZH00jN/ \
|
||||
kh2/nKSbwfk0drO+aJVs54GXf+z7474u10fqExnqE7ltq5yrnGuVxeuKc2vebn2PrKyuJKorL0ye \
|
||||
MVpZUJbnyc3w5O7efHjnIdX75qO+o/6DsVgHyY+A15ilvzU0VbYEYhnB2O5ga2VzZYwT2i4dSr2a \
|
||||
PMOfZ4pWle7SIqCfsdOmqtXUa0KljY499mb37lDTpVuy81PFEiGgvIvs+VwUJ1niTzLX1yQ7qDKS \
|
||||
8de0btn17mSwlpHoOzNPWyP7gRCOJE0B7FPE1FNChGbhMlD0UhKyXF8tm7ZaaEzzcRneRKB345Ts \
|
||||
KRRcSuKGynoKThVM26fwoU+PCX++EP6k9u+CZcsBfwbOR3+nxtczwkGk5JEkFiHJ+48iCUeTWBiH \
|
||||
NDN4BO3AwFVZskU2bIl6PGF4IH5V5g1bo5wX2bZl94asp95HBjX+Oixj3gPnk4ed3kgcdtrRcuhQ \
|
||||
i/AfjbBjR4GCfy6+fjkFIaRHU580qKFSCCJzNOlRIeL+UYi5pb/A2/EHmYu4tB8F+b/MhS/hg+Lg \
|
||||
X8qGLyVkw0r/LXS0vTSHkP6CAuN/X8qegw++45fiKNZe+iO/VIi5l6IIOkkGX/Qjk539IyG5+qY6 \
|
||||
PqUXzutNP4gG/AYN+ah0ID63X8LwTnz6/PnTp38571tF3QCD6PSLv7krJoTXTjQSisStixh+Xhmx \
|
||||
esPR7u6urm4FwkEjBb3sf4xZw23Os6wqHS97DVngL/ClA5RdWaIptmTstOx0a6OkDmwH5ezh/NPG \
|
||||
U6GT4YOd3tM98eGyy+PBm3jwj87WhsZmb8Yeb0t5VEuWJ45nut0KTxlldbMFh98O5OhJSWShOq5E \
|
||||
W7Q6/Rxyfxfht/EcZjIch0vbkY/u5cch33cRWZXemwNLhGbvJWhHfWqnItNg9YI+qL33YDu0xUcy \
|
||||
yG3GkK1oTxAQnHxzgkDSy/Na5DsL0Nu8m7xAH3n8AjgO0Us+gktQ/ANDjNC2ro1adte0ZtS0BJqa \
|
||||
wkLberOt2ba7NKBaR6k685tzfcl2dbJAqc6zr3P4gUNpKFbrhdb47S4lCsm5PZZEa3wyoZxsjSdP \
|
||||
Us4TtYnWeHJH/MtJ1GADNvwh/hPzDlWU7LautFXaHfJ88Al89DR8eLAju6a2urZW/gLUTqJehRqo \
|
||||
Yp49n2xuzFhFJZsbySKwEZAHQbL5kQzGn2KUas6oLTWZMxxUHsKTg/2Z8JP4TKa20uXwsL5yO9AW \
|
||||
5E7Z8KLq3R0nwWDbpjtxsjUHF9rh9lMtQttmTaJtk7fDd5k8SqmWJek6ENHtib5q0bcITVxAPmMm \
|
||||
rMBvnkYmtdESyki6yOWFMrhrLMWHiDcLku4yQ0/tbZDx5aUAjWKn+OeFPsW/9KTCN+KjmUKtGFZv \
|
||||
A/xhYmF+stiZwVEHojJ+HpHXmH9Iw4aOUd6Q/deeR1hIfHE45BXSMhnJs3ikxJGs+MbHCOXeM/G1 \
|
||||
jLCvziwEL1MsPLMNDPyQqPPCZYShKWZtyWzZ46lvUhhr68yhzBUUegrF63BXJWSXnlsKKWiDq5ee \
|
||||
S/8bHA5D6HOK1AmL4xKmkWgt26ONss9QUv8sAL/nyxnVPlw6VTgMrEf+lpX6XwfSlWaX0Bx2ZxUu \
|
||||
9W9CH0/HCGndvTPDT8Ydoyn4dmKkdEicg4cSA3RAIn6YWQbGgvjzA08IZO8RRSSVv5LsQCSVAsn2 \
|
||||
/0HyLec5EaKX+iuh2fyfRwNeFJ89muJfhGfUycvj+x9ixoJlQPIYPIye0MRLRgNJVnxBYsYQh8OX \
|
||||
nkMQeHO8gEHTdM0CQ5OWPAk/ErI1H6M/qXBe/4PMusBarSrv/sPU/nDEG7WRUZtfr5W/9x6xPDeR \
|
||||
zzmruJQ4NK2Am4gTWztz/ex83sgISR326PPv4UKGR5EgD3cO0X+m/xFGeFrBZxEChTMfHDvLwizi \
|
||||
zLsfrGT5A4mskELI8AmZIeFcLrpPVYJeJfBYXMrwabcMfks92ixRT6jez9YHwrURR4OjvsyHYsFo \
|
||||
eaJ802gOafdvbcz35Hs2mZTF5HYVV5Avr95at6NBrSkxqGzbzesiaw9tI6txmDZJXG/ylGrl1TqL \
|
||||
zmAqNertOmeJsxTpD6KCdF6f6GKLbtmrOWztKD/oa28m22KhQ5WHyXZzi3Y3G43Wx1ytvuO6E/lt \
|
||||
5Dp+DDOjr6TeGq2NZThDvmB93bUFsrDBu8uudnDmUoPQHvnY933wL32iLuFvanxy3Mvs/SjZLy8A \
|
||||
hHIzt/VtmX/7NvfWTJ4ZM4qXvnLwjU9yFVvfNuvdCBlnhMyNLl9470cyU1t7+d7MLz7dc/y44vjx \
|
||||
PZ9+If968/kVx1i+j1/A3P7669vRqKM8wvLP853i/H27TpyWwy6eZgoL8/Q5mZoSp1ungM/DTvHh \
|
||||
ot1rV8nXlqwv2sJKHBE1PJA4YpQ4EnDlaQCrbxJCa/69vnx+2P19+RI4AM8yCARUmBMT1Dl0Dr3T \
|
||||
4Df6ZMrGzb4t1gLbjhLttoOUrz7oizgjzrAjaAqYZW3qfdaD7v2u9mi0zRdyNHA+UvIYyMtbnUSU \
|
||||
uxCitLnia6vggiqcX1tFsE3Pb/hfwx7oo/roc+5hw865G4c9GJ8yPD6WOSpN/qrEA9iT2GRsFbYR \
|
||||
K8ZKMCNWjh3BjmNnsMsiVvSsaJJoumiOyC6qEtWKjoiOiXpEX4muir4V/Vn0V9GPKSBlVMqElOdS \
|
||||
nk95MWVrSnEKl1KW0piyJ2V/ytGUD1Iup3yb8ueU2ykDqaLUUalPpI5LnZj6XOrK1F2p+lRnqi+1 \
|
||||
KfVAalfqydQzqedSv0j9LvVO6s9p4rThaRPSXkqblbYgbVPa9rRdaSVpxrRg2pG0L9IupP027Vra \
|
||||
7bR/pcXTBsSpYlIsFT8qZsWjxU+KnxW/Jl4oXipeIc4XK8V6cZnYIa4V+8RBcYO4TXxY/L74lPi8 \
|
||||
+CvxVfGfxX8V/13cj4twEpfg6fijOIuPwrPxcfhE/AV8Pr4SX4NvwotxDq/APfd+sWI/fhjvwj/A \
|
||||
P8U/xy/hf0hmeRT0JLBpE2kbbH78vxzYF4JUIXBR/D+glzcJvTzh8qgeQa+YLqJS6XQq4Ww2vQE5 \
|
||||
h8Fuj+2UZCo1FY33ktChS48CUymW9ntcvoDchfyYizWHzSFrvWFPaZs14PEHmwMxT9Bb7w2RTme1 \
|
||||
yyOnNUIrOS3kCGLaqIpONhQ9Rf3aSkS73S5PrZf0hVyRiDxii5hD7D5dYbQgs2CLtkiruN+skUFf \
|
||||
wCMcG7MafApPaVWptZQ0mI1WLlMw0Aq6lRpKzSYwHU1kU/RCoeGOhjNnUHzOqxTMiQE64Z1LDMg7 \
|
||||
G30lQS5g9lg8Zg/n1zlMBhPn1AVNt+bIbC5PhSfT46lxuRS3LgX9zogplGEK6pyciZQwzwN6FpVK \
|
||||
B2w+k4dNnC/SL+BJmc1UVeYqu8A/JAQ45WEfSes4g5YW+oM0mq2DvesFgBb6gYRfhXiRoo9SXgOg \
|
||||
hZYTlsZHUbToXDagrcAinM9P/liD1q0XfqyhXOPl4Ei+VcafeO2+02SN3NDvO9B5Rfs66Tlonklv \
|
||||
m/M2JakBSkD3zKTovq2AdnncLqFA6q3w2AeTcy33CqSORIG0xG7mbBarXSiQ0oIGKGih/VO0FzEl \
|
||||
NPPQyf6/oVP5PmvQ3FDj+4Ay+YxVRjPNvAzoTZRQumFp22C7Ea0LGiL0YBV4sITM3/61fDwP7GlA \
|
||||
2lESLaaJVwHtcXhdFM0M5qt5aj0jXD6EDNesc0sv00Kw8UYyJEgEG/eFAkJowNLzKAXtThzMPwqW \
|
||||
UTTxAkVXRt3h+mB9MOKKOqKOUJlPz1FJ1KLdX4TcDi0cihEgmdllzBz6GYAVuH7jcj5jFS+hictL \
|
||||
z82ifRMvyWpt5TXWzPLyCrtNMXEObaaQ2aP3BaOCzmmAkaILmu4d3qLNQIBitFBVXo8WQPipDnoK \
|
||||
WEjR1y9cuE6bjTW6gKBoAXOgyu+7dUmW0LFAouHTRAcjikkAia40Qg91iwonRYQWUlroI9xFKcYu \
|
||||
pu4IR0z/W9S7Fwx1qQuRNh3PHUpfDOQS9Gpkrmkhv4aicrp0WekKw4ri8Tt5QvuS9uo2iKtvGz4p \
|
||||
/cTwKZ04+IFQGi2oknDOn0XL4sv00clG7dXdyt9clF9sPd/dzXZ3n2+9mEl/1adcPdSmPVf5+urV \
|
||||
7OrVC5SzM+kpB2b2LmIX9/xh843MP1872NOj6O098M2f5XR354Y1NHF93oVpNNeIcAAt2AchqSik \
|
||||
F+ktYMgi0dA6HtA+DUWj+NQe8tKnutCDfq5JaNmpDlA0+yKghZNFzyDdqaY8NHGqq+sUmmpnNy01 \
|
||||
JZuZhFRLuKXVz7b66VowuPnoOUDpp7MoCTIC9YIRMHvKPMaEEaCZQ5SgdcjU3bklS3aO0W6rdSWg \
|
||||
nR6f3Oegq4IBdIXGpyRMI0tn+jxOen3iyAfyvXTBZ3P3zdeSNCHsa9pUqfUb6fQWmLW4ZzGcIr19 \
|
||||
Ns4yHyJd2IRubTQGOZD4SQOj8JMA9DkoOUeXCCVaOlEc54xVmoCBFg43Zb1P0TAHGbKZSJsuIG1S \
|
||||
eAFNLEPrlCzW00sRN1F1PKuHJrZQdDsc2Udzb4OIJewh6cZDXZFOE9lpatm8QU4LBwny29jDiYME \
|
||||
9DzwNEUP7cLZgFbwT+Phgx/c7Pp97IPEuswG8wBt5pyJnpaGWl+ITt6Jvl1JWdD8kZrMoefgGwDN \
|
||||
r4uqaf42QbudaC2QtlsakOWm+9LDyXTQGDoK3Ao64D8G0Iaij5s/8B9uPdy6+yj9vwFmYCQ0 \
|
||||
') 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 |
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
4053
sys/include/psa_crypto/psa/crypto.h
Normal file
4053
sys/include/psa_crypto/psa/crypto.h
Normal file
File diff suppressed because it is too large
Load Diff
96
sys/include/psa_crypto/psa/crypto_contexts.h
Normal file
96
sys/include/psa_crypto/psa/crypto_contexts.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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 crypto_contexts.h
|
||||
* @brief Context definitions for PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_PSA_CRYPTO_CONTEXTS_H
|
||||
#define PSA_CRYPTO_PSA_CRYPTO_CONTEXTS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "kernel_defines.h"
|
||||
|
||||
#include "psa/crypto_includes.h"
|
||||
|
||||
|
||||
#if IS_USED(MODULE_PSA_HASH)
|
||||
/**
|
||||
* @brief Structure containing the hash contexts needed by the application.
|
||||
*/
|
||||
typedef union {
|
||||
#if IS_USED(MODULE_PSA_HASH_MD5) || defined(DOXYGEN)
|
||||
psa_hashes_md5_ctx_t md5; /**< MD5 context */
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_HASH_SHA_1) || defined(DOXYGEN)
|
||||
psa_hashes_sha1_ctx_t sha1; /**< SHA-1 context */
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_HASH_SHA_224) || defined(DOXYGEN)
|
||||
psa_hashes_sha224_ctx_t sha224; /**< SHA-224 context */
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_HASH_SHA_256) || defined(DOXYGEN)
|
||||
psa_hashes_sha256_ctx_t sha256; /**< SHA-256 context */
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_HASH_SHA_512) || defined(DOXYGEN)
|
||||
psa_hashes_sha512_ctx_t sha512; /**< SHA-512 context */
|
||||
#endif
|
||||
} psa_hash_context_t;
|
||||
#endif
|
||||
|
||||
#if IS_USED(MODULE_PSA_CIPHER)
|
||||
/**
|
||||
* @brief Structure containing the cipher contexts needed by the application.
|
||||
*/
|
||||
typedef union {
|
||||
#if IS_USED(MODULE_PSA_CIPHER_AES_128_ECB) ||\
|
||||
IS_USED(MODULE_PSA_CIPHER_AES_128_CBC) ||\
|
||||
defined(DOXYGEN)
|
||||
psa_cipher_aes_128_ctx_t aes_128; /**< AES 128 context*/
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_CIPHER_AES_192_CBC) || defined(DOXYGEN)
|
||||
psa_cipher_aes_192_ctx_t aes_192; /**< AES 192 context*/
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_CIPHER_AES_256_CBC) || defined(DOXYGEN)
|
||||
psa_cipher_aes_256_ctx_t aes_256; /**< AES 256 context*/
|
||||
#endif
|
||||
} psa_cipher_context_t;
|
||||
#endif
|
||||
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
/**
|
||||
* @brief Structure containing the secure element specific cipher contexts needed by the
|
||||
* application.
|
||||
*/
|
||||
typedef struct {
|
||||
psa_encrypt_or_decrypt_t direction; /**< Direction of this cipher operation */
|
||||
/** Structure containing a driver specific cipher context */
|
||||
union driver_context {
|
||||
unsigned dummy; /**< Make the union non-empty even with no supported algorithms. */
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A) || defined(DOXYGEN)
|
||||
atca_aes_cbc_ctx_t atca_aes_cbc; /**< ATCA AES CBC context*/
|
||||
#endif
|
||||
} drv_ctx; /**< SE specific cipher operation context */
|
||||
} psa_se_cipher_context_t;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_PSA_CRYPTO_CONTEXTS_H */
|
||||
/** @} */
|
||||
56
sys/include/psa_crypto/psa/crypto_includes.h
Normal file
56
sys/include/psa_crypto/psa/crypto_includes.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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
|
||||
* @{
|
||||
*
|
||||
* @brief Files to include in the build of PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_PSA_CRYPTO_INCLUDES_H
|
||||
#define PSA_CRYPTO_PSA_CRYPTO_INCLUDES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "kernel_defines.h"
|
||||
|
||||
#if IS_USED(MODULE_CRYPTO)
|
||||
#include "crypto/psa/riot_ciphers.h"
|
||||
#endif
|
||||
|
||||
#if IS_USED(MODULE_PSA_RIOT_HASHES_HMAC_SHA256) || IS_USED(MODULE_PSA_RIOT_HASHES_MD5) || \
|
||||
IS_USED(MODULE_PSA_RIOT_HASHES_SHA_1) || IS_USED(MODULE_PSA_RIOT_HASHES_SHA_224) || \
|
||||
IS_USED(MODULE_PSA_RIOT_HASHES_SHA_256)
|
||||
#include "hashes/psa/riot_hashes.h"
|
||||
#endif
|
||||
|
||||
#if IS_USED(MODULE_PERIPH_CIPHER_AES_128_CBC)
|
||||
#include "psa_periph_aes_ctx.h"
|
||||
#endif
|
||||
|
||||
#if IS_USED(MODULE_PERIPH_HASH_SHA_1) || IS_USED(MODULE_PERIPH_HASH_SHA_224) || \
|
||||
IS_USED(MODULE_PERIPH_HASH_SHA_256) || IS_USED(MODULE_PERIPH_HASH_SHA_512)
|
||||
#include "psa_periph_hashes_ctx.h"
|
||||
#endif
|
||||
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A)
|
||||
#include "atca_params.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_PSA_CRYPTO_INCLUDES_H */
|
||||
/** @} */
|
||||
48
sys/include/psa_crypto/psa/crypto_se_config.h
Normal file
48
sys/include/psa_crypto/psa/crypto_se_config.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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_psa_crypto
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Define structures für SE slot configurations
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_PSA_CRYPTO_SE_CONFIG_H
|
||||
#define PSA_CRYPTO_PSA_CRYPTO_SE_CONFIG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A)
|
||||
#include "atca.h"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Structure containing device specific configuration data.
|
||||
*
|
||||
* This will be stored in the driver's persistent data to
|
||||
* manage the device.
|
||||
*/
|
||||
typedef union {
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A)
|
||||
psa_atca_slot_config_t slots[16];
|
||||
#endif
|
||||
} psa_se_config_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_PSA_CRYPTO_SE_CONFIG_H */
|
||||
/** @} */
|
||||
1004
sys/include/psa_crypto/psa/crypto_sizes.h
Normal file
1004
sys/include/psa_crypto/psa/crypto_sizes.h
Normal file
File diff suppressed because it is too large
Load Diff
224
sys/include/psa_crypto/psa/crypto_struct.h
Normal file
224
sys/include/psa_crypto/psa/crypto_struct.h
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
* 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 crypto_struct.h
|
||||
* @brief Structure definitions for PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_PSA_CRYPTO_STRUCT_H
|
||||
#define PSA_CRYPTO_PSA_CRYPTO_STRUCT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "crypto_types.h"
|
||||
#include "crypto_sizes.h"
|
||||
#include "crypto_contexts.h"
|
||||
|
||||
/**
|
||||
* @brief Structure containing a hash context and algorithm
|
||||
*/
|
||||
struct psa_hash_operation_s {
|
||||
psa_algorithm_t alg; /**< Operation algorithm */
|
||||
#if IS_USED(MODULE_PSA_HASH)
|
||||
psa_hash_context_t ctx; /**< Operation hash context */
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This macro returns a suitable initializer for a hash operation object of type
|
||||
* @ref psa_hash_operation_t.
|
||||
*/
|
||||
#define PSA_HASH_OPERATION_INIT { 0 }
|
||||
|
||||
/**
|
||||
* @brief Return an initial value for a hash operation object.
|
||||
*
|
||||
* @return struct psa_hash_operation_s
|
||||
*/
|
||||
static inline struct psa_hash_operation_s psa_hash_operation_init(void)
|
||||
{
|
||||
const struct psa_hash_operation_s v = PSA_HASH_OPERATION_INIT;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Structure storing the key usage policies
|
||||
*/
|
||||
struct psa_key_policy_s {
|
||||
psa_key_usage_t usage; /**< Key usage policy */
|
||||
psa_algorithm_t alg; /**< Algorithm for key usage */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Type for key usage policies.
|
||||
*/
|
||||
typedef struct psa_key_policy_s psa_key_policy_t;
|
||||
|
||||
/**
|
||||
* @brief Structure storing key attributes
|
||||
*/
|
||||
struct psa_key_attributes_s {
|
||||
psa_key_type_t type; /**< Type of key */
|
||||
psa_key_bits_t bits; /**< Size of key in bits */
|
||||
psa_key_lifetime_t lifetime; /**< Lifetime of key */
|
||||
psa_key_id_t id; /**< Key identifier */
|
||||
psa_key_policy_t policy; /**< Key usage policy */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This macro returns a suitable initializer for a key attribute object of
|
||||
* type @ref psa_key_attributes_t.
|
||||
*/
|
||||
#define PSA_KEY_ATTRIBUTES_INIT { 0 }
|
||||
|
||||
/**
|
||||
* @brief Return an initial value for a key attribute object.
|
||||
*
|
||||
* @return struct psa_key_attributes_s
|
||||
*/
|
||||
static inline struct psa_key_attributes_s psa_key_attributes_init(void)
|
||||
{
|
||||
const struct psa_key_attributes_s v = PSA_KEY_ATTRIBUTES_INIT;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Structure storing an AEAD operation context
|
||||
*
|
||||
* @note Not implemented, yet
|
||||
*/
|
||||
struct psa_aead_operation_s {
|
||||
int dummy; /**< Not implemented, yet */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This macro returns a suitable initializer for an AEAD operation object of type
|
||||
* @ref psa_aead_operation_t.
|
||||
*/
|
||||
#define PSA_AEAD_OPERATION_INIT { 0 }
|
||||
|
||||
/**
|
||||
* @brief Return an initial value for an AEAD operation object.
|
||||
*
|
||||
* @return psa_aead_operation_s
|
||||
*/
|
||||
static inline struct psa_aead_operation_s psa_aead_operation_init(void)
|
||||
{
|
||||
const struct psa_aead_operation_s v = PSA_AEAD_OPERATION_INIT;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Structure storing a cipher operation context
|
||||
*/
|
||||
struct psa_cipher_operation_s {
|
||||
uint8_t iv_required : 1; /**< True if algorithm requires IV */
|
||||
uint8_t iv_set : 1; /**< True if IV was already set */
|
||||
uint8_t default_iv_length; /**< Default IV length for algorithm */
|
||||
psa_algorithm_t alg; /**< Operation algorithm*/
|
||||
/** Union containing cipher contexts for the executing backend */
|
||||
union cipher_context {
|
||||
#if IS_USED(MODULE_PSA_CIPHER)
|
||||
psa_cipher_context_t cipher_ctx; /**< Cipher context */
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A) || defined(DOXYGEN)
|
||||
psa_se_cipher_context_t se_ctx; /**< SE Cipher context */
|
||||
#endif
|
||||
} backend_ctx; /**< Backend specific cipher context */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief This macro returns a suitable initializer for a cipher operation
|
||||
* object of type @ref psa_cipher_operation_t.
|
||||
*/
|
||||
#define PSA_CIPHER_OPERATION_INIT { 0 }
|
||||
|
||||
/**
|
||||
* @brief Return an initial value for a cipher operation object.
|
||||
*
|
||||
* @return psa_cipher_operation_s
|
||||
*/
|
||||
static inline struct psa_cipher_operation_s psa_cipher_operation_init(void)
|
||||
{
|
||||
const struct psa_cipher_operation_s v = PSA_CIPHER_OPERATION_INIT;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This macro returns a suitable initializer for a key derivation operation object of
|
||||
* type @ref psa_key_derivation_operation_t.
|
||||
*/
|
||||
#define PSA_KEY_DERIVATION_OPERATION_INIT { 0 }
|
||||
|
||||
/**
|
||||
* @brief Structure storing a key derivation context
|
||||
*
|
||||
* @note Not yet implemented
|
||||
*/
|
||||
struct psa_key_derivation_operation_s {
|
||||
int dummy; /**< Not implemented yet */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Return an initial value for a key derivation operation object.
|
||||
*
|
||||
* @return psa_key_derivation_operation_s
|
||||
*/
|
||||
static inline struct psa_key_derivation_operation_s psa_key_derivation_operation_init(void)
|
||||
{
|
||||
const struct psa_key_derivation_operation_s v = PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This macro returns a suitable initializer for a MAC operation object of type
|
||||
* @ref psa_mac_operation_t.
|
||||
*/
|
||||
#define PSA_MAC_OPERATION_INIT { 0 }
|
||||
|
||||
/**
|
||||
* @brief Structure storing a MAC operation context
|
||||
*
|
||||
* @note Not yet implemented
|
||||
*/
|
||||
struct psa_mac_operation_s {
|
||||
int dummy; /**< Not yet implemented */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Return an initial value for a MAC operation object.
|
||||
*
|
||||
* @return psa_mac_operation_s
|
||||
*/
|
||||
static inline struct psa_mac_operation_s psa_mac_operation_init(void)
|
||||
{
|
||||
const struct psa_mac_operation_s v = PSA_MAC_OPERATION_INIT;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_PSA_CRYPTO_STRUCT_H */
|
||||
/** @} */
|
||||
503
sys/include/psa_crypto/psa/crypto_types.h
Normal file
503
sys/include/psa_crypto/psa/crypto_types.h
Normal file
@ -0,0 +1,503 @@
|
||||
/*
|
||||
* 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 crypto_types.h
|
||||
* @brief Type definitions for PSA Crypto
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_PSA_CRYPTO_TYPES_H
|
||||
#define PSA_CRYPTO_PSA_CRYPTO_TYPES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief For encrypt-decrypt functions, whether the operation is an encryption
|
||||
* or a decryption.
|
||||
*/
|
||||
typedef enum {
|
||||
PSA_CRYPTO_DRIVER_DECRYPT,
|
||||
PSA_CRYPTO_DRIVER_ENCRYPT
|
||||
} psa_encrypt_or_decrypt_t;
|
||||
|
||||
/**
|
||||
* @brief Encoding of a cryptographic algorithm.
|
||||
*
|
||||
* @details For algorithms that can be applied to multiple key types, this identifier does not
|
||||
* encode the key type. For example, for symmetric ciphers based on a block cipher,
|
||||
* @ref psa_algorithm_t encodes the block cipher mode and the padding mode while the
|
||||
* block cipher itself is encoded via @ref psa_key_type_t.
|
||||
*/
|
||||
typedef uint32_t psa_algorithm_t;
|
||||
|
||||
/**
|
||||
* @brief The type of PSA finite-field Diffie-Hellman group family identifiers.
|
||||
*
|
||||
* @details The group family identifier is required to create a finite-field Diffie-Hellman
|
||||
* key using the @ref PSA_KEY_TYPE_DH_KEY_PAIR() or @ref PSA_KEY_TYPE_DH_PUBLIC_KEY()
|
||||
* macros.
|
||||
*
|
||||
* The specific Diffie-Hellman group within a family is identified by the @c key_bits
|
||||
* attribute of the key.
|
||||
*/
|
||||
typedef uint8_t psa_dh_family_t;
|
||||
|
||||
/**
|
||||
* @brief The type of PSA elliptic curve family identifiers.
|
||||
*
|
||||
* @details The curve identifier is required to create an ECC key using the
|
||||
* @ref PSA_KEY_TYPE_ECC_KEY_PAIR() or @ref PSA_KEY_TYPE_ECC_PUBLIC_KEY()
|
||||
* macros.
|
||||
*
|
||||
* The specific ECC curve within a family is identified by the @c key_bits
|
||||
* attribute of the key.
|
||||
*/
|
||||
typedef uint8_t psa_ecc_family_t;
|
||||
|
||||
/**
|
||||
* @brief The type of the state object for key derivation operations.
|
||||
*
|
||||
* @details Before calling any function on a key derivation operation object, the application must
|
||||
* initialize it by any of the following means:
|
||||
* - Set the object to all-bits-zero, for example:
|
||||
* @code
|
||||
* @ref psa_key_derivation_operation_t operation;
|
||||
* memset(&operation, 0, sizeof(operation));
|
||||
* @endcode
|
||||
* - Initialize the object to logical zero values by declaring the object as static or
|
||||
* global without an explicit initializer, for example:
|
||||
* @code
|
||||
* static @ref psa_key_derivation_operation_t operation;
|
||||
* @endcode
|
||||
* - Initialize the object to the initializer @ref PSA_KEY_DERIVATION_OPERATION_INIT,
|
||||
* for example:
|
||||
* @code
|
||||
* @ref psa_key_derivation_operation_t operation =
|
||||
* @ref PSA_KEY_DERIVATION_OPERATION_INIT;
|
||||
* @endcode
|
||||
* - Assign the result of the function @ref psa_key_derivation_operation_init() to
|
||||
* the object, for example:
|
||||
* @code
|
||||
* @ref psa_key_derivation_operation_t operation;
|
||||
* operation = @ref psa_key_derivation_operation_init();
|
||||
* @endcode
|
||||
* This is an implementation-defined type. Applications that make assumptions about the
|
||||
* content of this object will result in in implementation-specific behavior, and are
|
||||
* non-portable.
|
||||
*/
|
||||
typedef struct psa_key_derivation_operation_s psa_key_derivation_operation_t;
|
||||
|
||||
/**
|
||||
* @brief Encoding of the step of a key derivation.
|
||||
*/
|
||||
typedef uint16_t psa_key_derivation_step_t;
|
||||
|
||||
/**
|
||||
* @brief Key identifier.
|
||||
*
|
||||
* @details A key identifier can be a permanent name for a persistent key, or a transient reference
|
||||
* to volatile key.
|
||||
*/
|
||||
typedef uint32_t psa_key_id_t;
|
||||
|
||||
/**
|
||||
* @brief Encoding of key lifetimes.
|
||||
*
|
||||
* @details The lifetime of a key indicates where it is stored and which application and system
|
||||
* actions will create and destroy it.
|
||||
*
|
||||
* Lifetime values have the following structure:
|
||||
* - Bits[7:0]: Persistence level
|
||||
* This value indicates what device management actions can cause it to be destroyed.
|
||||
* In particular, it indicates whether the key is volatile or persistent.
|
||||
* See @ref psa_key_persistence_t for more information.
|
||||
* @ref PSA_KEY_LIFETIME_GET_PERSISTENCE(@p lifetime) returns the persistence level for
|
||||
* a key lifetime value.
|
||||
* - Bits[31:8]: Location indicator
|
||||
* This value indicates where the key material is stored (or at least where it is
|
||||
* accessible in cleartext) and where operations on the key are performed. See
|
||||
* @ref psa_key_location_t for more information.
|
||||
* @ref PSA_KEY_LIFETIME_GET_LOCATION(@p lifetime) returns the location indicator for a
|
||||
* key lifetime value.
|
||||
*
|
||||
* Volatile keys are automatically destroyed when the application instance terminates or
|
||||
* on a power reset of the device. Persistent keys are preserved until the application
|
||||
* explicitly destroys them or until an implementation-specific device management event
|
||||
* occurs, for example, a factor reset.
|
||||
*
|
||||
* Persistent keys have a key identifier of type @ref psa_key_id_t. This identifier
|
||||
* remains valid throughout the lifetime of the key, even if the application instance
|
||||
* that created the key terminates.
|
||||
*
|
||||
* This specification defines two basic lifetime values:
|
||||
* - Keys with the lifetime @ref PSA_KEY_LIFETIME_VOLATILE are volatile. All
|
||||
* implementations should support this lifetime.
|
||||
* - Keys with the lifetime @ref PSA_KEY_LIFETIME_PERSISTENT are persistent. All
|
||||
* implementations that have access to persistent storage with appropriate security
|
||||
* guarantees should support this lifetime.
|
||||
*/
|
||||
typedef uint32_t psa_key_lifetime_t;
|
||||
|
||||
/**
|
||||
* @brief Encoding of key location indicators.
|
||||
*
|
||||
* @details If an implementation of this API can make calls to external cryptoprocessors such as
|
||||
* secure elements, the location of a key indicates which secure element performs the
|
||||
* operations on the key. If the key material is not stored persistently inside the secure
|
||||
* element, it must be stored in a wrapped form such that only the secure element can
|
||||
* access the key material in cleartext.
|
||||
*
|
||||
* @note Key location indicators are 24-bit values. Key management interfaces operate on
|
||||
* lifetimes (type @ref psa_key_lifetime_t), and encode the location as the upper 24 bits
|
||||
* of a 32-bit value.
|
||||
*
|
||||
* Values for location indicators defined by this specification are shown below:
|
||||
* - @c 0: Primary local storage.
|
||||
* All implementations should support this value. The primary local storage is
|
||||
* typically the same storage area that contains the key metadata.
|
||||
* - @c 1: Primary secure element.
|
||||
* @note As of now, this value is not supported by this implementation.
|
||||
* Use the vendor-defined location values.
|
||||
*
|
||||
* Implementations should support this value if there is a secure element
|
||||
* attached to the operating environment. As a guideline, secure elements may
|
||||
* provide higher resistance against side channel and physical attacks than the
|
||||
* primary local storage, but may have restrictions on supported key types,
|
||||
* sizes, policies and operations and may have different performance
|
||||
* characteristics.
|
||||
* - @c 2–0x7fffff: Other locations defined by a PSA specification.
|
||||
* The PSA Cryptography API does not currently assign any meaning to
|
||||
* these locations, but future versions of this specification or other
|
||||
* PSA specifications may do so.
|
||||
* - @c 0x800000–0xffffff: Vendor-defined locations. No PSA specification will assign a
|
||||
* meaning to locations in this range.
|
||||
*/
|
||||
typedef uint32_t psa_key_location_t;
|
||||
|
||||
/**
|
||||
* @brief Encoding of key persistence levels.
|
||||
*
|
||||
* @details What distinguishes different persistence levels is which device management events can
|
||||
* cause keys to be destroyed. For example, power reset, transfer of device ownership,
|
||||
* or a factory reset are device management events that can affect keys at different
|
||||
* persistence levels. The specific management events which affect persistent keys at
|
||||
* different levels is outside the scope of the PSA Cryptography specification.
|
||||
*
|
||||
* @note Key persistence levels are 8-bit values. Key management interfaces operate on lifetimes
|
||||
* (type @ref psa_key_lifetime_t), and encode the persistence value as the lower 8 bits of
|
||||
* a 32-bit value.
|
||||
*
|
||||
* Values for persistence levels defined by this specification are shown below:
|
||||
* - @c 0 = @ref PSA_KEY_PERSISTENCE_VOLATILE : Volatile key.
|
||||
* A volatile key is automatically destroyed by the implementation when the
|
||||
* application instance terminates. In particular, a volatile key is
|
||||
* automatically destroyed on a power reset of the device.
|
||||
* - @c 1 = @ref PSA_KEY_PERSISTENCE_DEFAULT : Persistent key with a default lifetime.
|
||||
* Implementations should support this value if they support persistent keys
|
||||
* at all. Applications should use this value if they have no specific needs
|
||||
* that are only met by implementation-specific features.
|
||||
* - @c 2–127: Persistent key with a PSA-specified lifetime. The PSA Cryptography
|
||||
* specification does not define the meaning of these values, but other PSA
|
||||
* specifications may do so.
|
||||
* - @c 128–254: Persistent key with a vendor-specified lifetime. No PSA specification
|
||||
* will define the meaning of these values, so implementations may choose
|
||||
* the meaning freely. As a guideline, higher persistence levels should
|
||||
* cause a key to survive more management events than lower levels.
|
||||
* - @c 255 = @ref PSA_KEY_PERSISTENCE_READ_ONLY : Read-only or write-once key.
|
||||
* A key with this persistence level cannot be destroyed. Implementations that
|
||||
* support such keys may either allow their creation through the PSA
|
||||
* Cryptography API, preferably only to applications with the appropriate
|
||||
* privilege, or only expose keys created through implementation-specific
|
||||
* means such as a factory ROM engraving process.
|
||||
* @note Keys that are read-only due to policy restrictions rather than
|
||||
* due to physical limitations should not have this persistence level.
|
||||
*/
|
||||
typedef uint8_t psa_key_persistence_t;
|
||||
|
||||
/**
|
||||
* @brief Encoding of a key type.
|
||||
*
|
||||
* @details This is a structured bitfield that identifies the category and type of key. The range
|
||||
* of key type values is divided as follows:
|
||||
* - @ref PSA_KEY_TYPE_NONE == @c 0:
|
||||
* Reserved as an invalid key type.
|
||||
* - @c 0x0001–0x7fff:
|
||||
* Specification-defined key types. Key types defined by this standard always have bit
|
||||
* 15 clear. Unallocated key type values in this range are reserved for future use.
|
||||
* - @c 0x8000–0xffff:
|
||||
* Implementation-defined key types. Implementations that define additional key types
|
||||
* must use an encoding with bit 15 set.
|
||||
*/
|
||||
typedef uint16_t psa_key_type_t;
|
||||
|
||||
/**
|
||||
* @brief Encoding of permitted usage on a key.
|
||||
*/
|
||||
typedef uint32_t psa_key_usage_t;
|
||||
|
||||
/**
|
||||
* @brief Public interfaces use @c size_t, but internally we use a smaller type.
|
||||
*/
|
||||
typedef uint16_t psa_key_bits_t;
|
||||
|
||||
/* These are all temporarily defined as some numeric type to prevent errors at compile time.*/
|
||||
/**
|
||||
* @brief The type of the state object for multi-part AEAD operations.
|
||||
*
|
||||
* @details Before calling any function on an AEAD operation object, the application must
|
||||
* initialize it by any of the following means:
|
||||
* - Set the object to all-bits-zero, for example:
|
||||
* @code
|
||||
* @ref psa_aead_operation_t operation;
|
||||
* memset(&operation, 0, sizeof(operation));
|
||||
* @endcode
|
||||
* - Initialize the object to logical zero values by declaring the object as static
|
||||
* or global without an explicit initializer, for example:
|
||||
* @code
|
||||
* static @ref psa_aead_operation_t operation;
|
||||
* @endcode
|
||||
* - Initialize the object to the initializer @ref PSA_AEAD_OPERATION_INIT, for example:
|
||||
* @code
|
||||
* @ref psa_aead_operation_t operation = @ref PSA_AEAD_OPERATION_INIT;
|
||||
* @endcode
|
||||
* - Assign the result of the function @ref psa_aead_operation_init() to the object,
|
||||
* for example:
|
||||
* @code
|
||||
* @ref psa_aead_operation_t operation;
|
||||
* operation = @ref psa_aead_operation_init();
|
||||
* @endcode
|
||||
*
|
||||
* This is an implementation-defined type. Applications that make assumptions about the
|
||||
* content of this object will result in in implementation-specific behavior, and are
|
||||
* non-portable.
|
||||
*/
|
||||
typedef struct psa_aead_operation_s psa_aead_operation_t;
|
||||
|
||||
/**
|
||||
* @brief The type of the state object for multi-part MAC operations.
|
||||
*
|
||||
* @details Before calling any function on a MAC operation object, the application must initialize
|
||||
* it by any of the following means:
|
||||
* - Set the object to all-bits-zero, for example:
|
||||
* @code
|
||||
* @ref psa_mac_operation_t operation;
|
||||
* memset(&operation, 0, sizeof(operation));
|
||||
* @endcode
|
||||
* - Initialize the object to logical zero values by declaring the object as static or
|
||||
* global without an explicit initializer, for example:
|
||||
* @code
|
||||
* static @ref psa_mac_operation_t operation;
|
||||
* @endcode
|
||||
* - Initialize the object to the initializer @ref PSA_MAC_OPERATION_INIT, for example:
|
||||
* @code
|
||||
* @ref psa_mac_operation_t operation = @ref PSA_MAC_OPERATION_INIT;
|
||||
* @endcode
|
||||
* - Assign the result of the function @ref psa_mac_operation_init() to the object,
|
||||
* for example:
|
||||
* @code
|
||||
* @ref psa_mac_operation_t operation;
|
||||
* operation = @ref psa_mac_operation_init();
|
||||
* @endcode
|
||||
* This is an implementation-defined type. Applications that make assumptions about the
|
||||
* content of this object will result in in implementation-specific behavior, and are
|
||||
* non-portable.
|
||||
*/
|
||||
typedef struct psa_mac_operation_s psa_mac_operation_t;
|
||||
|
||||
/**
|
||||
* @brief Function return status.
|
||||
*
|
||||
* @details This is either @ref PSA_SUCCESS, which is zero, indicating success; or a small
|
||||
* negative value indicating that an error occurred. Errors are encoded as one of
|
||||
* the @c PSA_ERROR_xxx values defined here.
|
||||
*/
|
||||
typedef int32_t psa_status_t;
|
||||
|
||||
/**
|
||||
* @brief The type of the state data structure for multipart hash operations.
|
||||
*
|
||||
* @details Before calling any function on a hash operation object, the application must
|
||||
* initialize it by any of the following means:
|
||||
* - Set the structure to all-bits-zero, for example:
|
||||
* @code
|
||||
* @ref psa_hash_operation_t operation;
|
||||
* memset(&operation, 0, sizeof(operation));
|
||||
* @endcode
|
||||
* - Initialize the structure to logical zero values, for example:
|
||||
* @code
|
||||
* @ref psa_hash_operation_t operation = {0};
|
||||
* @endcode
|
||||
* - Initialize the structure to the initializer @ref PSA_HASH_OPERATION_INIT,
|
||||
* for example:
|
||||
* @code
|
||||
* @ref psa_hash_operation_t operation = @ref PSA_HASH_OPERATION_INIT;
|
||||
* @endcode
|
||||
* - Assign the result of the function @ref psa_hash_operation_init()
|
||||
* to the structure, for example:
|
||||
* @code
|
||||
* @ref psa_hash_operation_t operation;
|
||||
* operation = @ref psa_hash_operation_init();
|
||||
* @endcode
|
||||
*
|
||||
* This is an implementation-defined struct. Applications should not
|
||||
* make any assumptions about the content of this structure except
|
||||
* as directed by the documentation of a specific implementation.
|
||||
*/
|
||||
typedef struct psa_hash_operation_s psa_hash_operation_t;
|
||||
|
||||
/**
|
||||
* @brief The type of an object containing key attributes.
|
||||
*
|
||||
* @details This is the object that represents the metadata of a key object. Metadata that can be
|
||||
* stored in attributes includes:
|
||||
* - The location of the key in storage, indicated by its key identifier and its lifetime.
|
||||
* - The key’s policy, comprising usage flags and a specification of the permitted
|
||||
* algorithm(s).
|
||||
* - Information about the key itself: the key type and its size.
|
||||
* - Implementations can define additional attributes.
|
||||
*
|
||||
* The actual key material is not considered an attribute of a key. Key attributes do not
|
||||
* contain information that is generally considered highly confidential.
|
||||
*
|
||||
* @note Implementations are recommended to define the attribute object as a simple data
|
||||
* structure, with fields corresponding to the individual key attributes. In such an
|
||||
* implementation, each function @c psa_set_key_xxx() sets a field and the corresponding
|
||||
* function @c psa_get_key_xxx() retrieves the value of the field.
|
||||
* An implementation can report attribute values that are equivalent to the original one,
|
||||
* but have a different encoding. For example, an implementation can use a more compact
|
||||
* representation for types where many bit-patterns are invalid or not supported, and
|
||||
* store all values that it does not support as a special marker value. In such an
|
||||
* implementation, after setting an invalid value, the corresponding get function returns
|
||||
* an invalid value which might not be the one that was originally stored.
|
||||
*
|
||||
* This is an implementation-defined type. Applications that make assumptions about the
|
||||
* content of this object will result in in implementation-specific behavior, and are
|
||||
* non-portable.
|
||||
*
|
||||
* An attribute object can contain references to auxiliary resources, for example pointers
|
||||
* to allocated memory or indirect references to pre-calculated values. In order to free
|
||||
* such resources, the application must call @ref psa_reset_key_attributes(). As an
|
||||
* exception, calling @ref psa_reset_key_attributes() on an attribute object is optional
|
||||
* if the object has only been modified by the following functions since it was
|
||||
* initialized or last reset with @ref psa_reset_key_attributes():
|
||||
* - @ref psa_set_key_id()
|
||||
* - @ref psa_set_key_lifetime()
|
||||
* - @ref psa_set_key_type()
|
||||
* - @ref psa_set_key_bits()
|
||||
* - @ref psa_set_key_usage_flags()
|
||||
* - @ref psa_set_key_algorithm()
|
||||
* Before calling any function on a key attribute object, the application must initialize
|
||||
* it by any of the following means:
|
||||
* - Set the object to all-bits-zero, for example:
|
||||
* @code
|
||||
* @ref psa_key_attributes_t attributes;
|
||||
* memset(&attributes, 0, sizeof(attributes));
|
||||
* @endcode
|
||||
* - Initialize the object to logical zero values by declaring the object as static or
|
||||
* global without an explicit initializer, for example:
|
||||
* @code
|
||||
* static @ref psa_key_attributes_t attributes;
|
||||
* @endcode
|
||||
* - Initialize the object to the initializer @ref PSA_KEY_ATTRIBUTES_INIT, for example:
|
||||
* @code
|
||||
* @ref psa_key_attributes_t attributes = @ref PSA_KEY_ATTRIBUTES_INIT;
|
||||
* @endcode
|
||||
* - Assign the result of the function @ref psa_key_attributes_init() to the object,
|
||||
* for example:
|
||||
* @code
|
||||
* @ref psa_key_attributes_t attributes;
|
||||
* attributes = @ref psa_key_attributes_init();
|
||||
* @endcode
|
||||
*
|
||||
* A freshly initialized attribute object contains the following values:
|
||||
* - lifetime: @ref PSA_KEY_LIFETIME_VOLATILE.
|
||||
* - key identifier: @ref PSA_KEY_ID_NULL — which is not a valid key identifier.
|
||||
* - type: @ref PSA_KEY_TYPE_NONE — meaning that the type is unspecified.
|
||||
* - key size: @c 0 — meaning that the size is unspecified.
|
||||
* - usage flags: @c 0 — which allows no usage except exporting a public key.
|
||||
* - algorithm: @ref PSA_ALG_NONE — which does not allow cryptographic usage,
|
||||
* but allows exporting.
|
||||
*
|
||||
* ## Usage
|
||||
* A typical sequence to create a key is as follows:
|
||||
* -# Create and initialize an attribute object.
|
||||
* -# If the key is persistent, call @ref psa_set_key_id(). Also call @ref
|
||||
* psa_set_key_lifetime() to place the key in a non-default location.
|
||||
* -# Set the key policy with @ref psa_set_key_usage_flags() and @ref
|
||||
* psa_set_key_algorithm().
|
||||
* -# Set the key type with @ref psa_set_key_type(). Skip this step if copying an existing
|
||||
* key with @ref psa_copy_key().
|
||||
* -# When generating a random key with @ref psa_generate_key() or deriving a key with
|
||||
* @ref psa_key_derivation_output_key(), set the desired key size with @ref
|
||||
* psa_set_key_bits().
|
||||
* -# Call a key creation function: @ref psa_import_key(), @ref psa_generate_key(),
|
||||
* @ref psa_key_derivation_output_key() or @ref psa_copy_key(). This function reads the
|
||||
* attribute object, creates a key with these attributes, and outputs an identifier for
|
||||
* the newly created key.
|
||||
* -# Optionally call @ref psa_reset_key_attributes(), now that the attribute object is no
|
||||
* longer needed. Currently this call is not required as the attributes defined in this
|
||||
* specification do not require additional resources beyond the object itself.
|
||||
*
|
||||
* A typical sequence to query a key’s attributes is as follows:
|
||||
* -# Call @ref psa_get_key_attributes().
|
||||
* -# Call @c psa_get_key_xxx() functions to retrieve the required attribute(s).
|
||||
* -# Call @ref psa_reset_key_attributes() to free any resources that can be used by the
|
||||
* attribute object.
|
||||
*
|
||||
* Once a key has been created, it is impossible to change its attributes.
|
||||
*/
|
||||
typedef struct psa_key_attributes_s psa_key_attributes_t;
|
||||
|
||||
/**
|
||||
* @brief The type of the state object for multi-part cipher operations.
|
||||
*
|
||||
* @details Before calling any function on a cipher operation object, the application must
|
||||
* initialize it by any of the following means:
|
||||
* - Set the object to all-bits-zero, for example:
|
||||
* @code
|
||||
* @ref psa_cipher_operation_t operation;
|
||||
* memset(&operation, 0, sizeof(operation));
|
||||
* @endcode
|
||||
* - Initialize the object to logical zero values by declaring the object as static or
|
||||
* global without an explicit initializer, for example:
|
||||
* @code
|
||||
* static @ref psa_cipher_operation_t operation;
|
||||
* @endcode
|
||||
* - Initialize the object to the initializer @ref PSA_CIPHER_OPERATION_INIT, for example:
|
||||
* @code
|
||||
* @ref psa_cipher_operation_t operation = @ref PSA_CIPHER_OPERATION_INIT;
|
||||
* @endcode
|
||||
* - Assign the result of the function @ref psa_cipher_operation_init() to the object,
|
||||
* for example:
|
||||
* @code
|
||||
* @ref psa_cipher_operation_t operation;
|
||||
* operation = @ref psa_cipher_operation_init();
|
||||
* @endcode
|
||||
*
|
||||
* This is an implementation-defined type. Applications that make assumptions about the
|
||||
* content of this object will result in in implementation-specific behavior, and are
|
||||
* non-portable.
|
||||
*/
|
||||
typedef struct psa_cipher_operation_s psa_cipher_operation_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_PSA_CRYPTO_TYPES_H */
|
||||
/** @} */
|
||||
3486
sys/include/psa_crypto/psa/crypto_values.h
Normal file
3486
sys/include/psa_crypto/psa/crypto_values.h
Normal file
File diff suppressed because it is too large
Load Diff
24
sys/psa_crypto/Kconfig
Normal file
24
sys/psa_crypto/Kconfig
Normal file
@ -0,0 +1,24 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
menuconfig MODULE_PSA_CRYPTO
|
||||
bool "PSA Crypto"
|
||||
depends on TEST_KCONFIG
|
||||
select MODULE_RANDOM
|
||||
|
||||
if MODULE_PSA_CRYPTO
|
||||
|
||||
rsource "Kconfig.asymmetric"
|
||||
rsource "Kconfig.ciphers"
|
||||
rsource "Kconfig.hashes"
|
||||
rsource "Kconfig.mac"
|
||||
rsource "Kconfig.keys"
|
||||
|
||||
rsource "psa_se_mgmt/Kconfig"
|
||||
rsource "psa_key_slot_mgmt/Kconfig"
|
||||
|
||||
endif # MODULE_PSA_CRYPTO
|
||||
61
sys/psa_crypto/Kconfig.asymmetric
Normal file
61
sys/psa_crypto/Kconfig.asymmetric
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.
|
||||
#
|
||||
|
||||
menuconfig MODULE_PSA_ASYMMETRIC
|
||||
bool "PSA Asymmetric Crypto"
|
||||
select PSA_KEY_CONFIG
|
||||
select MODULE_PSA_KEY_SLOT_MGMT
|
||||
|
||||
if MODULE_PSA_ASYMMETRIC
|
||||
|
||||
menuconfig MODULE_PSA_ASYMMETRIC_ECC_P192R1
|
||||
bool "ECC NIST-P192R1"
|
||||
select PSA_KEY_SIZE_192
|
||||
|
||||
if MODULE_PSA_ASYMMETRIC_ECC_P192R1
|
||||
|
||||
choice PSA_ASYMMETRIC_ECC_P192R1_BACKEND
|
||||
bool "ECC NIST-P192R1 Implementation"
|
||||
|
||||
config MODULE_PSA_ASYMMETRIC_ECC_P192R1_BACKEND_PERIPH
|
||||
bool "Hardware accelerated with peripheral"
|
||||
depends on HAS_PERIPH_ECC_P192R1
|
||||
select MODULE_PERIPH_ECC_P192R1
|
||||
|
||||
config MODULE_PSA_ASYMMETRIC_ECC_P192R1_BACKEND_MICROECC
|
||||
bool "Micro-ECC Package"
|
||||
select PACKAGE_MICRO-ECC
|
||||
select MODULE_PSA_UECC_P192
|
||||
|
||||
endchoice
|
||||
|
||||
endif # MODULE_PSA_ASYMMETRIC_ECC_P192R1
|
||||
|
||||
menuconfig MODULE_PSA_ASYMMETRIC_ECC_P256R1
|
||||
bool "ECC NIST-P256R1"
|
||||
select PSA_KEY_SIZE_256
|
||||
|
||||
if MODULE_PSA_ASYMMETRIC_ECC_P256R1
|
||||
|
||||
choice PSA_ASYMMETRIC_ECC_P256R1_BACKEND
|
||||
bool "ECC NIST-P256R1 Implementation"
|
||||
|
||||
config MODULE_PSA_ASYMMETRIC_ECC_P256R1_BACKEND_PERIPH
|
||||
bool "Hardware Accelerated"
|
||||
depends on HAS_PERIPH_ECC_P256R1
|
||||
select MODULE_PERIPH_ECC_P256R1
|
||||
|
||||
config MODULE_PSA_ASYMMETRIC_ECC_P256R1_BACKEND_MICROECC
|
||||
bool "Micro-ECC Package"
|
||||
select PACKAGE_MICRO-ECC
|
||||
select MODULE_PSA_UECC_P256
|
||||
|
||||
endchoice
|
||||
|
||||
endif # MODULE_PSA_ASYMMETRIC_ECC_P256R1
|
||||
|
||||
endif # MODULE_PSA_ASYMMETRIC
|
||||
92
sys/psa_crypto/Kconfig.ciphers
Normal file
92
sys/psa_crypto/Kconfig.ciphers
Normal file
@ -0,0 +1,92 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
menuconfig MODULE_PSA_CIPHER
|
||||
bool "PSA Ciphers"
|
||||
select PSA_KEY_CONFIG
|
||||
select MODULE_PSA_KEY_SLOT_MGMT
|
||||
|
||||
if MODULE_PSA_CIPHER
|
||||
|
||||
menuconfig MODULE_PSA_CIPHER_AES_128_ECB
|
||||
bool "AES-128 ECB"
|
||||
select PSA_KEY_SIZE_128
|
||||
|
||||
if MODULE_PSA_CIPHER_AES_128_ECB
|
||||
|
||||
choice PSA_CIPHER_AES_128_ECB_BACKEND
|
||||
bool "AES-128 Implementation"
|
||||
|
||||
config MODULE_PSA_CIPHER_AES_128_ECB_BACKEND_RIOT
|
||||
bool "RIOT cipher"
|
||||
select MODULE_CRYPTO
|
||||
select MODULE_PSA_RIOT_CIPHER_AES_ECB
|
||||
|
||||
endchoice
|
||||
|
||||
endif # MODULE_PSA_CIPHER_AES_128_ECB
|
||||
|
||||
menuconfig MODULE_PSA_CIPHER_AES_128_CBC
|
||||
bool "AES-128 CBC"
|
||||
select PSA_KEY_SIZE_128
|
||||
|
||||
if MODULE_PSA_CIPHER_AES_128_CBC
|
||||
|
||||
choice PSA_CIPHER_AES_128_CBC_BACKEND
|
||||
bool "AES-128 CBC Implementation"
|
||||
|
||||
config MODULE_PSA_CIPHER_AES_128_CBC_BACKEND_PERIPH
|
||||
bool "Hardware Accelerated"
|
||||
depends on HAS_PERIPH_CIPHER_AES_128_CBC
|
||||
select MODULE_PERIPH_CIPHER_AES_128_CBC
|
||||
|
||||
config MODULE_PSA_CIPHER_AES_128_CBC_BACKEND_RIOT
|
||||
bool "RIOT cipher"
|
||||
select MODULE_CRYPTO
|
||||
select MODULE_PSA_RIOT_CIPHER_AES_128_CBC
|
||||
|
||||
endchoice
|
||||
|
||||
endif # MODULE_PSA_CIPHER_AES_128_CBC
|
||||
|
||||
menuconfig MODULE_PSA_CIPHER_AES_192_CBC
|
||||
bool "AES-192 CBC"
|
||||
select PSA_KEY_SIZE_192
|
||||
|
||||
if MODULE_PSA_CIPHER_AES_192_CBC
|
||||
|
||||
choice PSA_CIPHER_AES_192_CBC_BACKEND
|
||||
bool "AES-192 Implementation"
|
||||
|
||||
config MODULE_PSA_CIPHER_AES_192_CBC_BACKEND_RIOT
|
||||
bool "RIOT cipher"
|
||||
select MODULE_CRYPTO
|
||||
select MODULE_PSA_RIOT_CIPHER_AES_CBC
|
||||
|
||||
endchoice
|
||||
|
||||
endif # MODULE_PSA_CIPHER_AES_192_CBC
|
||||
|
||||
menuconfig MODULE_PSA_CIPHER_AES_256_CBC
|
||||
bool "AES-256 CBC"
|
||||
select PSA_KEY_SIZE_256
|
||||
|
||||
if MODULE_PSA_CIPHER_AES_256_CBC
|
||||
|
||||
choice CIPHER_AES_256_CBC_BACKEND
|
||||
bool "AES-256 Implementation"
|
||||
|
||||
config MODULE_PSA_CIPHER_AES_256_CBC_BACKEND_RIOT
|
||||
bool "RIOT Cipher Module"
|
||||
select MODULE_CRYPTO
|
||||
select MODULE_PSA_RIOT_CIPHER_AES_CBC
|
||||
|
||||
endchoice
|
||||
|
||||
endif # MODULE_PSA_CIPHER_AES_256_CBC
|
||||
|
||||
endif # MODULE_PSA_CIPHER
|
||||
111
sys/psa_crypto/Kconfig.hashes
Normal file
111
sys/psa_crypto/Kconfig.hashes
Normal file
@ -0,0 +1,111 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
menuconfig MODULE_PSA_HASH
|
||||
bool "PSA Hashes"
|
||||
select PSA_KEY_CONFIG
|
||||
|
||||
if MODULE_PSA_HASH
|
||||
|
||||
menuconfig MODULE_PSA_HASH_MD5
|
||||
bool "MD5"
|
||||
|
||||
if MODULE_PSA_HASH_MD5
|
||||
|
||||
choice PSA_HASH_MD5_BACKEND
|
||||
bool "MD5 implementation"
|
||||
|
||||
config MODULE_PSA_HASH_MD5_BACKEND_RIOT
|
||||
bool "RIOT hash"
|
||||
select MODULE_PSA_RIOT_HASHES_MD5
|
||||
|
||||
endchoice
|
||||
|
||||
endif # MODULE_PSA_HASH_MD5
|
||||
|
||||
menuconfig MODULE_PSA_HASH_SHA_1
|
||||
bool "SHA-1"
|
||||
|
||||
if MODULE_PSA_HASH_SHA_1
|
||||
|
||||
choice PSA_HASH_SHA_1_BACKEND
|
||||
bool "SHA-1 implementation"
|
||||
|
||||
config MODULE_PSA_HASH_SHA_1_BACKEND_PERIPH
|
||||
bool "Hardware accelerated"
|
||||
depends on HAS_PERIPH_HASH_SHA_1
|
||||
select MODULE_PERIPH_HASH_SHA_1
|
||||
|
||||
config MODULE_PSA_HASH_SHA_1_BACKEND_RIOT
|
||||
bool "RIOT hash"
|
||||
select MODULE_PSA_RIOT_HASHES_SHA_1
|
||||
|
||||
endchoice
|
||||
|
||||
endif # MODULE_PSA_HASH_SHA_1
|
||||
|
||||
menuconfig MODULE_PSA_HASH_SHA_224
|
||||
bool "SHA-224"
|
||||
|
||||
if MODULE_PSA_HASH_SHA_224
|
||||
|
||||
choice PSA_HASH_SHA_224_BACKEND
|
||||
bool "SHA-224 implementation"
|
||||
|
||||
config MODULE_PSA_HASH_SHA_224_BACKEND_PERIPH
|
||||
bool "Hardware accelerated"
|
||||
depends on HAS_PERIPH_HASH_SHA_224
|
||||
select MODULE_PERIPH_HASH_SHA_224
|
||||
|
||||
config MODULE_PSA_HASH_SHA_224_BACKEND_RIOT
|
||||
bool "RIOT Hash Module"
|
||||
select MODULE_PSA_RIOT_HASHES_SHA_224
|
||||
|
||||
endchoice
|
||||
|
||||
endif # MODULE_PSA_HASH_SHA_224
|
||||
|
||||
menuconfig MODULE_PSA_HASH_SHA_256
|
||||
bool "SHA-256"
|
||||
|
||||
if MODULE_PSA_HASH_SHA_256
|
||||
|
||||
choice PSA_HASH_SHA_256_BACKEND
|
||||
bool "SHA-256 implementation"
|
||||
|
||||
config MODULE_PSA_HASH_SHA_256_BACKEND_PERIPH
|
||||
bool "Hardware accelerated"
|
||||
depends on HAS_PERIPH_HASH_SHA_256
|
||||
select MODULE_PERIPH_HASH_SHA_256
|
||||
|
||||
config MODULE_PSA_HASH_SHA_256_BACKEND_RIOT
|
||||
bool "RIOT hash"
|
||||
select MODULE_PSA_RIOT_HASHES_SHA_256
|
||||
|
||||
endchoice
|
||||
|
||||
endif # MODULE_PSA_HASH_SHA_256
|
||||
|
||||
menuconfig MODULE_PSA_HASH_SHA_512
|
||||
bool "SHA-512"
|
||||
depends on HAS_PERIPH_HASH_SHA_512 # no software implementation so far...
|
||||
|
||||
if MODULE_PSA_HASH_SHA_512
|
||||
|
||||
choice PSA_HASH_SHA_512_BACKEND
|
||||
bool "SHA-512 implementation"
|
||||
|
||||
config MODULE_PSA_HASH_SHA_512_BACKEND_PERIPH
|
||||
bool "Hardware accelerated"
|
||||
depends on HAS_PERIPH_HASH_SHA_512
|
||||
select MODULE_PERIPH_HASH_SHA_512
|
||||
|
||||
endchoice
|
||||
|
||||
endif # MODULE_PSA_HASH_SHA_512
|
||||
|
||||
endif # MODULE_PSA_HASH
|
||||
55
sys/psa_crypto/Kconfig.keys
Normal file
55
sys/psa_crypto/Kconfig.keys
Normal file
@ -0,0 +1,55 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
menu "PSA Key Management Configuration"
|
||||
|
||||
config PSA_KEY_SIZE_128
|
||||
bool "Application uses key of size 128 Bits"
|
||||
help
|
||||
Indicates that the maximum PSA key size should be at least 128 bits.
|
||||
|
||||
config PSA_KEY_SIZE_192
|
||||
bool
|
||||
help
|
||||
Indicates that the maximum PSA key size should be at least 192 bits.
|
||||
|
||||
config PSA_KEY_SIZE_256
|
||||
bool
|
||||
help
|
||||
Indicates that the maximum PSA key size should be at least 256 bits.
|
||||
|
||||
config PSA_KEY_SIZE_512
|
||||
bool
|
||||
help
|
||||
Indicates that the maximum PSA key size should be at least 512 bits.
|
||||
|
||||
config PSA_MAX_KEY_SIZE
|
||||
int
|
||||
default 64 if PSA_KEY_SIZE_512
|
||||
default 32 if PSA_KEY_SIZE_256
|
||||
default 24 if PSA_KEY_SIZE_192
|
||||
default 16 if PSA_KEY_SIZE_128
|
||||
default 0
|
||||
help
|
||||
Indicates the maximum PSA key size in bytes.
|
||||
|
||||
config PSA_PROTECTED_KEY_COUNT
|
||||
int "Specifies number of allocated protected key slots"
|
||||
default 5 if MODULE_PSA_SECURE_ELEMENT
|
||||
default 0
|
||||
|
||||
config PSA_ASYMMETRIC_KEYPAIR_COUNT
|
||||
int "Specifies number of allocated key pair slots"
|
||||
default 5 if MODULE_PSA_ASYMMETRIC
|
||||
default 0
|
||||
|
||||
config PSA_SINGLE_KEY_COUNT
|
||||
int "Specifies number of allocated single key slots"
|
||||
default 5 if PSA_MAX_KEY_SIZE != 0
|
||||
default 0
|
||||
|
||||
endmenu # PSA Key Management Configuration
|
||||
37
sys/psa_crypto/Kconfig.mac
Normal file
37
sys/psa_crypto/Kconfig.mac
Normal file
@ -0,0 +1,37 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
menuconfig MODULE_PSA_MAC
|
||||
bool "PSA Message Authenticated Ciphers"
|
||||
select PSA_KEY_CONFIG
|
||||
select MODULE_PSA_KEY_SLOT_MGMT
|
||||
|
||||
if MODULE_PSA_MAC
|
||||
|
||||
menuconfig MODULE_PSA_MAC_HMAC_SHA_256
|
||||
bool "HMAC SHA-256"
|
||||
select PSA_KEY_SIZE_256
|
||||
|
||||
if MODULE_PSA_MAC_HMAC_SHA_256
|
||||
|
||||
choice PSA_MAC_HMAC_SHA_256_BACKEND
|
||||
bool "HMAC SHA256 Implementation"
|
||||
|
||||
config MODULE_PSA_MAC_HMAC_SHA_256_BACKEND_PERIPH
|
||||
bool "Hardware Accelerated"
|
||||
depends on HAS_PERIPH_HMAC_SHA_256
|
||||
select MODULE_PERIPH_HMAC_SHA_256
|
||||
|
||||
config MODULE_PSA_MAC_HMAC_SHA_256_BACKEND_RIOT
|
||||
bool "RIOT HMAC SHA-256"
|
||||
select MODULE_PSA_RIOT_HASHES_HMAC_SHA256
|
||||
|
||||
endchoice # PSA_MAC_HMAC_SHA_256_BACKEND
|
||||
|
||||
endif # MODULE_PSA_MAC_HMAC_SHA_256
|
||||
|
||||
endif # MODULE_PSA_MAC
|
||||
15
sys/psa_crypto/Makefile
Normal file
15
sys/psa_crypto/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
# PSA Crypto casts like hell, so this needs to shut the f up
|
||||
CFLAGS += -Wno-cast-align
|
||||
|
||||
# include the PSA headers
|
||||
INCLUDES += -I$(RIOTBASE)/sys/psa_crypto/include
|
||||
|
||||
ifneq (,$(filter psa_key_slot_mgmt,$(USEMODULE)))
|
||||
DIRS += psa_key_slot_mgmt
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_se_mgmt,$(USEMODULE)))
|
||||
DIRS += psa_se_mgmt
|
||||
endif
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
241
sys/psa_crypto/Makefile.dep
Normal file
241
sys/psa_crypto/Makefile.dep
Normal file
@ -0,0 +1,241 @@
|
||||
ifneq (,$(filter psa_crypto,$(USEMODULE)))
|
||||
USEMODULE += random
|
||||
USEMODULE += prng_musl_lcg
|
||||
endif
|
||||
|
||||
# Asymmetric
|
||||
ifneq (,$(filter psa_asymmetric,$(USEMODULE)))
|
||||
USEMODULE += psa_key_slot_mgmt
|
||||
endif
|
||||
|
||||
## ECC_P192R1 backend
|
||||
ifneq (,$(filter psa_asymmetric_ecc_p192r1,$(USEMODULE)))
|
||||
ifeq (,$(filter psa_asymmetric_ecc_p192r1_custom_backend,$(USEMODULE)))
|
||||
FEATURES_OPTIONAL += periph_ecc_p192r1
|
||||
include $(RIOTMAKE)/features_check.inc.mk
|
||||
# HACK: Due to kconfig migration, may cause problems
|
||||
ifneq (,$(filter periph_ecc_p192r1,$(FEATURES_USED)))
|
||||
USEMODULE += psa_asymmetric_ecc_p192r1_backend_periph
|
||||
else
|
||||
USEMODULE += psa_asymmetric_ecc_p192r1_backend_microecc
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_asymmetric_ecc_p192r1_backend_microecc, $(USEMODULE)))
|
||||
USEPKG += micro-ecc
|
||||
USEMODULE += psa_uecc
|
||||
USEMODULE += psa_uecc_p192
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_asymmetric_ecc_p192r1_backend_periph,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_ecc_p192r1
|
||||
endif
|
||||
|
||||
## ECC_P256R1 backend
|
||||
ifneq (,$(filter psa_asymmetric_ecc_p256r1,$(USEMODULE)))
|
||||
ifeq (,$(filter psa_asymmetric_ecc_p256r1_custom_backend,$(USEMODULE)))
|
||||
FEATURES_OPTIONAL += periph_ecc_p256r1
|
||||
include $(RIOTMAKE)/features_check.inc.mk
|
||||
# HACK: Due to kconfig migration, may cause problems
|
||||
ifneq (,$(filter periph_ecc_p256r1,$(FEATURES_USED)))
|
||||
USEMODULE += psa_asymmetric_ecc_p256r1_backend_periph
|
||||
else
|
||||
USEMODULE += psa_asymmetric_ecc_p256r1_backend_microecc
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_asymmetric_ecc_p256r1_backend_microecc,$(USEMODULE)))
|
||||
USEPKG += micro-ecc
|
||||
USEMODULE += psa_uecc
|
||||
USEMODULE += psa_uecc_p256
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_asymmetric_ecc_p256r1_backend_periph,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_ecc_p256r1
|
||||
endif
|
||||
|
||||
# Cipher
|
||||
ifneq (,$(filter psa_cipher,$(USEMODULE)))
|
||||
USEMODULE += psa_key_slot_mgmt
|
||||
endif
|
||||
|
||||
## AES-128-ECB backend
|
||||
ifneq (,$(filter psa_cipher_aes_128_ecb,$(USEMODULE)))
|
||||
USEMODULE += psa_cipher_aes_128_ecb_backend_riot
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_cipher_aes_128_ecb_backend_riot,$(USEMODULE)))
|
||||
USEMODULE += crypto
|
||||
USEMODULE += cipher_modes
|
||||
USEMODULE += psa_riot_cipher
|
||||
USEMODULE += psa_riot_cipher_aes_ecb
|
||||
endif
|
||||
|
||||
## AES-128-CBC
|
||||
ifneq (,$(filter psa_cipher_aes_128_cbc,$(USEMODULE)))
|
||||
ifeq (,$(filter psa_cipher_aes_128_cbc_custom_backend,$(USEMODULE)))
|
||||
FEATURES_OPTIONAL += periph_cipher_aes_128_cbc
|
||||
include $(RIOTMAKE)/features_check.inc.mk
|
||||
# HACK: Due to kconfig migration, may cause problems
|
||||
ifneq (,$(filter periph_cipher_aes_128_cbc,$(FEATURES_USED)))
|
||||
USEMODULE += psa_cipher_aes_128_cbc_backend_periph
|
||||
else
|
||||
USEMODULE += psa_cipher_aes_128_cbc_backend_riot
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_cipher_aes_128_cbc_backend_periph,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_cipher_aes_128_cbc
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_cipher_aes_128_cbc_backend_riot,$(USEMODULE)))
|
||||
USEMODULE += crypto
|
||||
USEMODULE += cipher_modes
|
||||
USEMODULE += psa_riot_cipher
|
||||
USEMODULE += psa_riot_cipher_aes_128_cbc
|
||||
endif
|
||||
|
||||
## AES-192-CBC
|
||||
ifneq (,$(filter psa_cipher_aes_192_cbc,$(USEMODULE)))
|
||||
USEMODULE += psa_cipher_aes_192_cbc_backend_riot
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_cipher_aes_192_cbc_backend_riot,$(USEMODULE)))
|
||||
USEMODULE += crypto
|
||||
USEMODULE += cipher_modes
|
||||
USEMODULE += psa_riot_cipher
|
||||
USEMODULE += psa_riot_cipher_aes_192_cbc
|
||||
endif
|
||||
|
||||
# Hash
|
||||
|
||||
## MD5
|
||||
ifneq (,$(filter psa_hash_md5,$(USEMODULE)))
|
||||
USEMODULE += psa_hash_md5_backend_riot
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_hash_md5_backend_riot,$(USEMODULE)))
|
||||
USEMODULE += hashes
|
||||
USEMODULE += psa_riot_hashes
|
||||
USEMODULE += psa_riot_hashes_md5
|
||||
endif
|
||||
|
||||
## SHA-1
|
||||
ifneq (,$(filter psa_hash_sha_1,$(USEMODULE)))
|
||||
ifeq (,$(filter psa_hash_sha_1_custom_backend,$(USEMODULE)))
|
||||
FEATURES_OPTIONAL += periph_hash_sha_1
|
||||
include $(RIOTMAKE)/features_check.inc.mk
|
||||
# HACK: Due to kconfig migration, may cause problems
|
||||
ifneq (,$(filter periph_hash_sha_1,$(FEATURES_USED)))
|
||||
USEMODULE += psa_hash_sha_1_backend_periph
|
||||
else
|
||||
USEMODULE += psa_hash_sha_1_backend_riot
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_hash_sha_1_backend_periph,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_hash_sha_1
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_hash_sha_1_backend_riot,$(USEMODULE)))
|
||||
USEMODULE += hashes
|
||||
USEMODULE += psa_riot_hashes
|
||||
USEMODULE += psa_riot_hashes_sha_1
|
||||
endif
|
||||
|
||||
## SHA-224
|
||||
ifneq (,$(filter psa_hash_sha_224,$(USEMODULE)))
|
||||
ifeq (,$(filter psa_hash_sha_224_custom_backend,$(USEMODULE)))
|
||||
FEATURES_OPTIONAL += periph_hash_sha_224
|
||||
include $(RIOTMAKE)/features_check.inc.mk
|
||||
# HACK: Due to kconfig migration, may cause problems
|
||||
ifneq (,$(filter periph_hash_sha_224,$(FEATURES_USED)))
|
||||
USEMODULE += psa_hash_sha_224_backend_periph
|
||||
else
|
||||
USEMODULE += psa_hash_sha_224_backend_riot
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_hash_sha_224_backend_periph,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_hash_sha_224
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_hash_sha_224_backend_riot,$(USEMODULE)))
|
||||
USEMODULE += hashes
|
||||
USEMODULE += psa_riot_hashes
|
||||
USEMODULE += psa_riot_hashes_sha_224
|
||||
endif
|
||||
|
||||
## SHA-256
|
||||
ifneq (,$(filter psa_hash_sha_256,$(USEMODULE)))
|
||||
ifeq (,$(filter psa_hash_sha_256_custom_backend,$(USEMODULE)))
|
||||
FEATURES_OPTIONAL += periph_hash_sha_256
|
||||
include $(RIOTMAKE)/features_check.inc.mk
|
||||
# HACK: Due to kconfig migration, may cause problems
|
||||
ifneq (,$(filter periph_hash_sha_256,$(FEATURES_USED)))
|
||||
USEMODULE += psa_hash_sha_256_backend_periph
|
||||
else
|
||||
USEMODULE += psa_hash_sha_256_backend_riot
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_hash_sha_256_backend_periph,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_hash_sha_256
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_hash_sha_256_backend_riot,$(USEMODULE)))
|
||||
USEMODULE += hashes
|
||||
USEMODULE += psa_riot_hashes
|
||||
USEMODULE += psa_riot_hashes_sha_256
|
||||
endif
|
||||
|
||||
## SHA-512
|
||||
ifneq (,$(filter psa_hash_sha_512,$(USEMODULE)))
|
||||
USEMODULE += psa_hash_sha_512_backend_periph
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_hash_sha_512_backend_periph,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_hash_sha_512
|
||||
endif
|
||||
|
||||
# MAC
|
||||
## HMAC SHA-256
|
||||
ifneq (,$(filter psa_mac_hmac_sha_256,$(USEMODULE)))
|
||||
ifeq (,$(filter psa_mac_hmac_sha_256_custom_backend,$(USEMODULE)))
|
||||
FEATURES_OPTIONAL += periph_hmac_sha_256
|
||||
include $(RIOTMAKE)/features_check.inc.mk
|
||||
# HACK: Due to kconfig migration, may cause problems
|
||||
ifneq (,$(filter periph_hmac_sha_256,$(FEATURES_USED)))
|
||||
USEMODULE += psa_mac_hmac_sha_256_backend_periph
|
||||
else
|
||||
USEMODULE += psa_mac_hmac_sha_256_backend_riot
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_mac_hmac_sha_256_backend_periph,$(USEMODULE)))
|
||||
FEATURES_REQUIRED += periph_hmac_sha_256
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_mac_hmac_sha_256_backend_riot,$(USEMODULE)))
|
||||
USEMODULE += hashes
|
||||
USEMODULE += psa_riot_hashes
|
||||
USEMODULE += psa_riot_hashes_hmac_sha256
|
||||
endif
|
||||
|
||||
# Secure Elements
|
||||
ifneq (,$(filter psa_secure_element,$(USEMODULE)))
|
||||
USEMODULE += psa_se_mgmt
|
||||
USEMODULE += psa_key_slot_mgmt
|
||||
endif
|
||||
|
||||
ifneq (,$(filter psa_secure_element_ateccx08a, $(USEMODULE)))
|
||||
USEPKG += cryptoauthlib
|
||||
USEMODULE += psa_secure_element_config
|
||||
endif
|
||||
154
sys/psa_crypto/Makefile.include
Normal file
154
sys/psa_crypto/Makefile.include
Normal file
@ -0,0 +1,154 @@
|
||||
# include the PSA headers
|
||||
INCLUDES += -I$(RIOTBASE)/sys/psa_crypto/include
|
||||
|
||||
# Workaround for mbedtls namespacing issue
|
||||
# sys/include will include the conflicting header files in psa but requires a psa/*.h structure.
|
||||
INCLUDES += -I$(RIOTBASE)/sys/include/psa_crypto
|
||||
|
||||
backends = $(words $(filter $1_backend_%,$(USEMODULE)))
|
||||
|
||||
# Pseudomodules
|
||||
## Asymmetric
|
||||
PSEUDOMODULES += psa_asymmetric
|
||||
PSEUDOMODULES += psa_asymmetric_ecc_p192r1
|
||||
PSEUDOMODULES += psa_asymmetric_ecc_p192r1_backend_microecc
|
||||
PSEUDOMODULES += psa_asymmetric_ecc_p192r1_backend_periph
|
||||
PSEUDOMODULES += psa_asymmetric_ecc_p192r1_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_asymmetric_ecc_p192r1,$(USEMODULE)))
|
||||
ifneq (1,$(call backends, psa_asymmetric_ecc_p192r1))
|
||||
$(error "One (and only one) backend should be selected for psa_asymmetric_ecc_p192r1")
|
||||
endif
|
||||
endif
|
||||
|
||||
PSEUDOMODULES += psa_asymmetric_ecc_p256r1
|
||||
PSEUDOMODULES += psa_asymmetric_ecc_p256r1_backend_microecc
|
||||
PSEUDOMODULES += psa_asymmetric_ecc_p256r1_backend_periph
|
||||
PSEUDOMODULES += psa_asymmetric_ecc_p256r1_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_asymmetric_ecc_p256r1,$(USEMODULE)))
|
||||
ifneq (1,$(call backends,psa_asymmetric_ecc_p256r1))
|
||||
$(error "One (and only one) backend should be selected for psa_asymmetric_ecc_p256r1")
|
||||
endif
|
||||
endif
|
||||
|
||||
## Cipher
|
||||
PSEUDOMODULES += psa_cipher
|
||||
PSEUDOMODULES += psa_cipher_aes_128_ecb
|
||||
PSEUDOMODULES += psa_cipher_aes_128_ecb_backend_riot
|
||||
|
||||
PSEUDOMODULES += psa_cipher_aes_128_cbc
|
||||
PSEUDOMODULES += psa_cipher_aes_128_cbc_backend_periph
|
||||
PSEUDOMODULES += psa_cipher_aes_128_cbc_backend_riot
|
||||
PSEUDOMODULES += psa_cipher_aes_128_cbc_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_cipher_aes_128_cbc,$(USEMODULE)))
|
||||
ifneq (1,$(call backends,psa_cipher_aes_128_cbc))
|
||||
$(error "One (and only one) backend should be selected for psa_cipher_aes_128_cbc")
|
||||
endif
|
||||
endif
|
||||
|
||||
PSEUDOMODULES += psa_cipher_aes_192_cbc
|
||||
PSEUDOMODULES += psa_cipher_aes_192_cbc_backend_riot
|
||||
PSEUDOMODULES += psa_cipher_aes_192_cbc_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_cipher_aes_192_cbc,$(USEMODULE)))
|
||||
ifneq (1,$(call backends,psa_cipher_aes_192_cbc))
|
||||
$(error "One (and only one) backend should be selected for psa_cipher_aes_192_cbc")
|
||||
endif
|
||||
endif
|
||||
|
||||
PSEUDOMODULES += psa_cipher_aes_256_cbc
|
||||
PSEUDOMODULES += psa_cipher_aes_256_cbc_backend_riot
|
||||
PSEUDOMODULES += psa_cipher_aes_256_cbc_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_cipher_aes_256_cbc,$(USEMODULE)))
|
||||
ifneq (1,$(call backends,psa_cipher_aes_256_cbc))
|
||||
$(error "One (and only one) backend should be selected for psa_cipher_aes_256_cbc")
|
||||
endif
|
||||
endif
|
||||
|
||||
## Hash
|
||||
PSEUDOMODULES += psa_hash
|
||||
PSEUDOMODULES += psa_hash_md5
|
||||
PSEUDOMODULES += psa_hash_md5_backend_riot
|
||||
PSEUDOMODULES += psa_hash_md5_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_hash_md5,$(USEMODULE)))
|
||||
ifneq (1,$(call backends,psa_hash_md5))
|
||||
$(error "One (and only one) backend should be selected for psa_hash_md5")
|
||||
endif
|
||||
endif
|
||||
|
||||
PSEUDOMODULES += psa_hash_sha_1
|
||||
PSEUDOMODULES += psa_hash_sha_1_backend_periph
|
||||
PSEUDOMODULES += psa_hash_sha_1_backend_riot
|
||||
PSEUDOMODULES += psa_hash_sha_1_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_hash_sha_1,$(USEMODULE)))
|
||||
ifneq (1,$(call backends,psa_hash_sha_1))
|
||||
$(error "One (and only one) backend should be selected for psa_hash_sha_1")
|
||||
endif
|
||||
endif
|
||||
|
||||
PSEUDOMODULES += psa_hash_sha_224
|
||||
PSEUDOMODULES += psa_hash_sha_224_backend_periph
|
||||
PSEUDOMODULES += psa_hash_sha_224_backend_riot
|
||||
PSEUDOMODULES += psa_hash_sha_224_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_hash_sha_224,$(USEMODULE)))
|
||||
ifneq (1,$(call backends,psa_hash_sha_224))
|
||||
$(error "One (and only one) backend should be selected for psa_hash_sha_224")
|
||||
endif
|
||||
endif
|
||||
|
||||
PSEUDOMODULES += psa_hash_sha_256
|
||||
PSEUDOMODULES += psa_hash_sha_256_backend_periph
|
||||
PSEUDOMODULES += psa_hash_sha_256_backend_riot
|
||||
PSEUDOMODULES += psa_hash_sha_256_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_hash_sha_256,$(USEMODULE)))
|
||||
ifneq (1,$(call backends,psa_hash_sha_256))
|
||||
$(error "One (and only one) backend should be selected for psa_hash_sha_256")
|
||||
endif
|
||||
endif
|
||||
|
||||
PSEUDOMODULES += psa_hash_sha_512
|
||||
PSEUDOMODULES += psa_hash_sha_512_backend_periph
|
||||
PSEUDOMODULES += psa_hash_sha_512_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_hash_sha_512,$(USEMODULE)))
|
||||
ifneq (1,$(call backends,psa_hash_sha_512))
|
||||
$(error "One (and only one) backend should be selected for psa_hash_sha_512")
|
||||
endif
|
||||
endif
|
||||
|
||||
## MAC
|
||||
PSEUDOMODULES += psa_mac
|
||||
PSEUDOMODULES += psa_mac_hmac_sha_256
|
||||
PSEUDOMODULES += psa_mac_hmac_sha_256_backend_periph
|
||||
PSEUDOMODULES += psa_mac_hmac_sha_256_backend_riot
|
||||
PSEUDOMODULES += psa_mac_hmac_sha_256_custom_backend
|
||||
|
||||
# check that one and only one backend has been selected
|
||||
ifneq (,$(filter psa_mac_hmac_sha_256,$(USEMODULE)))
|
||||
ifneq (1,$(call backends,psa_mac_hmac_sha_256))
|
||||
$(error "One (and only one) backend should be selected for psa_mac_hmac_sha_256")
|
||||
endif
|
||||
endif
|
||||
|
||||
## Secure Elements
|
||||
PSEUDOMODULES += psa_secure_element
|
||||
PSEUDOMODULES += psa_secure_element_asymmetric
|
||||
PSEUDOMODULES += psa_secure_element_config
|
||||
PSEUDOMODULES += psa_secure_element_multiple
|
||||
996
sys/psa_crypto/doc.txt
Normal file
996
sys/psa_crypto/doc.txt
Normal file
@ -0,0 +1,996 @@
|
||||
/**
|
||||
* @defgroup sys_psa_crypto PSA Cryptographic API
|
||||
* @ingroup sys
|
||||
* @brief Implements the PSA Crypto API specification.
|
||||
* @see https://armmbed.github.io/mbed-crypto/html/
|
||||
*
|
||||
* @warning This implementation is not complete and not yet thoroughly tested.
|
||||
* Please do not use this module in production, as it may introduce security issues.
|
||||
*
|
||||
* @note This implementation is not complete and will be successively expanded.
|
||||
*
|
||||
* About {#About}
|
||||
* =====
|
||||
* This module implements the PSA Cryptography API Version 1.1 as specified
|
||||
* [here](https://armmbed.github.io/mbed-crypto/html/).
|
||||
* It provides an OS level access to cryptographic operations and supports software and hardware
|
||||
* backends as well as the use of secure elements.
|
||||
* The API automatically builds a hardware backend for an operation, if there's one available,
|
||||
* otherwise it falls back to software. Specific backends can be configured, if needed.
|
||||
* For configuration options see [Configuration](#configuration).
|
||||
*
|
||||
* PSA Crypto has an integrated key management module, which stores keys internally
|
||||
* without exposing them to applications. To learn how to use keys with PSA,
|
||||
* read [Using Keys](#using-keys).
|
||||
*
|
||||
* A basic usage and configuration example can be found in `examples/psa_crypto`.
|
||||
* For more usage instructions, please read the documentation.
|
||||
*
|
||||
* If you want to add your own crypto backend, see [Porting Guide](#porting-guide).
|
||||
*
|
||||
* Basic Usage
|
||||
* ===
|
||||
* To use PSA Crypto, add `psa/crypto.h` to your includes. This will make all
|
||||
* operations and macros available.
|
||||
*
|
||||
* Call `psa_crypto_init()` before calling any other operation.
|
||||
*
|
||||
* ## Structure Initialization
|
||||
* Whenever you declare a PSA Crypto structure (e.g. operation contexts or key attributes),
|
||||
* it needs to be initialized with zeroes. A structure that is not initialized will be interpreted
|
||||
* by PSA as *active* and can not be used for a new operation.
|
||||
* The example function and macro shown below result in the same thing: A new, inactive structure.
|
||||
*
|
||||
* @code {.c}
|
||||
* // Choose one of these options
|
||||
* psa_hash_operation_t hash_op = psa_hash_operation_init();
|
||||
* psa_hash_operation_t hash_op = PSA_HASH_OPERATION_INIT;
|
||||
* @endcode
|
||||
*
|
||||
* An already active operation can be set to zero by reinitializing it. It then becomes *inactive*
|
||||
* again and can be used for a new operation.
|
||||
*
|
||||
* When errors occur during execution, PSA resets the operation contexts and makes them
|
||||
* *inactive*, to prevent unauthorized access to an operation's state.
|
||||
* Users can also call `psa_<operation>_abort()` anytime in between function calls to do the same.
|
||||
*
|
||||
* Using Keys {#using-keys}
|
||||
* ===
|
||||
* PSA can only operate on keys, that are registered with and stored within the internal
|
||||
* key storage module. This means you need to either generate keys with PSA or
|
||||
* import an existing key.
|
||||
* For this purpose there are a number of
|
||||
* [key management functions](https://armmbed.github.io/mbed-crypto/html/api/keys/management.html)
|
||||
* (external link).
|
||||
*
|
||||
* ## Key Attributes
|
||||
* When creating a key for PSA, the implementation needs to know what kind of key it is
|
||||
* dealing with, what it can be used for, where it's supposed to be stored, etc.
|
||||
* That information needs to be specified in a set of
|
||||
* [Key Attributes](https://armmbed.github.io/mbed-crypto/html/api/keys/attributes.html)
|
||||
* (external link).
|
||||
*
|
||||
* The example below defines attributes for an AES-128 key, which can be used for CBC encryption
|
||||
* and decryption and will be stored in local volatile memory.
|
||||
* @code
|
||||
* // Initializes empty attributes structure
|
||||
* psa_key_attributes_t attributes = psa_key_attributes_init();
|
||||
*
|
||||
* // Set all necessary attributes
|
||||
* psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_VOLATILE);
|
||||
* psa_set_key_type(&attributes, PSA_KEY_TYPE_AES);
|
||||
* psa_set_key_bits(&attributes, 128);
|
||||
* psa_set_key_algorithm(&attributes, PSA_ALG_CBC_NO_PADDING);
|
||||
* psa_set_key_usage_flags(&attributes, (PSA_KEY_USAGE_ENCRYPT | PSA_KEY_USAGE_DECRYPT));
|
||||
* @endcode
|
||||
*
|
||||
* After setting the attributes, an exiting key can be imported:
|
||||
* @code
|
||||
* uint8_t aes_key[] = { ... };
|
||||
* psa_key_id_t key_id = 0; // Will be set by PSA Crypto
|
||||
* psa_status_t status = psa_import_key(&attributes, aes_key, sizeof(aes_key), &key_id);
|
||||
* @endcode
|
||||
* The PSA Crypto implementation will assign an identifier to the key and return it
|
||||
* via the `key_id` parameter. This identifier can then be used for operations with this
|
||||
* specific key.
|
||||
* @code
|
||||
* uint8_t PLAINTEXT[] = { ... };
|
||||
* // Buffer sizes can be calculated with macros
|
||||
* size_t output_buf_size = PSA_CIPHER_ENCRYPT_OUTPUT_SIZE(PSA_KEY_TYPE_AES, PSA_ALG_CBC_NO_PADDING,sizeof(PLAINTEXT));
|
||||
* uint8_t output_buffer[output_buf_size];
|
||||
*
|
||||
* status = psa_cipher_encrypt(key_id, PSA_ALG_CBC_NO_PADDING, PLAINTEXT, sizeof(PLAINTEXT),output_buffer, sizeof(output_buffer), &output_length));
|
||||
* @endcode
|
||||
*
|
||||
* All the supported key types, algorithms and usage flags can be found in the documentation.
|
||||
*
|
||||
* ### Key Lifetime {#key-lifetime}
|
||||
* #### Volatile vs. Persistent
|
||||
* The PSA API specifies two ways of storing keys: volatile and persistent. Volatile
|
||||
* keys will be stored only in RAM, which means they will be destroyed after application
|
||||
* termination or a device reset.
|
||||
* Persistent keys will also be written into flash memory for later access. To destroy
|
||||
* them they must be explicitly deleted with the `psa_destroy_key()` function.
|
||||
*
|
||||
* @note So far this implementation only supports volatile storage. Persistent storage
|
||||
* will be added in the future.
|
||||
*
|
||||
* #### Lifetime Encoding
|
||||
* When creating a key, the user needs to specify a lifetime value, which actually consists
|
||||
* of two values: persistence and location. The location defines the actual memory location
|
||||
* of the key (e.g. whether the key will be stored in RAM, in a hardware protected memory slot
|
||||
* or on an external device like a secure element).
|
||||
*
|
||||
* The persistence value defines whether the key will be stored in RAM (volatile)
|
||||
* in flash (persistent).
|
||||
* Some default values that exist are:
|
||||
* - @ref PSA_KEY_LIFETIME_VOLATILE (stored in local, volatile memory)
|
||||
* - @ref PSA_KEY_LIFETIME_PERSISTENT (stored in local, persistent memory)
|
||||
*
|
||||
* Other lifetime values can be constructed with the macro
|
||||
* `PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION(persistence, location)`.
|
||||
* All supported `PSA_KEY_PERSISTENCE_*` and `PSA_KEY_LOCATION_*` values can be combined.
|
||||
*
|
||||
* In addition to the location values defined by the specification, this implementation also
|
||||
* supports values for [Secure Elements](#secure-elements).
|
||||
*
|
||||
* Configuration {#configuration}
|
||||
* ===
|
||||
* Currently there are two ways to configure PSA Crypto: Kconfig and Makefiles. An example for both
|
||||
* can be found in `RIOT/examples/psa_crypto`.
|
||||
*
|
||||
* ## Kconfig
|
||||
* We recommend using Kconfig and choosing your features in `menuconfig`.
|
||||
* You can access the GUI by calling
|
||||
*
|
||||
* @code
|
||||
* TEST_KCONFIG=1 BOARD=<your board> make menuconfig
|
||||
* @endcode
|
||||
*
|
||||
* from your application directory.
|
||||
* There you can find the available PSA features and options under `System->PSA Crypto`.
|
||||
* If you only select the operations you want to use (e.g. `PSA Ciphers->AES-128 CBC`), Kconfig
|
||||
* will automatically select the best backend for you depending on the board (e.g. a hardware
|
||||
* accelerator if it is available). Optionally you can force a custom backend.
|
||||
*
|
||||
* Further you can specify the exact number of keys you need to store (section `PSA Key Management
|
||||
* Configuration` in `menuconfig`), or choose your [Secure Element](#secure-elements)
|
||||
* configurations.
|
||||
*
|
||||
* Alternatively you can create an `app.config.test` file in your application folder
|
||||
* and choose your symbols there (see `examples/psa_crypto`).
|
||||
*
|
||||
* In the `app.config.test` file, modules can be chosen with the following syntax:
|
||||
* `CONFIG_MODULE_<MODULENAME>=y`, as shown below.
|
||||
* @code
|
||||
* CONFIG_MODULE_PSA_CRYPTO=y
|
||||
* CONFIG_MODULE_PSA_CIPHER=y
|
||||
* CONFIG_MODULE_PSA_CIPHER_AES_128_CBC=y
|
||||
* @endcode
|
||||
*
|
||||
* ## Makefiles
|
||||
* If you don't want to use Kconfig, you can use the traditional way in RIOT of selecting
|
||||
* modules in your application Makefile.
|
||||
*
|
||||
* Here you need to set the base module and individual modules for each operation you need.
|
||||
* The example below also chooses a default backend depending on your board.
|
||||
* @code
|
||||
* // Base module: this is required!
|
||||
* USEMODULE += psa_crypto
|
||||
*
|
||||
* USEMODULE += psa_cipher
|
||||
* USEMODULE += psa_cipher_aes_128_cbc
|
||||
* @endcode
|
||||
*
|
||||
* If desired, you can choose a specific backend at compile time. For this you need to specify
|
||||
* that you want to set a custom backend and then explicitly choose the one you want (see below).
|
||||
* @code
|
||||
* USEMODULE += psa_cipher_aes_128_cbc_custom_backend
|
||||
* USEMODULE += psa_cipher_aes_128_cbc_backend_riot
|
||||
* @endcode
|
||||
*
|
||||
* The currently available modules, are listed [below](#available-modules).
|
||||
*
|
||||
* ## Key Slot Types {#configuration-keys}
|
||||
* The key management of PSA keeps track of keys by storing them in virtual key slot
|
||||
* representations, along with their attributes. Since keys can come in various sizes,
|
||||
* it would be inefficient to allocate the same amount of memory for all keys.
|
||||
* To reduce the amount of memory used for key storage, PSA internally differentiates between
|
||||
* three types of key slots (see below). Depending on the operations your application uses, PSA will
|
||||
* automatically detect the key sizes needed and will allocate the required memory.
|
||||
* The number of key slots allocated of each type is set to five per default, but can be changed by
|
||||
* the user depending on their requirements.
|
||||
*
|
||||
* | Single Key Slot | Asymmetric Key Slot | Protected Key Slot |
|
||||
* |----------------|---------------------|--------------------|
|
||||
* | Single keys or unstructured data,<br>e.g. AES keys or asymmetric<br>public keys in local memory | Asymmetric key pairs<br>(private and public parts) <br>in local memory | Any keys stored on a secure<br>element or on-chip in<br>hardware protected memory |
|
||||
*
|
||||
* If you want to change the default number of allocated key slots you can do so by
|
||||
* updating the number in `menuconfig`, or adding them to the `app.config.test` file like so:
|
||||
* @code
|
||||
* CONFIG_PSA_SINGLE_KEY_COUNT=3
|
||||
* CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1
|
||||
* CONFIG_PSA_PROTECTED_KEY_COUNT=2
|
||||
* @endcode
|
||||
*
|
||||
* When using Makefiles, you can pass CFLAGS as shown below.
|
||||
* @code
|
||||
* CFLAGS += -DCONFIG_PSA_SINGLE_KEY_COUNT=3
|
||||
* CFLAGS += -DCONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT=1
|
||||
* CFLAGS += -DCONFIG_PSA_PROTECTED_KEY_COUNT=2
|
||||
* @endcode
|
||||
*
|
||||
* ## Available Modules {#available-modules}
|
||||
* Below are the currently available modules.
|
||||
* No matter which operation you need, you always have to choose the base module.
|
||||
* If you want to specify a backend other than the default, you need to select
|
||||
* `psa_<operation>_custom_backend` in addition to the actual backend module.
|
||||
*
|
||||
* The names listed are are the version used in makefiles with the
|
||||
* `USEMODULE += <modulename>` syntax.
|
||||
* In Kconfig you don't need to know the exact names, you can simply choose the features in
|
||||
* `menuconfig`.
|
||||
* When using `app.config.test` files in your application directory, you need to write the
|
||||
* names in uppercase and add the prefix `CONFIG_MODULE_` to all of them.
|
||||
*
|
||||
* ### Asymmetric Crypto
|
||||
* - Base: psa_asymmetric
|
||||
*
|
||||
* #### NIST ECC P192
|
||||
* - psa_asymmetric_ecc_p192r1
|
||||
* - psa_asymmetric_ecc_p192r1_backend_periph
|
||||
* - psa_asymmetric_ecc_p192r1_custom_backend
|
||||
* - psa_asymmetric_ecc_p192r1_backend_microecc
|
||||
*
|
||||
* #### NIST ECC P192
|
||||
* - psa_asymmetric_ecc_p256r1
|
||||
* - psa_asymmetric_ecc_p256r1_backend_periph
|
||||
* - psa_asymmetric_ecc_p256r1_custom_backend
|
||||
* - psa_asymmetric_ecc_p256r1_backend_microecc
|
||||
*
|
||||
* ### Ciphers
|
||||
* - Base: psa_cipher
|
||||
*
|
||||
* #### AES ECB
|
||||
* - psa_cipher_aes_128_ecb
|
||||
* - psa_cipher_aes_128_ecb_backend_riot
|
||||
*
|
||||
* #### AES CBC
|
||||
* - psa_cipher_aes_128_cbc
|
||||
* - psa_cipher_aes_128_cbc_backend_periph
|
||||
* - psa_cipher_aes_128_cbc_custom_backend
|
||||
* - psa_cipher_aes_128_cbc_backend_riot
|
||||
* - psa_cipher_aes_192_cbc
|
||||
* - psa_cipher_aes_192_cbc_custom_backend
|
||||
* - psa_cipher_aes_192_cbc_backend_riot
|
||||
* - psa_cipher_aes_256_cbc
|
||||
* - psa_cipher_aes_256_cbc_custom_backend
|
||||
* - psa_cipher_aes_256_cbc_backend_riot
|
||||
*
|
||||
* ### Hashes
|
||||
* - Base: psa_hash
|
||||
*
|
||||
* #### MD5
|
||||
* - psa_hash_md5
|
||||
* - psa_hash_md5_custom_backend
|
||||
* - psa_hash_md5_backend_riot
|
||||
*
|
||||
* #### SHA 1
|
||||
* - psa_hash_sha_1
|
||||
* - psa_hash_sha_1_backend_periph
|
||||
* - psa_hash_sha_1_custom_backend
|
||||
* - psa_hash_sha_1_backend_riot
|
||||
*
|
||||
* #### SHA 224
|
||||
* - psa_hash_sha_224
|
||||
* - psa_hash_sha_224_backend_periph
|
||||
* - psa_hash_sha_224_custom_backend
|
||||
* - psa_hash_sha_224_backend_riot
|
||||
*
|
||||
* #### SHA 256
|
||||
* - psa_hash_sha_256
|
||||
* - psa_hash_sha_256_backend_periph
|
||||
* - psa_hash_sha_256_custom_backend
|
||||
* - psa_hash_sha_256_backend_riot
|
||||
*
|
||||
* #### SHA 512
|
||||
* - psa_hash_sha_512
|
||||
* - psa_hash_sha_512_backend_periph
|
||||
* - psa_hash_sha_512_custom_backend
|
||||
*
|
||||
* ### MAC
|
||||
* - Base: psa_mac
|
||||
*
|
||||
* #### HMAC SHA 256
|
||||
* - psa_mac_hmac_sha_256
|
||||
* - psa_mac_hmac_sha_256_backend_periph
|
||||
* - psa_mac_hmac_sha_256_custom_backend
|
||||
* - psa_mac_hmac_sha_256_backend_riot
|
||||
*
|
||||
* ### Secure Elements
|
||||
* Base:
|
||||
*
|
||||
* - psa_secure_element
|
||||
* - psa_secure_element_multiple
|
||||
*
|
||||
* #### SE Types
|
||||
* - psa_secure_element_ateccx08a
|
||||
* - psa_secure_element_ateccx08a_ecc_p256
|
||||
*
|
||||
* Random Number Generation {#rng}
|
||||
* ===
|
||||
* Currently uses the [RIOT Random Module](#sys_random) as a backend.
|
||||
* See the documentation for configuration options.
|
||||
*
|
||||
* Secure Elements {#secure-elements}
|
||||
* ===
|
||||
*
|
||||
* An example showing the use of SEs can be found in `examples/psa_crypto`.
|
||||
*
|
||||
* To use secure elements, you first need to assign a static location value to each device,
|
||||
* so PSA can find it. If you only use one device, you can use
|
||||
* `PSA_KEY_LOCATION_PRIMARY_SECURE_ELEMENT`. For additional devices this value must be within
|
||||
* the range of `PSA_KEY_LOCATION_SE_MIN` and `PSA_KEY_LOCATION_SE_MAX`.
|
||||
* When booting the system, the `auto_init` module in RIOT will automatically register the device
|
||||
* with the location with PSA Crypto.
|
||||
*
|
||||
* You can now import or create keys on the secure element by constructing a key lifetime containing
|
||||
* a device's location value.
|
||||
*
|
||||
* @code {.c}
|
||||
* psa_key_lifetime_t lifetime =
|
||||
* PSA_KEY_LIFETIME_FROM_PERSISTENCE_AND_LOCATION (PSA_KEY_LIFETIME_VOLATILE,
|
||||
PSA_KEY_LOCATION_PRIMARY_SECURE_ELEMENT);
|
||||
* @endcode
|
||||
*
|
||||
* Some secure elements come with their own key management and device configurations. In this case
|
||||
* the configuration parameters must be passed to PSA Crypto during the registration. For this, you
|
||||
* need to define a `psa_se_config_t` structure containing the configuration.
|
||||
* PSA Crypto will use this structure to keep track of what types of keys are allowed on the device
|
||||
* and how much storage is available.
|
||||
* Where this structure should be placed, how it looks and what parameters are required depends
|
||||
* on the type of your device.
|
||||
*
|
||||
* A good place to define that structure and the location values is a drivers `<driver>_params.h`
|
||||
* file, but this may vary depending on how your device is integrated in RIOT.
|
||||
*
|
||||
* For detailed, device specific information, please check the device driver documentation or
|
||||
* the example.
|
||||
*
|
||||
* ## Available Devices and Drivers
|
||||
* - ATECCX08A: [Microchip Cryptoauthlib as a PSA backend](#psa-cryptoauthlib)
|
||||
*
|
||||
* ## Main SE Configuration
|
||||
* To use SEs, the appropriate modules must be chosen in Kconfig:
|
||||
* @code
|
||||
* CONFIG_PSA_SECURE_ELEMENT=y
|
||||
* CONFIG_PSA_SECURE_ELEMENT_ATECCX08A=y // device example
|
||||
* CONFIG_PSA_SECURE_ELEMENT_ATECCX08A_ECC=y
|
||||
* @endcode
|
||||
*
|
||||
* or added to the the Makefile:
|
||||
* @code
|
||||
* USEMODULE += psa_secure_element
|
||||
* USEMODULE += psa_secure_element_ateccx08a // device example
|
||||
* USEMODULE += psa_secure_element_ateccx08a_ecc_p256
|
||||
* @endcode
|
||||
*
|
||||
* This implementation supports the use of one or more secure elements (SE) as backends. In this
|
||||
* case the number of used secure elements must be specified (must be at least 2 and at most 255).
|
||||
* When using more than one SE, add
|
||||
* @code
|
||||
* CONFIG_PSA_SECURE_ELEMENT_MULTIPLE=y
|
||||
* CONFIG_PSA_MAX_SE_COUNT=2 // or any other number between 2 and 255
|
||||
* @endcode
|
||||
*
|
||||
* or, respectively,
|
||||
*
|
||||
* @code
|
||||
* USEMODULE += psa_secure_element_multiple
|
||||
* CFLAGS += -DCONFIG_PSA_MAX_SE_COUNT=2 // or any other number between 2 and 255
|
||||
* @endcode
|
||||
*
|
||||
* Porting Guide {#porting-guide}
|
||||
* ===
|
||||
* This porting guide focuses on how to add your software library or hardware driver
|
||||
* as a backend to PSA Crypto without actually touching the PSA implementation.
|
||||
* We will provide some [general information](#porting-general) and then some case
|
||||
* examples for different kinds of backends:
|
||||
* - [Software Libraries](#porting-software)
|
||||
* - [Hardware Drivers](#porting-hardware)
|
||||
* - [Secure Elements](#porting-secure-elements)
|
||||
*
|
||||
* Some examples to look at are:
|
||||
* - [RIOT hash module](#sys_hashes)
|
||||
* - [RIOT cipher module](#sys_crypto)
|
||||
* - [Micro-ECC](#pkg_micro_ecc)
|
||||
* - [CryptoCell 310 driver](#pkg_driver_cryptocell_310).
|
||||
*
|
||||
* An example integrating a secure element can be found in the
|
||||
* [Cryptoauthlib Package](#pkg_cryptoauthlib).
|
||||
*
|
||||
* ## General Information {#porting-general}
|
||||
* ### Error Values
|
||||
* You should always check the status of your function calls and translate your library's or
|
||||
* driver's errors to PSA error values (please be as thorough as possible).
|
||||
* The PSA Crypto specification describes exactly what kind of error values should be returned
|
||||
* by which function. Please read the API documentation and comply with the instructions.
|
||||
* We recommend writing a`<mylibrary>_to_psa_error()` function right in the beginning (see for
|
||||
* example `CRYS_to_psa_error()` in
|
||||
* `pkg/driver_cryptocell_310/psa_cryptocell_310/error_conversion.c`).
|
||||
*
|
||||
* ### The Build System
|
||||
* As mentioned before, there are two ways of selecting build time configurations in RIOT: Kconfig
|
||||
* and Makefiles.
|
||||
* Kconfig dependency resolution is currently an experimental feature and will at some point
|
||||
* replace Makefiles. Until then, our implementation needs to support both, which means we need
|
||||
* to define features and symbols in multiple places.
|
||||
* Luckily, the modules have the exact same names in both systems, which makes the transfer easier.
|
||||
* The examples below show both ways.
|
||||
*
|
||||
* ### Modules {#module-names}
|
||||
* In RIOT, module names are generated from path names, so if you create a directory for
|
||||
* your sourcefiles, the module name will be the same as the directory name. It is possible
|
||||
* to change that by declaring a new module name in the Makefile by adding the line
|
||||
* your_module_name`.
|
||||
*
|
||||
* If you leave it like this, all sourcefiles in the path corresponding to the module name will be
|
||||
* built (e.g. if you choose to module `hashes`, all files in `sys/hashes` will be included).
|
||||
* For better configurability it is possible to add submodules (see
|
||||
* `sys/hashes/psa_riot_hashes` for example).
|
||||
* In that case the base module name will be the directory name and each file inside the directory
|
||||
* becomes its own submodule that must be explicitly chosen. The module name will then be the
|
||||
* directory name with the file name as a postfix.
|
||||
* For example:
|
||||
* @code
|
||||
* USEMODULE += hashes
|
||||
* USEMODULE += psa_riot_hashes
|
||||
* USEMODULE += psa_riot_hashes_sha_256
|
||||
*
|
||||
* will build the file at `sys/hashes/psa_riot_hashes/sha_256.c`, but none of the other files in
|
||||
* the directory).
|
||||
*
|
||||
* To enable submodules for your implementation add the following to the directory makefile:
|
||||
* @code
|
||||
* BASE_MODULE := psa_<modulename>
|
||||
* SUBMODULES := 1
|
||||
* @endcode
|
||||
*
|
||||
* We also need to create so-called pseudomodules for each available submodule.
|
||||
* Those must follow the scheme `psa_<modulename>_<filename>`.
|
||||
* Where they are declared depends on where your module is located. Pseudomodules in `RIOT/sys` must
|
||||
* be added in `pseudomodules.inc.mk`.
|
||||
* When integrating packages or drivers, the pseudomodules can be added in the `Makefile.include`
|
||||
* file of the individual module's directory (see `pkg/micro-ecc/Makefile.include`).
|
||||
*
|
||||
* When adding backends to PSA Crypto, please name your modules in ways that fit within the
|
||||
* current naming scheme: `psa_<library>_<algorithm>`. Also, when adding software libraries and
|
||||
* hardware drivers, use the submodule approach. That makes PSA Crypto more configurable.
|
||||
*
|
||||
* The drawback of the submodule approach is, that if one of our sourcefiles depends on
|
||||
* another sourcefile in the same folder, we need to select it explicitly. For example, in
|
||||
* `pkg/driver_cryptocell_310/psa_cryptocell_310` you can see that there are some common source
|
||||
* files that all the others use (e.g. for hashes there is a `hashes_common.c` file).
|
||||
*
|
||||
* If that is the case for your driver, you need to make sure the modules are selected in
|
||||
* the Kconfig file as well as the `Makefile.dep` file (see `psa_cryptocell_310/Makefile.dep` or
|
||||
* `psa_cryptocell_310/Kconfig`).
|
||||
*
|
||||
* ### Adding Glue Code {#glue-code}
|
||||
* We define a number of wrapper APIs, which are called by PSA to invoke crypto backends.
|
||||
* Software libraries and hardware drivers use the same methods, secure elements are handled
|
||||
* in a different way (see [Case Example – Secure Elements](#porting-secure-elements) for details).
|
||||
*
|
||||
* The names, parameters and return values for wrapper methods are defined in header files in
|
||||
* `sys/psa_crypto/include/psa_<algorithm>.h`.
|
||||
* The functions declared in those files are the ones that are currently supported by this
|
||||
* PSA implementation. They will be extended in the future.
|
||||
*
|
||||
* You need to implement those functions with glue code calling your library or driver code
|
||||
* and converting types and error values between PSA and your backend.
|
||||
* Below is an example of how this might look (it's very reduced, your library may need
|
||||
* much more glue code).
|
||||
* @code {.c}
|
||||
* 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 status = <libraryname>_<sign_hash_func>(key_buffer, hash, hash_length,
|
||||
* signature, signature_length, curve);
|
||||
*
|
||||
* if (status != SUCCESS) {
|
||||
* return <libraryname>_status_to_psa_error(status);
|
||||
* }
|
||||
*
|
||||
* (void)alg;
|
||||
* (void)attributes;
|
||||
* (void)key_buffer_size;
|
||||
* return PSA_SUCCESS;
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* ### Operation Contexts
|
||||
* Some cryptographic operations use driver specific context to store the operation state in
|
||||
* between function calls. These must be defined somewhere. Examples can be found in
|
||||
* `pkg/driver_cryptocell_310/include/psa_periph_hashes_ctx.h` and
|
||||
* `sys/include/hashes/psa/riot_hashes.h`.
|
||||
*
|
||||
* When defining the contexts for a hardware driver, all you need to do is add a file called
|
||||
* `psa_periph_<algorithm>_ctx.h` to your driver's include folder and define the available types
|
||||
* (see supported [types](#supported-types) below).
|
||||
* Those files are automatically included in `crypto_includes.h` and it is important that they
|
||||
* always have the same name for each algorithm.
|
||||
*
|
||||
* When defining the contexts for a software library, the headerfile should be called
|
||||
* `<library>_<algorithm>.h` (e.g. `riot_hashes.h`) and must be added to `crypto_includes.h` as
|
||||
* shown below:
|
||||
* @code
|
||||
* #if IS_USED(MODULE_PSA_<LIBRARY>_<ALGORITHM>)
|
||||
* #include "<library>/<library>_<algorithm>.h"
|
||||
* #endif
|
||||
* @endcode
|
||||
*
|
||||
* When defining the context types, those must always depend on the specific algorithm module,
|
||||
* for example
|
||||
* @code
|
||||
* #if IS_USED(MODULE_PSA_<LIBRARY>_HASHES_SHA_256)
|
||||
* #include "path/to/headerfile_containing_the_driver_context_definition"
|
||||
*
|
||||
* typedef <library_context_type_t> psa_hashes_sha256_ctx_t;
|
||||
* #endif
|
||||
* @endcode
|
||||
*
|
||||
* #### Hashes {#supported-types}
|
||||
* - `psa_hashes_md5_ctx_t`
|
||||
* - `psa_hashes_sha1_ctx_t`
|
||||
* - `psa_hashes_sha224_ctx_t`
|
||||
* - `psa_hashes_sha256_ctx_t`
|
||||
* - `psa_hashes_sha512_ctx_t`
|
||||
*
|
||||
* #### Ciphers
|
||||
* - `psa_cipher_aes_128_ctx_t`
|
||||
* - `psa_cipher_aes_192_ctx_t`
|
||||
* - `psa_cipher_aes_256_ctx_t`
|
||||
*
|
||||
* Secure Elements need their own contexts. For this,
|
||||
* see [Case Example – Secure Elements](#porting-secure-elements).
|
||||
*
|
||||
* ## Adding a Backend
|
||||
* The integration of hardware drivers, software libraries and secure element drivers
|
||||
* differs a bit. Below we describe the necessary steps for each of them.
|
||||
*
|
||||
* ### Case Example – A Software Library {#porting-software}
|
||||
* Software libraries are the easiest backends, because they are not platform or hardware
|
||||
* specific. They can generally run on all platforms in RIOT and we can
|
||||
* combine different software backends for different operations (we could, for example,
|
||||
* use the Micro-ECC package for ECC NIST curves and the C25519 package for operations with
|
||||
* the Curve25519).
|
||||
*
|
||||
* Let's say we have an imaginary software library called `FancyCrypt` and want to use
|
||||
* it as a backend of PSA. We've already added it to RIOT as a third party package in
|
||||
* `pkg/fancycrypt`.
|
||||
* Our library provides hashes and elliptic curve operations and to make it accessible to
|
||||
* PSA Crypto we need to write wrappers for our API calls.
|
||||
*
|
||||
* First we create a folder called `psa_fancycrypt` in the package directory. Inside we create
|
||||
* a file with the name of each operation you want to integrate, e.g. `p256.c` and
|
||||
* `hashes_sha_224.c` (when adding operations, remember that the path of the files will also
|
||||
* be the [module name](#module-names), so please comply with the current naming scheme).
|
||||
*
|
||||
* In these files we need to implement the methods that are called by PSA as described
|
||||
* [above](#glue-code).
|
||||
*
|
||||
* #### Adding Makefiles
|
||||
* We add a Makefile to the `psa_fancycrypt` folder with the following content:
|
||||
* @code {.c}
|
||||
* BASE_MODULE := psa_fancycrypt
|
||||
* SUBMODULES := 1
|
||||
*
|
||||
* include $(RIOTBASE)/Makefile.base
|
||||
* @endcode
|
||||
*
|
||||
* This tells RIOT that the `psa_fancycrypt` module has submodules, which can be selected
|
||||
* individually.
|
||||
*
|
||||
* In `pkg/fancycrypt` we now need to declare explicit pseudomodules in `Makefile.include` and add
|
||||
* the `psa_fancycrypt` folder to the source files and the `sys/psa_crypto/include` folder to the
|
||||
* includes.
|
||||
* These should be dependent on the PSA Crypto module as shown below.
|
||||
*
|
||||
* @code
|
||||
* ifneq (,$(filter psa_fancycrypt_%, $(USEMODULE)))
|
||||
* PSEUDOMODULES += psa_fancycrypt_hashes_sha_256
|
||||
* PSEUDOMODULES += psa_fancycrypt_p256
|
||||
* DIRS += $(RIOTPKG)/fancycrypt/psa_fancycrypt
|
||||
* INCLUDES += -I$(RIOTBASE)/sys/psa_crypto/include
|
||||
* endif
|
||||
* @endcode
|
||||
*
|
||||
* If the implementation has any dependencies, they need to be added in `Makefile.dep`, for example:
|
||||
* @code
|
||||
* USEMODULE += psa_fancycrypt
|
||||
* USEMODULE += psa_fancycrypt_error_conversion
|
||||
*
|
||||
* ifneq (,$(filter psa_fancycrypt_hashes_sha1,$(USEMODULE)))
|
||||
* USEMODULE += psa_fancycrypt_hashes_common
|
||||
* endif
|
||||
* @endcode
|
||||
*
|
||||
* #### Adding a Kconfig file
|
||||
* We add a file called `Kconfig` to the `psa_fancycrypt` folder. Here we declare
|
||||
* the modules for Kconfig like so:
|
||||
* @code
|
||||
* config MODULE_PSA_FANCYCRYPT_HASHES_SHA_256
|
||||
* bool
|
||||
* depends on MODULE_PSA_CRYPTO
|
||||
* select MODULE_PSA_FANCYCRYPT
|
||||
*
|
||||
* config MODULE_PSA_FANCYCRYPT_P256
|
||||
* bool
|
||||
* depends on MODULE_PSA_CRYPTO
|
||||
* select MODULE_PSA_FANCYCRYPT
|
||||
*
|
||||
* config MODULE_PSA_FANCYCRYPT
|
||||
* bool
|
||||
* @endcode
|
||||
*
|
||||
* If the implementation has any dependencies, we can select them in this Kconfig file:
|
||||
* @code
|
||||
* config MODULE_PSA_FANCYCRYPT_HASHES_SHA_256
|
||||
* bool
|
||||
* depends on MODULE_PSA_CRYPTO
|
||||
* select MODULE_PSA_FANCYCRYPT
|
||||
* select MODULE_PSA_FANCYCRYPT_HASHES_COMMON
|
||||
* select MODULE_PSA_FANCYCRYPT_ERROR_CONVERSION
|
||||
* @endcode
|
||||
*
|
||||
* In `pkg/fancycrypt/Kconfig` we need to add the line
|
||||
* @code
|
||||
* rsource "psa_fancycrypt/Kconfig"
|
||||
* @endcode
|
||||
* at the bottom.
|
||||
*
|
||||
* #### Telling PSA Crypto about it
|
||||
* To be able to choose `fancycrypt` as a PSA backend, we need to add the option to the Kconfig
|
||||
* and Makefiles of the PSA Crypto Module.
|
||||
*
|
||||
* In `sys/psa_crypto/` we need to modify `Kconfig.asymmetric`, `sys/psa_crypto/Kconfig.hashes`,
|
||||
* `Makefile.dep` and `Makefile.include`.
|
||||
*
|
||||
* To `Kconfig.asymmetric` we need to add
|
||||
* @code
|
||||
* config MODULE_PSA_ASYMMETRIC_ECC_P256R1_BACKEND_FANCYCRYPT
|
||||
* bool "FancyCrypt Package"
|
||||
* select PACKAGE_FANCYCRYPT
|
||||
* select MODULE_PSA_FANCYCRYPT_P256
|
||||
* @endcode
|
||||
* This will expose FancyCrypt as a backend option in PSA and then enable all the necessary
|
||||
* features, when users select it.
|
||||
* You need to do the same thing for the hash operation in `Kconfig.hashes`.
|
||||
*
|
||||
* To achieve the same thing with Makefiles we need to do this in two places:
|
||||
* In `Makefile.include` there are some existing pseudomodules for asymmetric crypto and hashes.
|
||||
* There we need to create the backend modules for FancyCrypt by adding
|
||||
*
|
||||
* @code
|
||||
* PSEUDOMODULES += psa_asymmetric_ecc_p256r1_backend_fancycrypt
|
||||
* @endcode
|
||||
*
|
||||
* and
|
||||
*
|
||||
* @code
|
||||
* PSEUDOMODULES += psa_hash_sha_256_backend_fancycrypt
|
||||
* @endcode
|
||||
*
|
||||
* The automatic module selection happens in `Makefile.dep`. To the place where exiting P256 curves
|
||||
* and hashes are selected we add cases for our backend modules:
|
||||
*
|
||||
* @code
|
||||
* ifneq (,$(filter psa_asymmetric_ecc_p256r1_backend_fancycrypt,$(USEMODULE)))
|
||||
* USEPKG += fancycrypt
|
||||
* USEMODULE += psa_fancycrypt
|
||||
* USEMODULE += psa_fancycrypt_p256
|
||||
* endif
|
||||
* @endcode
|
||||
*
|
||||
* Now you should be able to select your package as a backend for PSA Crypto and use it to perform
|
||||
* operations.
|
||||
*
|
||||
* ### Case Example – A Hardware Driver {#porting-hardware}
|
||||
* The first steps of porting a hardware driver are the same as for the software library.
|
||||
* Only we skip the last part where we add the modules to the PSA Crypto Kconfig and Makefiles
|
||||
* and do something else instead.
|
||||
*
|
||||
* Hardware drivers are treated a little differently, mostly because they are tied to a specific
|
||||
* platform and users can not just choose a different driver for their accelerator.
|
||||
* Therefore we just want PSA Crypto to automatically use this driver whenever it runs on the
|
||||
* corresponding platform, which means that we have to add some additional options and features,
|
||||
* not only to the driver but also to the CPU it belongs to.
|
||||
* A good example for this is the [CryptoCell 310 driver](#pkg_driver_cryptocell_310) for the
|
||||
* accelerator on the [nRF52840 CPU](#cpu_nrf52).
|
||||
*
|
||||
* Now, let's say we have a CPU called `myCPU` with an on-chip accelerator called
|
||||
* `speedycrypt`. Let's say that `speedycrypt` provides hashes and ECC curves.
|
||||
* The vendor provides a driver, which we already have included in RIOT as a package.
|
||||
* Also we've followed the steps in the [glue code section](#glue-code) and provide a folder called
|
||||
* `pkg/driver_speedycrypt/psa_speedycrypt` with the required wrapper files.
|
||||
* We have also added the module names in a Kconfig file and in the Makefiles.
|
||||
*
|
||||
* #### Telling PSA Crypto about it
|
||||
* This is where we diverge from the software library example. If you take a look at the available
|
||||
* backends in PSA, you'll notice one with the postfix `*_BACKEND_PERIPH` for each available
|
||||
* algorithm. **Periph** here is short for *peripheral hardware accelerator*.
|
||||
* The `*_BACKEND_PERIPH` modules depend on the presence of such an accelerator. They are a generic
|
||||
* module for all crypto hardware accelerators and will automatically resolve to the driver that is
|
||||
* associated with the available accelerator.
|
||||
*
|
||||
* Before we're able to use it we need to tell RIOT that those hardware features exist for
|
||||
* our `myCPU` (see `cpu/nrf52/Kconfig` and `cpu/nrf52/Makefile.features` as an example).
|
||||
* In `cpu/myCPU` we add all the provided features as shown below.
|
||||
*
|
||||
* Files we need to touch:
|
||||
* - `cpu/myCPU/Makefile.features`
|
||||
* - `cpu/myCPU/Kconfig`
|
||||
* - `cpu/myCPU/periph/Makefile.dep`
|
||||
* - `cpu/myCPU/periph/Kconfig`
|
||||
* - When defining new features: `RIOT/kconfigs/Kconfig.features`
|
||||
*
|
||||
* **cpu/myCPU/Makefile.features:**
|
||||
* @code
|
||||
* FEATURES_PROVIDED += periph_speedycrypt // General feature for the acclerator
|
||||
* FEATURES_PROVIDED += periph_hash_sha_256
|
||||
* FEATURES_PROVIDED += periph_ecc_p256r1
|
||||
* @endcode
|
||||
*
|
||||
* **cpu/myCPU/Kconfig:**
|
||||
* @code
|
||||
* config CPU_FAM_MYCPU
|
||||
* bool
|
||||
* select CPU_SOME_FEATURES
|
||||
* ...
|
||||
* select HAS_PERIPH_HASH_SHA_256
|
||||
* select HAS_PERIPH_ECC_P256R1
|
||||
* select HAS_PERIPH_SPEEDYCRYPT
|
||||
* @endcode
|
||||
* The `HAS_PERIPH_*` symbols are defined in ``. If your device
|
||||
* provides capabilities that are not yet defined, you can add them to that file.
|
||||
*
|
||||
* Next we need to define selectable modules for this in the `cpu/myCPU/periph` folder, which
|
||||
* then automatically enable the driver. An example for this is `cpu/nrf52/periph`.
|
||||
* We add the following to the `cpu/myCPU/periph/Kconfig` file and `cpu/myCPU/periph/Makefile.dep`:
|
||||
*
|
||||
* **cpu/myCPU/periph/Makefile.dep:**
|
||||
* @code
|
||||
* ifneq (,$(filter periph_hash_sha_256,$(USEMODULE)))
|
||||
* USEPKG += driver_speedycrypt
|
||||
* USEMODULE += psa_speedycrypt_hashes_sha256
|
||||
* endif
|
||||
* @endcode
|
||||
*
|
||||
* **cpu/myCPU/periph/Kconfig:**
|
||||
* @code
|
||||
* config MODULE_PERIPH_FANCYCRYPT
|
||||
* bool
|
||||
* depends on HAS_PERIPH_FANCYCRYPT
|
||||
* select PACKAGE_DRIVER_FANCYCRYPT
|
||||
*
|
||||
* config MODULE_PERIPH_HASH_SHA_256
|
||||
* bool
|
||||
* depends on HAS_PERIPH_HASH_SHA_256
|
||||
* select MODULE_PERIPH_SPEEDYCRYPT
|
||||
* select MODULE_PSA_SPEEDYCRYPT_HASHES_SHA256
|
||||
* @endcode
|
||||
*
|
||||
* Here we basically say "If the user chooses the `periph_hash_sha_256 module`, also select the
|
||||
* `periph_speedycrypt` feature, which will then enable the speedycrypt driver". Of course you need
|
||||
* to do this for all your available features.
|
||||
*
|
||||
* Now, if you build PSA Crypto with default configurations, it should automatically detect that
|
||||
* your board has a hardware accelerator for hashes and ECC operations and build the hardware
|
||||
* driver as a backend.
|
||||
*
|
||||
* ### Case Example – A Secure Element Driver {#porting-secure-elements}
|
||||
* Secure elements (SEs) are handled almost completely separate from the other backends. When we use
|
||||
* software libraries or hardware drivers, we only build one implementation per algorithm.
|
||||
* When it comes to secure elements we want to be able to build them in addition to the other
|
||||
* backends and we may want to connect and use more than one of them at the same time.
|
||||
* Another difference is that when using software libraries and hardware drivers, PSA handles the
|
||||
* storage of key material. When using SEs, keys are stored on the SE, which means, we need
|
||||
* additional functionality for the key management.
|
||||
*
|
||||
* An existing example in RIOT is the Microchip ATECCX08A device family, whose driver can be found
|
||||
* in `pkg/cryptoauthlib`.
|
||||
*
|
||||
* PSA Crypto has an integrated SE driver registry, which stores all registered drivers in a list.
|
||||
* When an application calls a cryptographic operation that's supposed to be performed by a secure
|
||||
* element, the registry will find the correct driver in the list and PSA will invoke the operation.
|
||||
* Each driver is stored with a context that contains persistent as well as transient driver data.
|
||||
* Transient driver data can be anything the driver needs to function. Persistent data is supposed
|
||||
* to be used to keep track of how many keys are stored on the device and if there is still some
|
||||
* free space available.
|
||||
*
|
||||
* @note Currently PSA does not support persistent storage, so the persistent driver data
|
||||
* is not really persistent, yet. Once persistent storage is implemented, this data
|
||||
* will be stored, so the implementation can find already existing keys again after
|
||||
* a reboot.
|
||||
*
|
||||
* For this example we integrate an imaginary SE called `superSE`, which comes with a driver called
|
||||
* `superSE_lib`. Again, we assume that we have already added the driver as a package in RIOT and it
|
||||
* can be found at `pkg/superse_lib`.
|
||||
*
|
||||
* #### Adding the Glue Code
|
||||
* Secure element drivers need to implement a different API than the other backends. It is defined
|
||||
* [here](#sys_psa_crypto_se_driver).
|
||||
* In our package folder we now create a new folder called `psa_superse_driver` and add a source
|
||||
* file called `psa_superse_lib_driver.c`. Here we now implement glue code for all the cryptographic
|
||||
* operations our SE supports.
|
||||
*
|
||||
* You will notice that the SE interface also provides some key management functions. This is
|
||||
* because keys are stored on the device and PSA can not access the memory and key data itself,
|
||||
* but needs to tell the driver to do it.
|
||||
*
|
||||
* ### Operation Contexts
|
||||
* Some operations need driver specific contexts. For secure elements these are wrapped in types
|
||||
* defined in `crypto_contexts.h` (currently only `psa_se_cipher_context_t` is supported).
|
||||
* In this header file add operation contexts that belong to your driver to the available SE
|
||||
* context unions as shown in the example below:
|
||||
*
|
||||
* @code
|
||||
* typedef struct {
|
||||
* union driver_context {
|
||||
* unsigned dummy;
|
||||
* #if IS_USED(MODULE_PSA_SECURE_ELEMENT_ATECCX08A) || defined(DOXYGEN)
|
||||
* atca_aes_cbc_ctx_t atca_aes_cbc;
|
||||
* #endif
|
||||
* #if IS_USED(MODULE_PSA_SECURE_ELEMENT_SUPERSE) || defined(DOXYGEN)
|
||||
* superse_cipher_ctx_t superse_aes_cbc;
|
||||
* #endif
|
||||
* } drv_ctx;
|
||||
* } psa_se_cipher_context_t;
|
||||
* @endcode
|
||||
*
|
||||
* #### Allocation
|
||||
* The first thing PSA will do, when an application creates a key on an SE, is ask the driver to
|
||||
* find a free key slot on the device. This is what the `allocate` function is for. How exactly
|
||||
* the slot is allocated, depends on the driver.
|
||||
* It may be possible to query that information directly from the device. If that is not possible,
|
||||
* we can use the persistent data stored in the driver context. An example for this can be
|
||||
* found in `pkg/cryptoauthlib/psa_atca_driver/psa_atca_se_driver.c`.
|
||||
* This example requires the user to provide information about the configurations for each key slot,
|
||||
* which is then stored in the persistent driver data and used for key management (for a better
|
||||
* description read [Using Cryptoauthlib as a backend for PSA Crypto](#psa-cryptoauthlib)).
|
||||
* At this point you can decide what the best approach for your device is.
|
||||
*
|
||||
* The `allocate` function should then return some reference to the slot it has allocated
|
||||
* for the key (possibly a pointer or a slot number). Next PSA Crypto will invoke the `import`
|
||||
* or `generate` function to store a key.
|
||||
*
|
||||
* #### Using Persistent Data
|
||||
* When you want to use persistent data to keep track of keys, you should utilize the
|
||||
* `psa_se_config_t` structure, which is declared in `crypto_se_config.h`.
|
||||
* You can define a structure that can hold your device configuration and make sure it is available
|
||||
* then your SE is used.
|
||||
*
|
||||
* #### Making the Methods Available
|
||||
* At the bottom of the wrapper code, define structures with pointers to the available methods.
|
||||
* For example if you have implemented a `superse_allocate` and `superse_generate_key` function,
|
||||
* you need to add a `psa_drv_se_key_management_t` structure as shown below. Fill the unimplemented
|
||||
* methods with `NULL` pointers.
|
||||
* The last structure should be a `psa_drv_se_t` struct containing pointers to the other structures.
|
||||
* That one will be stored during driver registration to get access to all the implemented
|
||||
* functions.
|
||||
*
|
||||
* @code {.c}
|
||||
* static psa_drv_se_key_management_t superse_key_management = {
|
||||
* .p_allocate = superse_allocate,
|
||||
* .p_validate_slot_number = NULL,
|
||||
* .p_import = NULL,
|
||||
* .p_generate = superse_generate_key,
|
||||
* .p_destroy = NULL,
|
||||
* .p_export = NULL,
|
||||
* .p_export_public = NULL
|
||||
* };
|
||||
*
|
||||
* psa_drv_se_t superse_methods = {
|
||||
* .hal_version = PSA_DRV_SE_HAL_VERSION,
|
||||
* .persistent_data_size = 0,
|
||||
* .p_init = NULL,
|
||||
* .key_management = &superse_key_management,
|
||||
* .mac = NULL,
|
||||
* .cipher = NULL,
|
||||
* .aead = NULL,
|
||||
* .asymmetric = NULL,
|
||||
* .derivation = NULL
|
||||
* };
|
||||
* @endcode
|
||||
*
|
||||
* You should do this for all available functions. The structures for the functions are
|
||||
* declared in `sys/psa_crypto/include/psa_crypto_se_driver.h`.
|
||||
*
|
||||
* #### Driver Registration
|
||||
* At start-up all secure element drivers need to be registered with the PSA SE management module.
|
||||
* This happens by calling `psa_register_secure_element()` during the automatic driver
|
||||
* initialization in RIOT.
|
||||
* When you added support for our device to RIOT, you should have implemented an
|
||||
* `auto_init_<device>` function, which initializes the connected devices.
|
||||
* In this function, after initializing a device, you should call `psa_register_secure_element()`
|
||||
* and pass the device's location value, and pointers to the `psa_drv_se_t` structure,
|
||||
* the persistent data and some device specific context.
|
||||
* An example implementation of this can be seen in `sys/auto_init/security/auto_init_atca.c`.
|
||||
*
|
||||
* #### Telling PSA Crypto about it
|
||||
* To be able to choose our `superSE` during configuration, we need to define the corresponding
|
||||
* modules in the Kconfig files and Makefiles.
|
||||
*
|
||||
* To `pkg/super_se_lib/Kconfig` we add something like
|
||||
* @code
|
||||
* config MODULE_PSA_SUPERSE_DRIVER
|
||||
* bool
|
||||
* depends on PACKAGE_SUPERSE_LIB
|
||||
* default y if MODULE_PSA_CRYPTO
|
||||
* select PSA_KEY_MANAGEMENT
|
||||
* @endcode
|
||||
* This tells the build system that whenever this driver and PSA Crypto are used at the same time,
|
||||
* the wrapper and the PSA key management module are needed, too.
|
||||
*
|
||||
* To `sys/psa_crypto/psa_se_mgmt/Kconfig` we add a menu for the SE like so:
|
||||
* @code
|
||||
* menuconfig MODULE_PSA_SECURE_ELEMENT_SUPERSE
|
||||
* bool "Our Vendor's SuperSE"
|
||||
* select PACKAGE_SUPERSE_LIB
|
||||
* depends on <whatever protocol is needed for communication, e.g. HAS_PERIPH_I2C>
|
||||
* help
|
||||
* <Some helpful information about this module>
|
||||
* @endcode
|
||||
* This makes our driver selectable whenever an application configuration selects the PSA secure
|
||||
* element module.
|
||||
*
|
||||
* As described in the [Configuration Section](#configuration-keys), references to keys on secure
|
||||
* elements are stored by PSA in a different type of key slot than other keys.
|
||||
* The slot for protected keys usually only contains a slot number or address and not the actual
|
||||
* key, which requires a lot less memory space.
|
||||
*
|
||||
* **BUT:** If your secure element supports asymmetric cryptography and exports a public key part
|
||||
* during key generation, that key part must be stored somewhere. This is why there needs to be
|
||||
* an option to tell PSA Crypto that an application is going to perform asymmetric operations.
|
||||
* Only if that option is selected, the protected key slots will have the space to store a public
|
||||
* key.
|
||||
*
|
||||
* For this we need to add the following to the `superSE` menu:
|
||||
* @code
|
||||
* config MODULE_PSA_SECURE_ELEMENT_SUPERSE_ECC_P256
|
||||
* bool "Our Vendor's Elliptic Curve P256"
|
||||
* select PSA_KEY_SIZE_256
|
||||
* select MODULE_PSA_SECURE_ELEMENT_ASYMMETRIC
|
||||
* depends on MODULE_PSA_SECURE_ELEMENT_SUPERSE
|
||||
* @endcode
|
||||
* This tells us, what size a key slot should have to store the public key. If your SE supports
|
||||
* other curves, you need to modify this accordingly or add more of them.
|
||||
*
|
||||
* Now we need to add the same to the Makefiles. In `Makefile.include` we add the source file path
|
||||
* and the PSA include folders and define the new available pseudomodules:
|
||||
* @code
|
||||
* ifneq (,$(filter psa_crypto,$(USEMODULE)))
|
||||
* DIRS += $(RIOTPKG)/superse_lib/psa_superse_driver
|
||||
* INCLUDES += -I$(RIOTBASE)/sys/psa_crypto/include
|
||||
* PSEUDOMODULES += psa_secure_element_superse
|
||||
* PSEUDOMODULES += psa_secure_element_superse_ecc_p256
|
||||
* endif
|
||||
* @endcode
|
||||
*
|
||||
* In `Makefile.dep` we automatically add required modules when PSA Crypto and the ECC curve
|
||||
* module are chosen:
|
||||
* @code
|
||||
* ifneq (,$(filter psa_crypto,$(USEMODULE)))
|
||||
* USEMODULE += psa_superse_driver
|
||||
* endif
|
||||
*
|
||||
* ifneq (,$(filter psa_secure_element_superse_ecc_p256, $(USEMODULE)))
|
||||
* USEMODULE += psa_secure_element_asymmetric
|
||||
* endif
|
||||
*
|
||||
* Now the secure element should be available for use with PSA Crypto.
|
||||
* @endcode
|
||||
*/
|
||||
136
sys/psa_crypto/include/psa_ciphers.h
Normal file
136
sys/psa_crypto/include/psa_ciphers.h
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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
|
||||
* @defgroup sys_psa_crypto_cipher PSA Wrapper Functions: Cipher
|
||||
* @{
|
||||
*
|
||||
* @file psa_ciphers.h
|
||||
* @brief Function declarations for low level wrapper functions for cipher operations.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_CIPHERS_H
|
||||
#define PSA_CIPHERS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_contexts.h"
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an AES 128 CBC encryption.
|
||||
* See @ref psa_cipher_encrypt()
|
||||
*
|
||||
* @param attributes
|
||||
* @param key_buffer
|
||||
* @param key_buffer_size
|
||||
* @param alg
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @param output
|
||||
* @param output_size
|
||||
* @param output_length
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an AES 128 CBC decryption.
|
||||
* See @ref psa_cipher_decrypt()
|
||||
*
|
||||
* @param attributes
|
||||
* @param key_buffer
|
||||
* @param key_buffer_size
|
||||
* @param alg
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @param output
|
||||
* @param output_size
|
||||
* @param output_length
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an AES 192 CBC encryption.
|
||||
* See @ref psa_cipher_encrypt()
|
||||
*
|
||||
* @param attributes
|
||||
* @param key_buffer
|
||||
* @param key_buffer_size
|
||||
* @param alg
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @param output
|
||||
* @param output_size
|
||||
* @param output_length
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t psa_cipher_cbc_aes_192_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);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an AES 256 CBC encryption.
|
||||
* See @ref psa_cipher_encrypt()
|
||||
*
|
||||
* @param attributes
|
||||
* @param key_buffer
|
||||
* @param key_buffer_size
|
||||
* @param alg
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @param output
|
||||
* @param output_size
|
||||
* @param output_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CIPHERS_H */
|
||||
/** @} */
|
||||
201
sys/psa_crypto/include/psa_crypto_algorithm_dispatch.h
Normal file
201
sys/psa_crypto/include/psa_crypto_algorithm_dispatch.h
Normal file
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* 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
|
||||
* @defgroup sys_psa_crypto_alg_disp PSA Crypto Algorithm Dispatcher
|
||||
* @{
|
||||
*
|
||||
* @file psa_crypto_algorithm_dispatch.h
|
||||
* @brief Function declarations for PSA Crypto algorithm dispatcher
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_ALGORITHM_DISPATCH_H
|
||||
#define PSA_CRYPTO_ALGORITHM_DISPATCH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "kernel_defines.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_slot_management.h"
|
||||
|
||||
/**
|
||||
* @brief Dispatch a hash setup function to a specific backend.
|
||||
* See @ref psa_hash_setup()
|
||||
*
|
||||
* @param operation
|
||||
* @param alg
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t psa_algorithm_dispatch_hash_setup(psa_hash_operation_t *operation,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
/**
|
||||
* @brief Dispatch a hash update function to a specific backend.
|
||||
* See @ref psa_hash_update()
|
||||
*
|
||||
* @param operation
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t psa_algorithm_dispatch_hash_update(psa_hash_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length);
|
||||
|
||||
/**
|
||||
* @brief Dispatch a hash finish function to a specific backend.
|
||||
* See @ref psa_hash_finish()
|
||||
*
|
||||
* @param operation
|
||||
* @param hash
|
||||
* @param hash_size
|
||||
* @param hash_length
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t psa_algorithm_dispatch_hash_finish(psa_hash_operation_t *operation,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length);
|
||||
|
||||
/**
|
||||
* @brief Dispatch a hash signature function to a specific backend.
|
||||
* See @ref psa_sign_hash()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param slot
|
||||
* @param hash
|
||||
* @param hash_length
|
||||
* @param signature
|
||||
* @param signature_size
|
||||
* @param signature_length
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t psa_algorithm_dispatch_sign_hash( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
uint8_t *signature,
|
||||
size_t signature_size,
|
||||
size_t *signature_length);
|
||||
|
||||
/**
|
||||
* @brief Dispatch a hash verification function to a specific backend.
|
||||
* See @ref psa_verify_hash()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param slot
|
||||
* @param hash
|
||||
* @param hash_length
|
||||
* @param signature
|
||||
* @param signature_length
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t psa_algorithm_dispatch_verify_hash( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length);
|
||||
|
||||
/**
|
||||
* @brief Dispatch the key generation function to a specific backend.
|
||||
* See @ref psa_generate_key()
|
||||
*
|
||||
* @param attributes
|
||||
* @param slot
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t psa_algorithm_dispatch_generate_key( const psa_key_attributes_t *attributes,
|
||||
psa_key_slot_t *slot);
|
||||
|
||||
/**
|
||||
* @brief Dispatch a cipher encrypt function to a specific backend.
|
||||
* See @ref psa_cipher_encrypt()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param slot
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @param output
|
||||
* @param output_size
|
||||
* @param output_length
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t psa_algorithm_dispatch_cipher_encrypt( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
/**
|
||||
* @brief Dispatch a cipher decrypt function to a specific backend.
|
||||
* See @ref psa_cipher_decrypt()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param slot
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @param output
|
||||
* @param output_size
|
||||
* @param output_length
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t psa_algorithm_dispatch_cipher_decrypt( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
/**
|
||||
* @brief Dispatch a mac computation function to a specific backend.
|
||||
* See @ref psa_mac_compute()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param slot
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @param mac
|
||||
* @param mac_size
|
||||
* @param mac_length
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t psa_algorithm_dispatch_mac_compute(const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_ALGORITHM_DISPATCH_H */
|
||||
/** @} */
|
||||
230
sys/psa_crypto/include/psa_crypto_location_dispatch.h
Normal file
230
sys/psa_crypto/include/psa_crypto_location_dispatch.h
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* 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
|
||||
* @defgroup sys_psa_crypto_loc_disp PSA Crypto Location Dispatcher
|
||||
* @{
|
||||
*
|
||||
* @file psa_crypto_location_dispatch.h
|
||||
* @brief Function declarations for the PSA Crypto location dispatcher.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_LOCATION_DISPATCH_H
|
||||
#define PSA_CRYPTO_LOCATION_DISPATCH_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "kernel_defines.h"
|
||||
#include "psa/crypto.h"
|
||||
|
||||
/**
|
||||
* @brief Dispatch call of a hash signature function to a location specific backend.
|
||||
* See psa_sign_hash()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param slot
|
||||
* @param hash
|
||||
* @param hash_length
|
||||
* @param signature
|
||||
* @param signature_size
|
||||
* @param signature_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_location_dispatch_sign_hash( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
uint8_t *signature,
|
||||
size_t signature_size,
|
||||
size_t *signature_length);
|
||||
|
||||
/**
|
||||
* @brief Dispatch call of a hash verification function to a location specific backend.
|
||||
* See psa_verify_hash()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param slot
|
||||
* @param hash
|
||||
* @param hash_length
|
||||
* @param signature
|
||||
* @param signature_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_location_dispatch_verify_hash( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length);
|
||||
|
||||
/**
|
||||
* @brief Dispatch call of a mac computation function to a location specific backend.
|
||||
* See psa_mac_compute()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param slot
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @param mac
|
||||
* @param mac_size
|
||||
* @param mac_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_location_dispatch_mac_compute(const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length);
|
||||
|
||||
/**
|
||||
* @brief Dispatch call of the key generation function to a location specific backend.
|
||||
* See psa_generate_key()
|
||||
*
|
||||
* @param attributes
|
||||
* @param slot
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_location_dispatch_generate_key(const psa_key_attributes_t *attributes,
|
||||
psa_key_slot_t *slot);
|
||||
|
||||
/**
|
||||
* @brief Dispatch call of the key import function to a location specific backend.
|
||||
* See psa_import_key()
|
||||
*
|
||||
* @param attributes
|
||||
* @param data
|
||||
* @param data_length
|
||||
* @param slot
|
||||
* @param bits
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_location_dispatch_import_key( const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data, size_t data_length,
|
||||
psa_key_slot_t *slot, size_t *bits);
|
||||
|
||||
/**
|
||||
* @brief Dispatch call of a cipher encrypt setup function to a location specific backend.
|
||||
* See psa_cipher_setup()
|
||||
*
|
||||
* @param operation
|
||||
* @param attributes
|
||||
* @param slot
|
||||
* @param alg
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_location_dispatch_cipher_encrypt_setup( psa_cipher_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const psa_key_slot_t *slot,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
/**
|
||||
* @brief Dispatch call of a cipher decrypt setup function to a location specific backend.
|
||||
* See psa_cipher_setup()
|
||||
*
|
||||
* @param operation
|
||||
* @param attributes
|
||||
* @param slot
|
||||
* @param alg
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_location_dispatch_cipher_decrypt_setup(psa_cipher_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const psa_key_slot_t *slot,
|
||||
psa_algorithm_t alg);
|
||||
|
||||
/**
|
||||
* @brief Dispatch call of a function to set a cipher IV to a location specific backend.
|
||||
* See psa_cipher_set_iv()
|
||||
*
|
||||
* @param operation
|
||||
* @param iv
|
||||
* @param iv_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_location_dispatch_cipher_set_iv( psa_cipher_operation_t *operation,
|
||||
const uint8_t *iv,
|
||||
size_t iv_length);
|
||||
|
||||
/**
|
||||
* @brief Dispatch call of a cipher encrypt function to a location specific backend.
|
||||
* See psa_cipher_encrypt()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param slot
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @param output
|
||||
* @param output_size
|
||||
* @param output_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_location_dispatch_cipher_encrypt( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
/**
|
||||
* @brief Dispatch call of a cipher decrypt function to a location specific backend.
|
||||
* See psa_cipher_decrypt()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param slot
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @param output
|
||||
* @param output_size
|
||||
* @param output_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_location_dispatch_cipher_decrypt( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length);
|
||||
|
||||
/**
|
||||
* @brief Dispatch call of a random number generator to a specific backend.
|
||||
* See psa_generate_random()
|
||||
*
|
||||
* @param output
|
||||
* @param output_size
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_location_dispatch_generate_random(uint8_t *output,
|
||||
size_t output_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_LOCATION_DISPATCH_H */
|
||||
/** @} */
|
||||
172
sys/psa_crypto/include/psa_crypto_operation_encoder.h
Normal file
172
sys/psa_crypto/include/psa_crypto_operation_encoder.h
Normal file
@ -0,0 +1,172 @@
|
||||
/*
|
||||
* 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 psa_crypto_operation_encoder.h
|
||||
* @brief Macros used to map PSA akgorithms, key types and key sizes to specific key types
|
||||
* and operations to call the corresponding driver functions.
|
||||
*
|
||||
* @note Currently this only supports a small number of operations. It should be expanded as
|
||||
* needed as this implementation increases support for more operations.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_OPERATION_ENCODER_H
|
||||
#define PSA_CRYPTO_OPERATION_ENCODER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_slot_management.h"
|
||||
|
||||
/**
|
||||
* @brief Unknown or invalid operation
|
||||
*/
|
||||
#define PSA_INVALID_OPERATION (0xFF)
|
||||
|
||||
/**
|
||||
* @brief Enum encoding available cipher operations.
|
||||
*
|
||||
* @details To be expanded with the development of this implementation.
|
||||
*/
|
||||
typedef enum {
|
||||
PSA_CBC_NO_PAD_AES_128,
|
||||
PSA_CBC_NO_PAD_AES_192,
|
||||
PSA_CBC_NO_PAD_AES_256,
|
||||
PSA_CBC_PKCS7_AES_256
|
||||
} psa_cipher_op_t;
|
||||
|
||||
/**
|
||||
* @brief Enum encoding available asymmetric key types and sizes.
|
||||
*
|
||||
* @details To be expanded with the development of this implementation.
|
||||
*/
|
||||
typedef enum {
|
||||
PSA_ECC_P160_K1,
|
||||
PSA_ECC_P160_R1,
|
||||
PSA_ECC_P160_R2,
|
||||
PSA_ECC_P192_K1,
|
||||
PSA_ECC_P192_R1,
|
||||
PSA_ECC_P224_K1,
|
||||
PSA_ECC_P224_R1,
|
||||
PSA_ECC_P256_K1,
|
||||
PSA_ECC_P256_R1,
|
||||
PSA_ECC_P384_R1,
|
||||
PSA_ECC_P521_R1,
|
||||
PSA_ECC_FRP,
|
||||
PSA_ECMONT_255,
|
||||
PSA_ECMONT_448
|
||||
} psa_asym_key_t;
|
||||
|
||||
/**
|
||||
* @brief Combine an ECC 192 key type with a given curve.
|
||||
*
|
||||
* @param curve Must be a curve of type @ref psa_ecc_family_t
|
||||
*
|
||||
* @return @ref psa_asym_key_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c curve is not compatible with key size
|
||||
*/
|
||||
#define GET_ECC_KEY_TYPE_192(curve) \
|
||||
((curve == PSA_ECC_FAMILY_SECP_R1) ? PSA_ECC_P192_R1 : \
|
||||
PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Combine an ECC 265 key type with a given curve.
|
||||
*
|
||||
* @param curve Must be a curve of type @ref psa_ecc_family_t
|
||||
*
|
||||
* @return @ref psa_asym_key_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c curve is not compatible with key size
|
||||
*/
|
||||
#define GET_ECC_KEY_TYPE_256(curve) \
|
||||
((curve == PSA_ECC_FAMILY_SECP_R1) ? PSA_ECC_P256_R1 : \
|
||||
PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Map an ECC 192 key to a given curve according to its type and size.
|
||||
*
|
||||
* @param bits Key size of type @ref psa_key_bits_t
|
||||
* @param curve Must be a curve of type @ref psa_ecc_family_t
|
||||
*
|
||||
* @return @ref psa_asym_key_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c curve and @c bits are incompatible
|
||||
*/
|
||||
#define PSA_ENCODE_ECC_KEY_TYPE(bits, curve) \
|
||||
((bits == 256) || (bits == 520) ? GET_ECC_KEY_TYPE_256(curve) : \
|
||||
(bits == 192) || (bits == 392) ? GET_ECC_KEY_TYPE_192(curve) : \
|
||||
PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Combine algorithm, and key type with a key size of 128 bits.
|
||||
*
|
||||
* @param alg Algorithm of type @ref psa_algorithm_t.
|
||||
* @param type Key type of type @ref psa_key_type_t
|
||||
*
|
||||
* @return @ref psa_cipher_op_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, and @c type are incompatible with the key size
|
||||
*/
|
||||
#define GET_CIPHER_OPERATION_128(alg, type) \
|
||||
(((alg == PSA_ALG_CBC_NO_PADDING) && (type == PSA_KEY_TYPE_AES)) ? PSA_CBC_NO_PAD_AES_128 : \
|
||||
PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Combine algorithm, and key type with a key size of 192 bits.
|
||||
*
|
||||
* @param alg Algorithm of type @ref psa_algorithm_t.
|
||||
* @param type Key type of type @ref psa_key_type_t
|
||||
*
|
||||
* @return @ref psa_cipher_op_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, and @c type are incompatible with the key size
|
||||
*/
|
||||
#define GET_CIPHER_OPERATION_192(alg, type) \
|
||||
(((alg == PSA_ALG_CBC_NO_PADDING) && (type == PSA_KEY_TYPE_AES)) ? PSA_CBC_NO_PAD_AES_192 : \
|
||||
PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Combine algorithm, and key type with a key size of 256 bits.
|
||||
*
|
||||
* @param alg Algorithm of type @ref psa_algorithm_t.
|
||||
* @param type Key type of type @ref psa_key_type_t
|
||||
*
|
||||
* @return @ref psa_cipher_op_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, and @c type are incompatible with the key size
|
||||
*/
|
||||
#define GET_CIPHER_OPERATION_256(alg, type) \
|
||||
(((alg == PSA_ALG_CBC_NO_PADDING) && (type == PSA_KEY_TYPE_AES)) ? PSA_CBC_NO_PAD_AES_256 : \
|
||||
((alg == PSA_ALG_CBC_PKCS7) && (type == PSA_KEY_TYPE_AES)) ? PSA_CBC_PKCS7_AES_256 : \
|
||||
PSA_INVALID_OPERATION)
|
||||
|
||||
/**
|
||||
* @brief Map algorithm, key size and type to a specific operation.
|
||||
*
|
||||
* @param alg Algorithm of type @ref psa_algorithm_t.
|
||||
* @param bits Size of the used key of type @ref psa_key_bits_t
|
||||
* @param type Key type of type @ref psa_key_type_t
|
||||
*
|
||||
* @return @ref psa_cipher_op_t
|
||||
* @return @ref PSA_INVALID_OPERATION @c alg, @c bits and @c type are not compatible
|
||||
*/
|
||||
#define PSA_ENCODE_CIPHER_OPERATION(alg, bits, type) \
|
||||
((bits == 128) ? GET_CIPHER_OPERATION_128(alg, type) : \
|
||||
(bits == 192) ? GET_CIPHER_OPERATION_192(alg, type) : \
|
||||
(bits == 256) ? GET_CIPHER_OPERATION_256(alg, type) : \
|
||||
PSA_INVALID_OPERATION)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_OPERATION_ENCODER_H */
|
||||
/** @} */
|
||||
1314
sys/psa_crypto/include/psa_crypto_se_driver.h
Normal file
1314
sys/psa_crypto/include/psa_crypto_se_driver.h
Normal file
File diff suppressed because it is too large
Load Diff
207
sys/psa_crypto/include/psa_crypto_se_management.h
Normal file
207
sys/psa_crypto/include/psa_crypto_se_management.h
Normal file
@ -0,0 +1,207 @@
|
||||
/*
|
||||
* 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
|
||||
* @defgroup psa_crypto_se_mgmt PSA Crypto SE Management
|
||||
* @{
|
||||
*
|
||||
* @file psa_crypto_se_management.h
|
||||
* @brief PSA Secure Element management function declarations
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_SE_MANAGEMENT_H
|
||||
#define PSA_CRYPTO_SE_MANAGEMENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_se_driver.h"
|
||||
|
||||
/**
|
||||
* @brief Maximum number of available secure elements.
|
||||
*/
|
||||
#ifndef CONFIG_PSA_MAX_SE_COUNT
|
||||
#define CONFIG_PSA_MAX_SE_COUNT (1)
|
||||
#endif /* CONFIG_PSA_MAX_SE_COUNT */
|
||||
|
||||
/**
|
||||
* @brief Maximum supported number of secure elements
|
||||
*/
|
||||
#define PSA_MAX_SE_COUNT (CONFIG_PSA_MAX_SE_COUNT)
|
||||
|
||||
/**
|
||||
* @brief Internal secure element driver context.
|
||||
*
|
||||
* @details This is the same structure as @ref psa_drv_se_context_t, with the difference that it is
|
||||
* also writeable for the implementation.
|
||||
*
|
||||
* This structure is not to be used by applications, only by the PSA Crypto implementation.
|
||||
*/
|
||||
typedef struct {
|
||||
void * persistent_data; /**< Driver specific persistent data */
|
||||
size_t persistent_data_size; /**< Size of persistent data in bytes */
|
||||
uintptr_t transient_data; /**< Driver specific transient data */
|
||||
} psa_drv_se_internal_context_t;
|
||||
|
||||
/**
|
||||
* @brief Structure containing secure element driver data and contexts.
|
||||
*/
|
||||
struct psa_se_drv_data_s {
|
||||
psa_key_location_t location; /**< Location value assigned to driver */
|
||||
const psa_drv_se_t *methods; /**< Methods implemented by driver */
|
||||
union {
|
||||
psa_drv_se_internal_context_t internal; /**< Internally writable SE driver context */
|
||||
psa_drv_se_context_t context; /**< SE driver context, read only */
|
||||
} ctx; /**< SE driver context */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Encodes the secure element driver data
|
||||
*/
|
||||
typedef struct psa_se_drv_data_s psa_se_drv_data_t;
|
||||
|
||||
/**
|
||||
* @brief Register a secure element driver with the SE management.
|
||||
*
|
||||
* @details This function is called by the @c auto_init module during boot.
|
||||
*
|
||||
* @param location Location the driver should be registered with,
|
||||
* of type @ref psa_key_location_t
|
||||
* @param methods Structure of available driver entry points of the driver
|
||||
* @param psa_se_configuration Pointer to a secure element configuration structure
|
||||
* @param drv_transient_data Transient driver data to be used by the driver
|
||||
*
|
||||
* @return @ref PSA_SUCCESS
|
||||
* @return @ref PSA_ERROR_INVALID_ARGUMENT The location value is invalid
|
||||
* @return @ref PSA_ERROR_NOT_SUPPORTED
|
||||
* @return @ref PSA_ERROR_INSUFFICIENT_MEMORY
|
||||
* @return @ref PSA_ERROR_ALREADY_EXISTS *
|
||||
*/
|
||||
psa_status_t psa_register_secure_element(psa_key_location_t location,
|
||||
const psa_drv_se_t *methods,
|
||||
void *psa_se_configuration,
|
||||
const void *drv_transient_data);
|
||||
|
||||
/**
|
||||
* @brief Get the driver data of a specified driver
|
||||
*
|
||||
* @param lifetime Lifetime value of type @ref psa_key_lifetime_t of the key to be used
|
||||
*
|
||||
* @return @ref psa_se_drv_data_t* Pointer to the driver data
|
||||
* @return @c NULL if no driver exists with this location
|
||||
*/
|
||||
psa_se_drv_data_t *psa_get_se_driver_data(psa_key_lifetime_t lifetime);
|
||||
|
||||
/**
|
||||
* @brief Get the driver entry points and context of a specified driver
|
||||
*
|
||||
* @param lifetime Lifetime value of type @ref psa_key_lifetime_t of the key to be used
|
||||
* @param p_methods Pointer that will reference the driver methods
|
||||
* @param p_drv_context Pointer that will reference the driver context
|
||||
*
|
||||
* @return 1 if a driver was found
|
||||
* @return 0 if no driver exists with this location
|
||||
*/
|
||||
int psa_get_se_driver( psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t **p_methods,
|
||||
psa_drv_se_context_t **p_drv_context);
|
||||
|
||||
/**
|
||||
* @brief Get the driver entry points of a specified driver
|
||||
*
|
||||
* @param driver Driver data of type @ref psa_se_drv_data_t containing the entry points
|
||||
*
|
||||
* @return const psa_drv_se_t*
|
||||
*/
|
||||
const psa_drv_se_t *psa_get_se_driver_methods(const psa_se_drv_data_t *driver);
|
||||
|
||||
/**
|
||||
* @brief Get the driver context of a specified driver
|
||||
*
|
||||
* @param driver Driver data of type @ref psa_se_drv_data_t containing the context
|
||||
*
|
||||
* @return @ref psa_drv_se_context_t*
|
||||
*/
|
||||
psa_drv_se_context_t *psa_get_se_drv_context(psa_se_drv_data_t *driver);
|
||||
|
||||
/**
|
||||
* @brief Find an empty key slot on a secure element appropriate to the key attributes
|
||||
*
|
||||
* @param attributes @ref psa_key_attributes_t containing the attributes of the key to be created
|
||||
* @param method The method used to create the key (see @ref psa_key_creation_method_t)
|
||||
* @param driver Pointer to the driver for the SE the key should be created on
|
||||
* @param slot_number Pointer that will contain the slot number of the free SE slot
|
||||
*
|
||||
* @return @ref PSA_SUCCESS
|
||||
* @return @ref PSA_ERROR_CORRUPTION_DETECTED
|
||||
* @return @ref PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
psa_status_t psa_find_free_se_slot( const psa_key_attributes_t *attributes,
|
||||
psa_key_creation_method_t method,
|
||||
psa_se_drv_data_t *driver,
|
||||
psa_key_slot_number_t *slot_number);
|
||||
|
||||
/**
|
||||
* @brief Destroy the key on a secure element
|
||||
*
|
||||
* @note Some secure elements may not support this operation.
|
||||
*
|
||||
* @param driver Driver of the SE containing the key to be destroyed
|
||||
* @param slot_number Slot number of the key that is to be destroyed
|
||||
*
|
||||
* @return @ref PSA_SUCCESS
|
||||
* @return @ref PSA_ERROR_NOT_PERMITTED
|
||||
*/
|
||||
psa_status_t psa_destroy_se_key(psa_se_drv_data_t *driver,
|
||||
psa_key_slot_number_t slot_number);
|
||||
|
||||
/**
|
||||
* @brief Load SE data from persistent memory
|
||||
*
|
||||
* @note This operation is not yet supported by this implementation
|
||||
*
|
||||
* @param driver Pointer to the driver data the loaded data should be stored in
|
||||
*
|
||||
* @return @ref PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
psa_status_t psa_load_se_persistent_data(const psa_se_drv_data_t *driver);
|
||||
|
||||
/**
|
||||
* @brief Save SE data to persistent memory
|
||||
*
|
||||
* @note This operation is not yet supported by this implementation
|
||||
*
|
||||
* @param driver Pointer to the driver data containing the data to be saved
|
||||
*
|
||||
* @return @ref PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
psa_status_t psa_save_se_persistent_data(const psa_se_drv_data_t *driver);
|
||||
|
||||
/**
|
||||
* @brief Destroy SE data in persistent memory
|
||||
*
|
||||
* @note This operation is not yet supported by this implementation
|
||||
*
|
||||
* @param location Location of the data that should be destroyed
|
||||
*
|
||||
* @return @ref PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
psa_status_t psa_destroy_se_persistent_data(psa_key_location_t location);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_SE_MANAGEMENT_H */
|
||||
/**@}*/
|
||||
262
sys/psa_crypto/include/psa_crypto_slot_management.h
Normal file
262
sys/psa_crypto/include/psa_crypto_slot_management.h
Normal file
@ -0,0 +1,262 @@
|
||||
/*
|
||||
* 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
|
||||
* @defgroup sys_psa_crypto_slot_mgmt PSA Crypto Key Slot Management
|
||||
* @{
|
||||
*
|
||||
* @file psa_crypto_slot_management.h
|
||||
* @brief PSA key slot management function declarations
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_CRYPTO_SLOT_MANAGEMENT_H
|
||||
#define PSA_CRYPTO_SLOT_MANAGEMENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "clist.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_se_management.h"
|
||||
|
||||
/**
|
||||
* @brief Number of allocated slots for keys in protected memory or secure elements.
|
||||
*/
|
||||
#define PSA_PROTECTED_KEY_COUNT (CONFIG_PSA_PROTECTED_KEY_COUNT)
|
||||
|
||||
/**
|
||||
* @brief Number of allocated slots for asymmetric key pairs.
|
||||
*/
|
||||
#define PSA_ASYMMETRIC_KEYPAIR_COUNT (CONFIG_PSA_ASYMMETRIC_KEYPAIR_COUNT)
|
||||
|
||||
/**
|
||||
* @brief Number of allocated slots for single keys in local memory.
|
||||
*/
|
||||
#define PSA_SINGLE_KEY_COUNT (CONFIG_PSA_SINGLE_KEY_COUNT)
|
||||
|
||||
/**
|
||||
* @brief Complete number of available key slots
|
||||
*/
|
||||
#define PSA_KEY_SLOT_COUNT (PSA_PROTECTED_KEY_COUNT + \
|
||||
PSA_ASYMMETRIC_KEYPAIR_COUNT + \
|
||||
PSA_SINGLE_KEY_COUNT)
|
||||
|
||||
/**
|
||||
* @brief Minimum key id for volatile keys.
|
||||
*
|
||||
* @details This is used to assign volatile identifiers to created keys.
|
||||
*/
|
||||
#define PSA_KEY_ID_VOLATILE_MIN (PSA_KEY_ID_VENDOR_MIN)
|
||||
|
||||
/**
|
||||
* @brief Maximum key id for volatile keys.
|
||||
*
|
||||
* @details This is the maximum volatile identifiers that can be assigned to created keys.
|
||||
*/
|
||||
#define PSA_KEY_ID_VOLATILE_MAX (PSA_KEY_ID_VENDOR_MAX)
|
||||
|
||||
/**
|
||||
* @brief Structure of a virtual key slot in local memory.
|
||||
*
|
||||
* @details A slot contains key attributes, a lock count and the @c key_data structure.
|
||||
* @c key_data consists of the size of the stored key in bytes and a @c uint8_t data array
|
||||
* large enough to store the largest key used in the current build. This type of key slot
|
||||
* contains symmetric keys, asymmetric public keys or unstructured data.
|
||||
*/
|
||||
typedef struct {
|
||||
clist_node_t node; /**< List node to link slot in global list */
|
||||
size_t lock_count; /**< Number of entities accessing the slot */
|
||||
psa_key_attributes_t attr; /**< Attributes associated with the stored key */
|
||||
/** Structure containing key data */
|
||||
struct key_data {
|
||||
uint8_t data[PSA_MAX_KEY_DATA_SIZE]; /**< Key data buffer */
|
||||
size_t data_len; /**< Size of actual key data in bytes */
|
||||
} key; /**< Key data structure */
|
||||
} psa_key_slot_t;
|
||||
|
||||
/**
|
||||
* @brief Initializes the allocated key slots and prepares the internal key slot lists.
|
||||
*/
|
||||
void psa_init_key_slots(void);
|
||||
|
||||
/**
|
||||
* @brief Check whether a key identifier is a volatile key identifier.
|
||||
*
|
||||
* @param key_id Key identifier to test.
|
||||
*
|
||||
* @return 1 The key identifier is a volatile key identifier.
|
||||
* @return 0 The key identifier is not a volatile key identifier.
|
||||
*/
|
||||
static inline int psa_key_id_is_volatile(psa_key_id_t key_id)
|
||||
{
|
||||
return ((key_id >= PSA_KEY_ID_VOLATILE_MIN) &&
|
||||
(key_id <= PSA_KEY_ID_VOLATILE_MAX));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether a key slot is locked
|
||||
*
|
||||
* @param slot Pointer to the slot to be checked
|
||||
*
|
||||
* @return 1 if slot is locked, otherwise 0
|
||||
*/
|
||||
static inline int psa_is_key_slot_locked(psa_key_slot_t *slot)
|
||||
{
|
||||
return (slot->lock_count > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get slot number in protected memory
|
||||
*
|
||||
* @param slot Pointer to the slot containing the protected slot number
|
||||
* @return @ref psa_key_slot_number_t Key slot number stored in the input slot
|
||||
*/
|
||||
psa_key_slot_number_t * psa_key_slot_get_slot_number(const psa_key_slot_t *slot);
|
||||
|
||||
/**
|
||||
* @brief Check whether a key is stored on an external device
|
||||
*
|
||||
* @param lifetime Lifetime value of the key that's supposed to be checked
|
||||
*
|
||||
* @return int
|
||||
* @return 1 if key is stored on external device, otherwise 0
|
||||
*/
|
||||
static inline int psa_key_lifetime_is_external(psa_key_lifetime_t lifetime)
|
||||
{
|
||||
return (PSA_KEY_LIFETIME_GET_LOCATION(lifetime) != PSA_KEY_LOCATION_LOCAL_STORAGE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wipe volatile key slot and its contents. Wiped key slots can be reused.
|
||||
*
|
||||
* @param slot Pointer to the key slot to be wiped
|
||||
*
|
||||
* @return @ref PSA_SUCCESS
|
||||
* @return @ref PSA_ERROR_DOES_NOT_EXIST
|
||||
*/
|
||||
psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot);
|
||||
|
||||
/**
|
||||
* @brief Wipe all existing volatile key slots.
|
||||
*/
|
||||
void psa_wipe_all_key_slots(void);
|
||||
|
||||
/**
|
||||
* @brief Find a key slot in local memory and lock it.
|
||||
*
|
||||
* @param id ID of the key to be used
|
||||
* @param slot Pointer to the slot the key is stored in
|
||||
*
|
||||
* @return @ref PSA_SUCCESS
|
||||
* @return @ref PSA_ERROR_DOES_NOT_EXIST
|
||||
* @return @ref PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
psa_status_t psa_get_and_lock_key_slot(psa_key_id_t id, psa_key_slot_t **slot);
|
||||
|
||||
/**
|
||||
* @brief Find a currently empty key slot that is appropriate for the key.
|
||||
*
|
||||
* @param id Key ID of the newly generated or imported key
|
||||
* @param attr Attributes of the key that is supposed to be stored in the slot
|
||||
* @param p_slot Pointer to the empty slot in memory
|
||||
*
|
||||
* @return @ref PSA_SUCCESS
|
||||
* @return @ref PSA_ERROR_INSUFFICIENT_STORAGE
|
||||
*/
|
||||
psa_status_t psa_allocate_empty_key_slot( psa_key_id_t *id,
|
||||
const psa_key_attributes_t *attr,
|
||||
psa_key_slot_t **p_slot);
|
||||
|
||||
/**
|
||||
* @brief Increase lock count
|
||||
*
|
||||
* @param slot Slot to be locked
|
||||
*
|
||||
* @return @ref PSA_SUCCESS
|
||||
* @return @ref PSA_ERROR_CORRUPTION_DETECTED
|
||||
*/
|
||||
psa_status_t psa_lock_key_slot(psa_key_slot_t *slot);
|
||||
|
||||
/**
|
||||
* @brief Decrease lock count
|
||||
*
|
||||
* @param slot Slot to be unlocked
|
||||
*
|
||||
* @return @ref PSA_SUCCESS
|
||||
* @return @ref PSA_ERROR_CORRUPTION_DETECTED
|
||||
*/
|
||||
psa_status_t psa_unlock_key_slot(psa_key_slot_t *slot);
|
||||
|
||||
/**
|
||||
* @brief Check if key location exists
|
||||
*
|
||||
* @param lifetime Lifetime value of the key to be validated
|
||||
* @param driver Pointer to driver assigned to the existing key location, if it exists
|
||||
*
|
||||
* @return @ref PSA_SUCCESS
|
||||
* @return @ref PSA_ERROR_INVALID_ARGUMENT
|
||||
*/
|
||||
psa_status_t psa_validate_key_location( psa_key_lifetime_t lifetime,
|
||||
psa_se_drv_data_t **driver);
|
||||
|
||||
/**
|
||||
* @brief Validate key persistence. Currently only volatile keys are supported.
|
||||
*
|
||||
* @param lifetime Lifetime of key to be validated
|
||||
*
|
||||
* @return @ref PSA_SUCCESS
|
||||
* @return @ref PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
psa_status_t psa_validate_key_persistence(psa_key_lifetime_t lifetime);
|
||||
|
||||
/**
|
||||
* @brief Check if provided key ID is either a valid user ID or vendor ID
|
||||
*
|
||||
* @param id ID of key to be validated
|
||||
* @param vendor If ID is supposed to be user or vendor ID
|
||||
*
|
||||
* @return 1 if valid
|
||||
* @return 0 if invalid
|
||||
*/
|
||||
int psa_is_valid_key_id(psa_key_id_t id, int vendor);
|
||||
|
||||
/**
|
||||
* @brief Get key data and key size from key slot
|
||||
*
|
||||
* @param slot Slot the desired key is stored in
|
||||
* @param key_data Pointer to key data
|
||||
* @param key_bytes Pointer to key data size in bytes
|
||||
*
|
||||
* @return Size of @p key_data in bytes.
|
||||
*/
|
||||
size_t psa_get_key_data_from_key_slot(const psa_key_slot_t *slot,
|
||||
uint8_t **key_data,
|
||||
size_t **key_bytes);
|
||||
|
||||
/**
|
||||
* @brief Get public key data and size from key slot
|
||||
*
|
||||
* @param slot Slot the desired key is stored in
|
||||
* @param pubkey_data Pointer to key data
|
||||
* @param pubkey_data_len Pointer to key data size in bytes
|
||||
*/
|
||||
void psa_get_public_key_data_from_key_slot( const psa_key_slot_t *slot,
|
||||
uint8_t **pubkey_data,
|
||||
size_t **pubkey_data_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_CRYPTO_SLOT_MANAGEMENT_H */
|
||||
/**@}*/
|
||||
198
sys/psa_crypto/include/psa_ecc.h
Normal file
198
sys/psa_crypto/include/psa_ecc.h
Normal file
@ -0,0 +1,198 @@
|
||||
/*
|
||||
* 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
|
||||
* @defgroup sys_psa_crypto_ecc PSA Wrapper Functions: ECC
|
||||
* @{
|
||||
*
|
||||
* @file psa_ecc.h
|
||||
* @brief Function declarations for low level wrapper functions for ECC operations.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_ECC_H
|
||||
#define PSA_ECC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "psa/crypto.h"
|
||||
#include "kernel_defines.h"
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an ECC key generation
|
||||
* with a SECP 192 R1 key.
|
||||
* See @ref psa_generate_key()
|
||||
*
|
||||
* @param attributes
|
||||
* @param priv_key_buffer
|
||||
* @param pub_key_buffer
|
||||
* @param priv_key_buffer_length
|
||||
* @param pub_key_buffer_length
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an ECC public key export
|
||||
* of a SECP 192 R1 key.
|
||||
* See @ref psa_export_public_key()
|
||||
*
|
||||
* @param attributes
|
||||
* @param key_buffer
|
||||
* @param key_buffer_size
|
||||
* @param data
|
||||
* @param data_size
|
||||
* @param data_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_ecc_p192r1_export_public_key( const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an ECC hash signature
|
||||
* with a SECP 192 R1 key.
|
||||
* See @ref psa_sign_hash()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param key_buffer
|
||||
* @param key_buffer_size
|
||||
* @param hash
|
||||
* @param hash_length
|
||||
* @param signature
|
||||
* @param signature_size
|
||||
* @param signature_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an ECC hash verification
|
||||
* with a SECP 192 R1 key.
|
||||
* See @ref psa_verify_hash()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param key_buffer
|
||||
* @param key_buffer_size
|
||||
* @param hash
|
||||
* @param hash_length
|
||||
* @param signature
|
||||
* @param signature_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an ECC key generation
|
||||
* with a SECP 192 R1 key.
|
||||
* See @ref psa_generate_key()
|
||||
*
|
||||
* @param attributes
|
||||
* @param priv_key_buffer
|
||||
* @param pub_key_buffer
|
||||
* @param priv_key_buffer_length
|
||||
* @param pub_key_buffer_length
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an ECC public key export
|
||||
* of a SECP 256 R1 key.
|
||||
* See @ref psa_export_public_key()
|
||||
*
|
||||
* @param attributes
|
||||
* @param key_buffer
|
||||
* @param key_buffer_size
|
||||
* @param data
|
||||
* @param data_size
|
||||
* @param data_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_ecc_p256r1_export_public_key( const psa_key_attributes_t *attributes,
|
||||
uint8_t *key_buffer,
|
||||
size_t key_buffer_size,
|
||||
uint8_t *data,
|
||||
size_t data_size,
|
||||
size_t *data_length);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an ECC hash signature
|
||||
* with a SECP 256 R1 key.
|
||||
* See @ref psa_sign_hash()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param key_buffer
|
||||
* @param key_buffer_size
|
||||
* @param hash
|
||||
* @param hash_length
|
||||
* @param signature
|
||||
* @param signature_size
|
||||
* @param signature_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an ECC hash verification
|
||||
* with a SECP 256 R1 key.
|
||||
* See @ref psa_verify_hash()
|
||||
*
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param key_buffer
|
||||
* @param key_buffer_size
|
||||
* @param hash
|
||||
* @param hash_length
|
||||
* @param signature
|
||||
* @param signature_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_ECC_H */
|
||||
/**@}*/
|
||||
232
sys/psa_crypto/include/psa_hashes.h
Normal file
232
sys/psa_crypto/include/psa_hashes.h
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* 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
|
||||
* @defgroup sys_psa_crypto_hashes PSA Wrapper Functions: Hashes
|
||||
* @{
|
||||
*
|
||||
* @file psa_hashes.h
|
||||
* @brief Function declarations for low level wrapper functions for hash operations.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_HASHES_H
|
||||
#define PSA_HASHES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "kernel_defines.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_contexts.h"
|
||||
|
||||
#if IS_USED(MODULE_PSA_HASH_MD5) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an MD5 hash setup
|
||||
* See @ref psa_hash_setup()
|
||||
*
|
||||
* @param ctx
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_md5_setup(psa_hashes_md5_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an MD5 hash update
|
||||
* See @ref psa_hash_update()
|
||||
*
|
||||
* @param ctx
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_md5_update(psa_hashes_md5_ctx_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an MD5 hash finish
|
||||
* See @ref psa_hash_finish()
|
||||
*
|
||||
* @param ctx
|
||||
* @param hash
|
||||
* @param hash_size
|
||||
* @param hash_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_md5_finish(psa_hashes_md5_ctx_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length);
|
||||
#endif /* CONFIG_HASHES_MD5 */
|
||||
|
||||
#if IS_USED(MODULE_PSA_HASH_SHA_1) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an SHA1 hash setup
|
||||
* See @ref psa_hash_setup()
|
||||
*
|
||||
* @param ctx
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_sha1_setup(psa_hashes_sha1_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an SHA1 hash update
|
||||
* See @ref psa_hash_update()
|
||||
*
|
||||
* @param ctx
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_sha1_update(psa_hashes_sha1_ctx_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an SHA1 hash finish
|
||||
* See @ref psa_hash_finish()
|
||||
*
|
||||
* @param ctx
|
||||
* @param hash
|
||||
* @param hash_size
|
||||
* @param hash_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_sha1_finish(psa_hashes_sha1_ctx_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length);
|
||||
#endif /* CONFIG_HASHES_SHA1 */
|
||||
|
||||
#if IS_USED(MODULE_PSA_HASH_SHA_224) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an SHA224 hash setup
|
||||
* See @ref psa_hash_setup()
|
||||
*
|
||||
* @param ctx
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_sha224_setup(psa_hashes_sha224_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an SHA224 hash update
|
||||
* See @ref psa_hash_update()
|
||||
*
|
||||
* @param ctx
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_sha224_update(psa_hashes_sha224_ctx_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an SHA224 hash finish
|
||||
* See @ref psa_hash_finish()
|
||||
*
|
||||
* @param ctx
|
||||
* @param hash
|
||||
* @param hash_size
|
||||
* @param hash_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_sha224_finish(psa_hashes_sha224_ctx_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length);
|
||||
#endif /* CONFIG_HASHES_SHA224 */
|
||||
|
||||
#if IS_USED(MODULE_PSA_HASH_SHA_256) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an SHA256 hash setup
|
||||
* See @ref psa_hash_setup()
|
||||
*
|
||||
* @param ctx
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_sha256_setup(psa_hashes_sha256_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an SHA256 hash update
|
||||
* See @ref psa_hash_update()
|
||||
*
|
||||
* @param ctx
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_sha256_update(psa_hashes_sha256_ctx_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an SHA256 hash finish
|
||||
* See @ref psa_hash_finish()
|
||||
*
|
||||
* @param ctx
|
||||
* @param hash
|
||||
* @param hash_size
|
||||
* @param hash_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_sha256_finish(psa_hashes_sha256_ctx_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length);
|
||||
#endif /* CONFIG_HASHES_SHA256 */
|
||||
|
||||
#if IS_USED(MODULE_PSA_HASH_SHA_512) || defined(DOXYGEN)
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an SHA512 hash setup
|
||||
* See @ref psa_hash_setup()
|
||||
*
|
||||
* @param ctx
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_sha512_setup(psa_hashes_sha512_ctx_t *ctx);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an SHA512 hash update
|
||||
* See @ref psa_hash_update()
|
||||
*
|
||||
* @param ctx
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_sha512_update(psa_hashes_sha512_ctx_t *ctx,
|
||||
const uint8_t *input,
|
||||
size_t input_length);
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for an SHA512 hash finish
|
||||
* See @ref psa_hash_finish()
|
||||
*
|
||||
* @param ctx
|
||||
* @param hash
|
||||
* @param hash_size
|
||||
* @param hash_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
psa_status_t psa_hashes_sha512_finish(psa_hashes_sha512_ctx_t *ctx,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length);
|
||||
#endif /* CONFIG_HASHES_SHA512 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_HASHES_H */
|
||||
/**@}*/
|
||||
60
sys/psa_crypto/include/psa_mac.h
Normal file
60
sys/psa_crypto/include/psa_mac.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 sys_psa_crypto
|
||||
* @defgroup sys_psa_crypto_mac PSA Wrapper Functions: MAC
|
||||
* @{
|
||||
*
|
||||
* @file psa_mac.h
|
||||
* @brief Function declarations for low level wrapper functions for MAC operations.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PSA_MAC_H
|
||||
#define PSA_MAC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "kernel_defines.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "psa/crypto_contexts.h"
|
||||
|
||||
/**
|
||||
* @brief Low level wrapper function to call a driver for a HMAC SHA256 computation
|
||||
* See psa_mac_compute()
|
||||
*
|
||||
* @param attributes
|
||||
* @param key_buffer
|
||||
* @param key_buffer_size
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @param mac
|
||||
* @param mac_size
|
||||
* @param mac_length
|
||||
* @return psa_status_t
|
||||
*/
|
||||
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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* PSA_MAC_H */
|
||||
/**@}*/
|
||||
1931
sys/psa_crypto/psa_crypto.c
Normal file
1931
sys/psa_crypto/psa_crypto.c
Normal file
File diff suppressed because it is too large
Load Diff
425
sys/psa_crypto/psa_crypto_algorithm_dispatch.c
Normal file
425
sys/psa_crypto/psa_crypto_algorithm_dispatch.c
Normal file
@ -0,0 +1,425 @@
|
||||
/*
|
||||
* 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 sys_psa_crypto_alg_disp
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Dispatch calls from the PSA Crypto API to an available backend.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "kernel_defines.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_mac.h"
|
||||
#include "psa_hashes.h"
|
||||
#include "psa_ecc.h"
|
||||
#include "psa_ciphers.h"
|
||||
#include "psa_crypto_operation_encoder.h"
|
||||
|
||||
psa_status_t psa_algorithm_dispatch_hash_setup(psa_hash_operation_t *operation,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
|
||||
|
||||
switch (alg) {
|
||||
#if (IS_USED(MODULE_PSA_HASH_MD5))
|
||||
case PSA_ALG_MD5:
|
||||
status = psa_hashes_md5_setup(&operation->ctx.md5);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if (IS_USED(MODULE_PSA_HASH_SHA_1))
|
||||
case PSA_ALG_SHA_1:
|
||||
status = psa_hashes_sha1_setup(&operation->ctx.sha1);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if (IS_USED(MODULE_PSA_HASH_SHA_224))
|
||||
case PSA_ALG_SHA_224:
|
||||
status = psa_hashes_sha224_setup(&operation->ctx.sha224);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if (IS_USED(MODULE_PSA_HASH_SHA_256))
|
||||
case PSA_ALG_SHA_256:
|
||||
status = psa_hashes_sha256_setup(&operation->ctx.sha256);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if (IS_USED(MODULE_PSA_HASH_SHA_512))
|
||||
case PSA_ALG_SHA_512:
|
||||
status = psa_hashes_sha512_setup(&operation->ctx.sha512);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void)status;
|
||||
(void)operation;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
operation->alg = alg;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_algorithm_dispatch_hash_update(psa_hash_operation_t *operation,
|
||||
const uint8_t *input,
|
||||
size_t input_length)
|
||||
{
|
||||
switch (operation->alg) {
|
||||
#if (IS_USED(MODULE_PSA_HASH_MD5))
|
||||
case PSA_ALG_MD5:
|
||||
return psa_hashes_md5_update(&operation->ctx.md5, input, input_length);
|
||||
#endif
|
||||
#if (IS_USED(MODULE_PSA_HASH_SHA_1))
|
||||
case PSA_ALG_SHA_1:
|
||||
return psa_hashes_sha1_update(&operation->ctx.sha1, input, input_length);
|
||||
#endif
|
||||
#if (IS_USED(MODULE_PSA_HASH_SHA_224))
|
||||
case PSA_ALG_SHA_224:
|
||||
return psa_hashes_sha224_update(&operation->ctx.sha224, input, input_length);
|
||||
#endif
|
||||
#if (IS_USED(MODULE_PSA_HASH_SHA_256))
|
||||
case PSA_ALG_SHA_256:
|
||||
return psa_hashes_sha256_update(&operation->ctx.sha256, input, input_length);
|
||||
#endif
|
||||
#if (IS_USED(MODULE_PSA_HASH_SHA_512))
|
||||
case PSA_ALG_SHA_512:
|
||||
return psa_hashes_sha512_update(&operation->ctx.sha512, input, input_length);
|
||||
#endif
|
||||
default:
|
||||
(void)operation;
|
||||
(void)input;
|
||||
(void)input_length;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t psa_algorithm_dispatch_hash_finish(psa_hash_operation_t *operation,
|
||||
uint8_t *hash,
|
||||
size_t hash_size,
|
||||
size_t *hash_length)
|
||||
{
|
||||
switch (operation->alg) {
|
||||
#if (IS_USED(MODULE_PSA_HASH_MD5))
|
||||
case PSA_ALG_MD5:
|
||||
return psa_hashes_md5_finish(&operation->ctx.md5, hash, hash_size, hash_length);
|
||||
#endif
|
||||
#if (IS_USED(MODULE_PSA_HASH_SHA_1))
|
||||
case PSA_ALG_SHA_1:
|
||||
return psa_hashes_sha1_finish(&operation->ctx.sha1, hash, hash_size, hash_length);
|
||||
#endif
|
||||
#if (IS_USED(MODULE_PSA_HASH_SHA_224))
|
||||
case PSA_ALG_SHA_224:
|
||||
return psa_hashes_sha224_finish(&operation->ctx.sha224, hash, hash_size, hash_length);
|
||||
#endif
|
||||
#if (IS_USED(MODULE_PSA_HASH_SHA_256))
|
||||
case PSA_ALG_SHA_256:
|
||||
return psa_hashes_sha256_finish(&operation->ctx.sha256, hash, hash_size, hash_length);
|
||||
#endif
|
||||
#if (IS_USED(MODULE_PSA_HASH_SHA_512))
|
||||
case PSA_ALG_SHA_512:
|
||||
return psa_hashes_sha512_finish(&operation->ctx.sha512, hash, hash_size, hash_length);
|
||||
#endif
|
||||
default:
|
||||
(void)operation;
|
||||
(void)hash;
|
||||
(void)hash_size;
|
||||
(void)hash_length;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t psa_algorithm_dispatch_sign_hash( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
uint8_t *signature,
|
||||
size_t signature_size,
|
||||
size_t *signature_length)
|
||||
{
|
||||
psa_asym_key_t asym_key = PSA_INVALID_OPERATION;
|
||||
uint8_t *key_data = NULL;
|
||||
size_t *key_bytes = NULL;
|
||||
|
||||
if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type)) {
|
||||
asym_key =
|
||||
PSA_ENCODE_ECC_KEY_TYPE(attributes->bits, PSA_KEY_TYPE_ECC_GET_CURVE(attributes->type));
|
||||
|
||||
if (asym_key == PSA_INVALID_OPERATION) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
psa_get_key_data_from_key_slot(slot, &key_data, &key_bytes);
|
||||
|
||||
switch (asym_key) {
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1)
|
||||
case PSA_ECC_P192_R1:
|
||||
return psa_ecc_p192r1_sign_hash(attributes, alg, key_data, *key_bytes, hash, hash_length,
|
||||
signature, signature_size, signature_length);
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1)
|
||||
case PSA_ECC_P256_R1:
|
||||
return psa_ecc_p256r1_sign_hash(attributes, alg, key_data, *key_bytes, hash, hash_length,
|
||||
signature, signature_size, signature_length);
|
||||
#endif
|
||||
default:
|
||||
(void)alg;
|
||||
(void)slot;
|
||||
(void)hash;
|
||||
(void)hash_length;
|
||||
(void)signature;
|
||||
(void)signature_size;
|
||||
(void)signature_length;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t psa_algorithm_dispatch_verify_hash( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length)
|
||||
{
|
||||
psa_asym_key_t asym_key = PSA_INVALID_OPERATION;
|
||||
uint8_t *pubkey_data = NULL;
|
||||
size_t *pubkey_data_len = NULL;
|
||||
|
||||
if (PSA_KEY_TYPE_IS_ECC(attributes->type)) {
|
||||
asym_key =
|
||||
PSA_ENCODE_ECC_KEY_TYPE(attributes->bits, PSA_KEY_TYPE_ECC_GET_CURVE(attributes->type));
|
||||
|
||||
if (asym_key == PSA_INVALID_OPERATION) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
psa_get_public_key_data_from_key_slot(slot, &pubkey_data, &pubkey_data_len);
|
||||
|
||||
switch (asym_key) {
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1)
|
||||
case PSA_ECC_P192_R1:
|
||||
return psa_ecc_p192r1_verify_hash(attributes, alg, pubkey_data, *pubkey_data_len, hash,
|
||||
hash_length, signature, signature_length);
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1)
|
||||
case PSA_ECC_P256_R1:
|
||||
return psa_ecc_p256r1_verify_hash(attributes, alg, pubkey_data, *pubkey_data_len, hash,
|
||||
hash_length, signature, signature_length);
|
||||
#endif
|
||||
default:
|
||||
(void)alg;
|
||||
(void)slot;
|
||||
(void)hash;
|
||||
(void)hash_length;
|
||||
(void)signature;
|
||||
(void)signature_length;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t psa_algorithm_dispatch_generate_key( const psa_key_attributes_t *attributes,
|
||||
psa_key_slot_t *slot)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
uint8_t *key_data = NULL;
|
||||
size_t *key_bytes = NULL;
|
||||
|
||||
psa_get_key_data_from_key_slot(slot, &key_data, &key_bytes);
|
||||
|
||||
/**
|
||||
* Only asymmetric key generation needs special key generation algorithms. Symmetric keys can
|
||||
* be created by generating random bytes.
|
||||
*/
|
||||
if (PSA_KEY_TYPE_IS_ASYMMETRIC(attributes->type)) {
|
||||
psa_asym_key_t asym_key = PSA_INVALID_OPERATION;
|
||||
uint8_t *pubkey_data = NULL;
|
||||
size_t *pubkey_data_len = NULL;
|
||||
psa_get_public_key_data_from_key_slot(slot, &pubkey_data, &pubkey_data_len);
|
||||
|
||||
if (PSA_KEY_TYPE_IS_ECC_KEY_PAIR(attributes->type)) {
|
||||
asym_key =
|
||||
PSA_ENCODE_ECC_KEY_TYPE(attributes->bits,
|
||||
PSA_KEY_TYPE_ECC_GET_CURVE(attributes->type));
|
||||
|
||||
if (asym_key == PSA_INVALID_OPERATION) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
switch (asym_key) {
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P192R1)
|
||||
case PSA_ECC_P192_R1:
|
||||
return psa_generate_ecc_p192r1_key_pair(attributes, key_data, pubkey_data, key_bytes,
|
||||
pubkey_data_len);
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC_ECC_P256R1)
|
||||
case PSA_ECC_P256_R1:
|
||||
return psa_generate_ecc_p256r1_key_pair(attributes, key_data, pubkey_data, key_bytes,
|
||||
pubkey_data_len);
|
||||
#endif
|
||||
default:
|
||||
(void)status;
|
||||
(void)slot;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
return psa_builtin_generate_key(attributes, key_data, *key_bytes, key_bytes);
|
||||
}
|
||||
|
||||
psa_status_t psa_algorithm_dispatch_cipher_encrypt( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_cipher_op_t op = PSA_ENCODE_CIPHER_OPERATION(alg, attributes->bits, attributes->type);
|
||||
uint8_t *key_data = NULL;
|
||||
size_t *key_bytes = NULL;
|
||||
|
||||
psa_get_key_data_from_key_slot(slot, &key_data, &key_bytes);
|
||||
|
||||
if (op == PSA_INVALID_OPERATION) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
#if IS_USED(MODULE_PSA_CIPHER_AES_128_CBC)
|
||||
case PSA_CBC_NO_PAD_AES_128:
|
||||
return psa_cipher_cbc_aes_128_encrypt(attributes, key_data, *key_bytes, alg, input,
|
||||
input_length, output, output_size, output_length);
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_CIPHER_AES_192_CBC)
|
||||
case PSA_CBC_NO_PAD_AES_192:
|
||||
return psa_cipher_cbc_aes_192_encrypt(attributes, key_data, *key_bytes, alg, input,
|
||||
input_length, output, output_size, output_length);
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_CIPHER_AES_256_CBC)
|
||||
case PSA_CBC_NO_PAD_AES_256:
|
||||
return psa_cipher_cbc_aes_256_encrypt(attributes, key_data, *key_bytes, alg, input,
|
||||
input_length, output, output_size, output_length);
|
||||
#endif
|
||||
default:
|
||||
(void)slot;
|
||||
(void)input;
|
||||
(void)input_length;
|
||||
(void)output;
|
||||
(void)output_size;
|
||||
(void)output_length;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t psa_algorithm_dispatch_cipher_decrypt( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_cipher_op_t op = PSA_ENCODE_CIPHER_OPERATION(alg, attributes->bits, attributes->type);
|
||||
uint8_t *key_data = NULL;
|
||||
size_t *key_bytes = NULL;
|
||||
|
||||
psa_get_key_data_from_key_slot(slot, &key_data, &key_bytes);
|
||||
|
||||
if (op == PSA_INVALID_OPERATION) {
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
switch (op) {
|
||||
#if IS_USED(MODULE_PSA_CIPHER_AES_128_CBC)
|
||||
case PSA_CBC_NO_PAD_AES_128:
|
||||
return psa_cipher_cbc_aes_128_decrypt(attributes, key_data, *key_bytes, alg, input,
|
||||
input_length, output, output_size, output_length);
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_CIPHER_AES_192_CBC)
|
||||
case PSA_CBC_NO_PAD_AES_192:
|
||||
return psa_cipher_cbc_aes_192_decrypt(attributes, key_data, *key_bytes, alg, input,
|
||||
input_length, output, output_size, output_length);
|
||||
#endif
|
||||
#if IS_USED(MODULE_PSA_CIPHER_AES_256_CBC)
|
||||
case PSA_CBC_NO_PAD_AES_256:
|
||||
return psa_cipher_cbc_aes_256_decrypt(attributes, key_data, *key_bytes, alg, input,
|
||||
input_length, output, output_size, output_length);
|
||||
#endif
|
||||
default:
|
||||
(void)slot;
|
||||
(void)input;
|
||||
(void)input_length;
|
||||
(void)output;
|
||||
(void)output_size;
|
||||
(void)output_length;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t psa_algorithm_dispatch_mac_compute(const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_NOT_SUPPORTED;
|
||||
uint8_t *key_data = NULL;
|
||||
size_t *key_bytes = NULL;
|
||||
|
||||
psa_get_key_data_from_key_slot(slot, &key_data, &key_bytes);
|
||||
|
||||
switch (alg) {
|
||||
#if IS_USED(MODULE_PSA_MAC_HMAC_SHA_256)
|
||||
case PSA_ALG_HMAC(PSA_ALG_SHA_256):
|
||||
status = psa_mac_compute_hmac_sha256(attributes, key_data, *key_bytes, input, input_length,
|
||||
mac, mac_size, mac_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
(void)status;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
(void)attributes;
|
||||
(void)input;
|
||||
(void)input_length;
|
||||
(void)mac;
|
||||
(void)mac_size;
|
||||
(void)mac_length;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
441
sys/psa_crypto/psa_crypto_location_dispatch.c
Normal file
441
sys/psa_crypto/psa_crypto_location_dispatch.c
Normal file
@ -0,0 +1,441 @@
|
||||
/*
|
||||
* 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 sys_psa_crypto_loc_disp
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Dispatch calls from the PSA Crypto API to an available backend.
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "kernel_defines.h"
|
||||
#include "psa/crypto.h"
|
||||
#include "psa_crypto_algorithm_dispatch.h"
|
||||
#include "psa_crypto_slot_management.h"
|
||||
#include "psa_crypto_se_management.h"
|
||||
#include "psa_crypto_se_driver.h"
|
||||
|
||||
psa_status_t psa_location_dispatch_generate_key(const psa_key_attributes_t *attributes,
|
||||
psa_key_slot_t *slot)
|
||||
{
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
psa_status_t status;
|
||||
const psa_drv_se_t *drv;
|
||||
psa_drv_se_context_t *drv_context;
|
||||
psa_key_slot_number_t *slot_number = psa_key_slot_get_slot_number(slot);
|
||||
|
||||
uint8_t *pubkey_data = NULL;
|
||||
size_t *pubkey_data_len = NULL;
|
||||
|
||||
psa_get_public_key_data_from_key_slot(slot, &pubkey_data, &pubkey_data_len);
|
||||
|
||||
if (psa_get_se_driver(attributes->lifetime, &drv, &drv_context)) {
|
||||
if (drv->key_management == NULL || drv->key_management->p_generate == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
status = drv->key_management->p_generate(drv_context, *slot_number, attributes, pubkey_data,
|
||||
*pubkey_data_len, pubkey_data_len);
|
||||
if (status != PSA_SUCCESS) {
|
||||
/* In case anything goes wrong, free the key slot for reuse. */
|
||||
psa_se_drv_data_t *driver = psa_get_se_driver_data(attributes->lifetime);
|
||||
psa_status_t abort_status = drv->key_management->p_destroy(drv_context, driver->ctx.internal.persistent_data, *slot_number);
|
||||
return abort_status == PSA_SUCCESS ? status : abort_status;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif /* MODULE_PSA_SECURE_ELEMENT */
|
||||
|
||||
return psa_algorithm_dispatch_generate_key(attributes, slot);
|
||||
}
|
||||
|
||||
psa_status_t psa_location_dispatch_import_key( const psa_key_attributes_t *attributes,
|
||||
const uint8_t *data, size_t data_length,
|
||||
psa_key_slot_t *slot, size_t *bits)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(attributes->lifetime);
|
||||
uint8_t *key_data = NULL;
|
||||
size_t *key_bytes = NULL;
|
||||
size_t key_data_size;
|
||||
|
||||
key_data_size = psa_get_key_data_from_key_slot(slot, &key_data, &key_bytes);
|
||||
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
const psa_drv_se_t *drv;
|
||||
psa_drv_se_context_t *drv_context;
|
||||
psa_key_slot_number_t *slot_number = psa_key_slot_get_slot_number(slot);
|
||||
|
||||
if (psa_get_se_driver(attributes->lifetime, &drv, &drv_context)) {
|
||||
if (drv->key_management == NULL || drv->key_management->p_import == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
*bits = 0;
|
||||
|
||||
status = drv->key_management->p_import(drv_context, *slot_number,
|
||||
attributes, data,
|
||||
data_length, bits);
|
||||
if (status != PSA_SUCCESS) {
|
||||
/* In case anything goes wrong, free the key slot for reuse. */
|
||||
psa_se_drv_data_t *driver = psa_get_se_driver_data(attributes->lifetime);
|
||||
psa_status_t abort_status = drv->key_management->p_destroy(drv_context, driver->ctx.internal.persistent_data, *slot_number);
|
||||
return abort_status == PSA_SUCCESS ? status : abort_status;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif /* MODULE_PSA_SECURE_ELEMENT */
|
||||
|
||||
switch (location) {
|
||||
case PSA_KEY_LOCATION_LOCAL_STORAGE:
|
||||
return psa_builtin_import_key(attributes, data, data_length, key_data, key_data_size, key_bytes, bits);
|
||||
default:
|
||||
(void)status;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t psa_location_dispatch_cipher_encrypt_setup( psa_cipher_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const psa_key_slot_t *slot,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(attributes->lifetime);
|
||||
if (location != PSA_KEY_LOCATION_LOCAL_STORAGE) {
|
||||
const psa_drv_se_t *drv;
|
||||
psa_drv_se_context_t *drv_context;
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_slot_number_t *slot_number = psa_key_slot_get_slot_number(slot);
|
||||
|
||||
uint8_t *key_data = NULL;
|
||||
size_t *key_bytes = NULL;
|
||||
psa_get_key_data_from_key_slot(slot, &key_data, &key_bytes);
|
||||
|
||||
if (psa_get_se_driver(attributes->lifetime, &drv, &drv_context)) {
|
||||
if (drv->cipher == NULL || drv->cipher->p_setup == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
status = drv->cipher->p_setup(drv_context, &operation->backend_ctx.se_ctx, *slot_number,
|
||||
attributes->policy.alg, PSA_CRYPTO_DRIVER_ENCRYPT);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
}
|
||||
#endif /* MODULE_PSA_SECURE_ELEMENT */
|
||||
(void)operation;
|
||||
(void)attributes;
|
||||
(void)slot;
|
||||
(void)alg;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
psa_status_t psa_location_dispatch_cipher_decrypt_setup(psa_cipher_operation_t *operation,
|
||||
const psa_key_attributes_t *attributes,
|
||||
const psa_key_slot_t *slot,
|
||||
psa_algorithm_t alg)
|
||||
{
|
||||
(void)operation;
|
||||
(void)attributes;
|
||||
(void)slot;
|
||||
(void)alg;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
/**
|
||||
* @brief Single part function for cipher encryption and decryption on a secure element
|
||||
*
|
||||
* Some secure elements don't provide single part operations for cipher encryption.
|
||||
* This is a wrapper function, to support those.
|
||||
*
|
||||
* @param drv
|
||||
* @param drv_context
|
||||
* @param attributes
|
||||
* @param alg
|
||||
* @param direction
|
||||
* @param slot
|
||||
* @param input
|
||||
* @param input_length
|
||||
* @param output
|
||||
* @param output_size
|
||||
* @param output_length
|
||||
* @return @ref psa_status_t
|
||||
*/
|
||||
static psa_status_t psa_se_cipher_encrypt_decrypt( const psa_drv_se_t *drv,
|
||||
psa_drv_se_context_t *drv_context,
|
||||
const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
psa_encrypt_or_decrypt_t direction,
|
||||
psa_key_slot_number_t slot,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_cipher_operation_t operation = psa_cipher_operation_init();
|
||||
psa_se_cipher_context_t *se_ctx = &operation.backend_ctx.se_ctx;
|
||||
size_t input_offset = 0;
|
||||
size_t output_offset = 0;
|
||||
|
||||
*output_length = 0;
|
||||
|
||||
if (drv->cipher == NULL ||
|
||||
drv->cipher->p_setup == NULL ||
|
||||
drv->cipher->p_set_iv == NULL ||
|
||||
drv->cipher->p_update == NULL ||
|
||||
drv->cipher->p_finish == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
status = drv->cipher->p_setup(drv_context, se_ctx, slot, alg, direction);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (alg == PSA_ALG_CBC_NO_PADDING) {
|
||||
operation.iv_required = 1;
|
||||
operation.default_iv_length = PSA_CIPHER_IV_LENGTH(psa_get_key_type(attributes), alg);
|
||||
|
||||
if (direction == PSA_CRYPTO_DRIVER_ENCRYPT) {
|
||||
/* In case of encryption, we need to generate and set an IV. The IV will be written
|
||||
into the first 16 bytes of the output buffer. */
|
||||
size_t iv_length = 0;
|
||||
status = psa_cipher_generate_iv(&operation, output, operation.default_iv_length,
|
||||
&iv_length);
|
||||
|
||||
status = drv->cipher->p_set_iv(se_ctx, output, iv_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
/* Increase output buffer offset to IV length to write ciphertext to buffer after IV */
|
||||
output_offset += iv_length;
|
||||
*output_length += iv_length;
|
||||
}
|
||||
else {
|
||||
/* In case of decryption the IV to be used must be provided by the caller and is
|
||||
contained in the first 16 Bytes of the input buffer. */
|
||||
status = drv->cipher->p_set_iv(se_ctx, input, operation.default_iv_length);
|
||||
|
||||
/* Increase input buffer offset to IV length to start decryption
|
||||
with actual cipher text */
|
||||
input_offset += operation.default_iv_length;
|
||||
}
|
||||
}
|
||||
|
||||
status = drv->cipher->p_update(se_ctx, input + input_offset, input_length - input_offset,
|
||||
output + output_offset, output_size - output_offset,
|
||||
output_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
psa_cipher_abort(&operation);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = drv->cipher->p_finish(se_ctx, output, output_size, output_length);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#endif /* CONFIG_PSA_SECURE_ELEMENT */
|
||||
|
||||
psa_status_t psa_location_dispatch_cipher_encrypt( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
const psa_drv_se_t *drv;
|
||||
psa_drv_se_context_t *drv_context;
|
||||
psa_key_slot_number_t *slot_number = psa_key_slot_get_slot_number(slot);
|
||||
|
||||
if (psa_get_se_driver(attributes->lifetime, &drv, &drv_context)) {
|
||||
if (alg == PSA_ALG_ECB_NO_PADDING) {
|
||||
if (drv->cipher == NULL || drv->cipher->p_ecb == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
status = drv->cipher->p_ecb(drv_context, *slot_number, alg, PSA_CRYPTO_DRIVER_ENCRYPT,
|
||||
input, input_length, output, output_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* The SE interface does not support single part functions for other algorithms than ECB,
|
||||
so we need to build one ourselves */
|
||||
status = psa_se_cipher_encrypt_decrypt(drv, drv_context, attributes, alg,
|
||||
PSA_CRYPTO_DRIVER_ENCRYPT, *slot_number, input,
|
||||
input_length, output, output_size, output_length);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PSA_SECURE_ELEMENT */
|
||||
return psa_algorithm_dispatch_cipher_encrypt(attributes, alg, slot, input, input_length, output,
|
||||
output_size, output_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_location_dispatch_cipher_decrypt( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *output,
|
||||
size_t output_size,
|
||||
size_t *output_length)
|
||||
{
|
||||
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
const psa_drv_se_t *drv;
|
||||
psa_drv_se_context_t *drv_context;
|
||||
psa_key_slot_number_t *slot_number = psa_key_slot_get_slot_number(slot);
|
||||
|
||||
if (psa_get_se_driver(attributes->lifetime, &drv, &drv_context)) {
|
||||
if (alg == PSA_ALG_ECB_NO_PADDING) {
|
||||
if (drv->cipher == NULL || drv->cipher->p_ecb == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
status = drv->cipher->p_ecb(drv_context, *slot_number, alg, PSA_CRYPTO_DRIVER_DECRYPT,
|
||||
input, input_length, output, output_size);
|
||||
if (status != PSA_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
status = psa_se_cipher_encrypt_decrypt(drv, drv_context, attributes, alg,
|
||||
PSA_CRYPTO_DRIVER_DECRYPT, *slot_number, input,
|
||||
input_length, output, output_size, output_length);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* CONFIG_PSA_SECURE_ELEMENT */
|
||||
return psa_algorithm_dispatch_cipher_decrypt(attributes, alg, slot, input, input_length,
|
||||
output, output_size, output_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_location_dispatch_sign_hash( const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
uint8_t *signature,
|
||||
size_t signature_size,
|
||||
size_t *signature_length)
|
||||
{
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
const psa_drv_se_t *drv;
|
||||
psa_drv_se_context_t *drv_context;
|
||||
psa_key_slot_number_t *slot_number = psa_key_slot_get_slot_number(slot);
|
||||
|
||||
uint8_t *key_data = NULL;
|
||||
size_t *key_bytes = NULL;
|
||||
psa_get_key_data_from_key_slot(slot, &key_data, &key_bytes);
|
||||
|
||||
if (psa_get_se_driver(attributes->lifetime, &drv, &drv_context)) {
|
||||
if (drv->asymmetric == NULL || drv->asymmetric->p_sign == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
return drv->asymmetric->p_sign(drv_context, *slot_number, alg, hash, hash_length, signature,
|
||||
signature_size, signature_length);
|
||||
}
|
||||
|
||||
(void)key_bytes;
|
||||
#endif /* CONFIG_PSA_SECURE_ELEMENT */
|
||||
|
||||
return psa_algorithm_dispatch_sign_hash(attributes, alg, slot, hash, hash_length, signature,
|
||||
signature_size, signature_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_location_dispatch_verify_hash(const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *hash,
|
||||
size_t hash_length,
|
||||
const uint8_t *signature,
|
||||
size_t signature_length)
|
||||
{
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
const psa_drv_se_t *drv;
|
||||
psa_drv_se_context_t *drv_context;
|
||||
psa_key_slot_number_t *slot_number = psa_key_slot_get_slot_number(slot);
|
||||
|
||||
uint8_t *key_data = NULL;
|
||||
size_t *key_bytes = NULL;
|
||||
psa_get_key_data_from_key_slot(slot, &key_data, &key_bytes);
|
||||
|
||||
if (psa_get_se_driver(attributes->lifetime, &drv, &drv_context)) {
|
||||
if (drv->asymmetric == NULL || drv->asymmetric->p_verify == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
return drv->asymmetric->p_verify(drv_context, *slot_number, alg, hash, hash_length,
|
||||
signature, signature_length);
|
||||
}
|
||||
|
||||
(void)key_bytes;
|
||||
#endif /* CONFIG_PSA_SECURE_ELEMENT */
|
||||
|
||||
return psa_algorithm_dispatch_verify_hash(attributes, alg, slot, hash, hash_length, signature,
|
||||
signature_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_location_dispatch_mac_compute(const psa_key_attributes_t *attributes,
|
||||
psa_algorithm_t alg,
|
||||
const psa_key_slot_t *slot,
|
||||
const uint8_t *input,
|
||||
size_t input_length,
|
||||
uint8_t *mac,
|
||||
size_t mac_size,
|
||||
size_t *mac_length)
|
||||
{
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
const psa_drv_se_t *drv;
|
||||
psa_drv_se_context_t *drv_context;
|
||||
psa_key_slot_number_t *slot_number = psa_key_slot_get_slot_number(slot);
|
||||
|
||||
uint8_t *key_data = NULL;
|
||||
size_t *key_bytes = NULL;
|
||||
psa_get_key_data_from_key_slot(slot, &key_data, &key_bytes);
|
||||
|
||||
if (psa_get_se_driver(attributes->lifetime, &drv, &drv_context)) {
|
||||
if (drv->mac == NULL || drv->mac->p_mac == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
return drv->mac->p_mac(drv_context, input, input_length, *slot_number, alg, mac, mac_size,
|
||||
mac_length);
|
||||
}
|
||||
|
||||
(void)key_bytes;
|
||||
#endif /* CONFIG_PSA_SECURE_ELEMENT */
|
||||
|
||||
return psa_algorithm_dispatch_mac_compute(attributes, alg, slot, input, input_length, mac,
|
||||
mac_size, mac_length);
|
||||
}
|
||||
|
||||
psa_status_t psa_location_dispatch_generate_random(uint8_t *output,
|
||||
size_t output_size)
|
||||
{
|
||||
return psa_builtin_generate_random(output, output_size);
|
||||
}
|
||||
10
sys/psa_crypto/psa_key_slot_mgmt/Kconfig
Normal file
10
sys/psa_crypto/psa_key_slot_mgmt/Kconfig
Normal file
@ -0,0 +1,10 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
config MODULE_PSA_KEY_SLOT_MGMT
|
||||
bool
|
||||
default y if PACKAGE_PSA_ARCH_TESTS
|
||||
4
sys/psa_crypto/psa_key_slot_mgmt/Makefile
Normal file
4
sys/psa_crypto/psa_key_slot_mgmt/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
MODULE := psa_key_slot_mgmt
|
||||
INCLUDES += -I$(RIOTBASE)/sys/psa_crypto/include
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
539
sys/psa_crypto/psa_key_slot_mgmt/psa_crypto_slot_management.c
Normal file
539
sys/psa_crypto/psa_key_slot_mgmt/psa_crypto_slot_management.c
Normal file
@ -0,0 +1,539 @@
|
||||
/*
|
||||
* 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 sys_psa_crypto_slot_mgmt
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief PSA Crypto Key Slot Management implementation
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "clist.h"
|
||||
#include "psa_crypto_slot_management.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
/**
|
||||
* @brief Structure for a protected key slot.
|
||||
*
|
||||
* These slots hold Slot Numbers for keys in protected storage and, if the key type is an
|
||||
* asymmetric key pair, the public key.
|
||||
*/
|
||||
typedef struct {
|
||||
clist_node_t node;
|
||||
size_t lock_count;
|
||||
psa_key_attributes_t attr;
|
||||
struct prot_key_data {
|
||||
psa_key_slot_number_t slot_number;
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ASYMMETRIC)
|
||||
uint8_t pubkey_data[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
|
||||
size_t pubkey_data_len;
|
||||
#endif
|
||||
} key;
|
||||
} psa_prot_key_slot_t;
|
||||
|
||||
/**
|
||||
* @brief Array containing the protected key slots
|
||||
*/
|
||||
static psa_prot_key_slot_t protected_key_slots[PSA_PROTECTED_KEY_COUNT];
|
||||
|
||||
/**
|
||||
* @brief List pointing to empty protected key slots
|
||||
*/
|
||||
static clist_node_t protected_list_empty;
|
||||
#endif /* MODULE_PSA_SECURE_ELEMENT_ASYMMETRIC */
|
||||
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC)
|
||||
/**
|
||||
* @brief Structure for asymmetric key pairs.
|
||||
*
|
||||
* Contains asymmetric private and public key pairs.
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
clist_node_t node;
|
||||
size_t lock_count;
|
||||
psa_key_attributes_t attr;
|
||||
struct key_pair_data {
|
||||
/** Contains asymmetric private key*/
|
||||
uint8_t privkey_data[PSA_BITS_TO_BYTES(PSA_MAX_PRIV_KEY_SIZE)];
|
||||
/** Contains actual size of asymmetric private key */
|
||||
size_t privkey_data_len;
|
||||
/** Contains asymmetric public key */
|
||||
uint8_t pubkey_data[PSA_EXPORT_PUBLIC_KEY_MAX_SIZE];
|
||||
/*!< Contains actual size of asymmetric private key */
|
||||
size_t pubkey_data_len;
|
||||
} key;
|
||||
} psa_key_pair_slot_t;
|
||||
|
||||
/**
|
||||
* @brief Array containing the asymmetric key slots
|
||||
*/
|
||||
static psa_key_pair_slot_t key_pair_slots[PSA_ASYMMETRIC_KEYPAIR_COUNT];
|
||||
|
||||
/**
|
||||
* @brief List pointing to empty asymmetric key slots
|
||||
*/
|
||||
static clist_node_t key_pair_list_empty;
|
||||
#endif /* MODULE_PSA_ASYMMETRIC */
|
||||
|
||||
/**
|
||||
* @brief Array containing the single key slots
|
||||
*/
|
||||
static psa_key_slot_t single_key_slots[PSA_SINGLE_KEY_COUNT];
|
||||
|
||||
/**
|
||||
* @brief List pointing to empty single key slots
|
||||
*/
|
||||
static clist_node_t single_key_list_empty;
|
||||
|
||||
/**
|
||||
* @brief Global list of used key slots
|
||||
*/
|
||||
static clist_node_t key_slot_list;
|
||||
|
||||
/**
|
||||
* @brief Counter for volatile key IDs.
|
||||
*/
|
||||
static psa_key_id_t key_id_count = PSA_KEY_ID_VOLATILE_MIN;
|
||||
|
||||
/**
|
||||
* @brief Get the correct empty slot list, depending on the key type
|
||||
*
|
||||
* @param attr
|
||||
* @return clist_node_t* Pointer to the list the key is supposed to be stored in,
|
||||
* according to its attributes
|
||||
*/
|
||||
static clist_node_t * psa_get_empty_key_slot_list(const psa_key_attributes_t *attr)
|
||||
{
|
||||
if (!psa_key_lifetime_is_external(attr->lifetime)) {
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC)
|
||||
if (PSA_KEY_TYPE_IS_KEY_PAIR(attr->type)) {
|
||||
return &key_pair_list_empty;
|
||||
}
|
||||
#endif /* MODULE_PSA_ASYMMETRIC */
|
||||
return &single_key_list_empty;
|
||||
}
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
return &protected_list_empty;
|
||||
#else
|
||||
return NULL;
|
||||
#endif /* MODULE_PSA_SECURE_ELEMENT */
|
||||
}
|
||||
|
||||
void psa_init_key_slots(void)
|
||||
{
|
||||
DEBUG("List Node Size: %d\n", sizeof(clist_node_t));
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
memset(protected_key_slots, 0, sizeof(protected_key_slots));
|
||||
|
||||
#if PSA_PROTECTED_KEY_COUNT
|
||||
for (size_t i = 0; i < PSA_PROTECTED_KEY_COUNT; i++) {
|
||||
clist_rpush(&protected_list_empty, &protected_key_slots[i].node);
|
||||
}
|
||||
#endif /* PSA_PROTECTED_KEY_COUNT */
|
||||
|
||||
DEBUG("Protected Slot Count: %d, Size: %d\n", PSA_PROTECTED_KEY_COUNT,
|
||||
sizeof(psa_prot_key_slot_t));
|
||||
DEBUG("Protected Slot Array Size: %d\n", sizeof(protected_key_slots));
|
||||
DEBUG("Protected Slot Empty List Size: %d\n", clist_count(&protected_list_empty));
|
||||
#endif /* MODULE_PSA_SECURE_ELEMENT */
|
||||
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC)
|
||||
memset(key_pair_slots, 0, sizeof(key_pair_slots));
|
||||
|
||||
#if PSA_ASYMMETRIC_KEYPAIR_COUNT
|
||||
for (size_t i = 0; i < PSA_ASYMMETRIC_KEYPAIR_COUNT; i++) {
|
||||
clist_rpush(&key_pair_list_empty, &key_pair_slots[i].node);
|
||||
}
|
||||
#endif /* PSA_ASYMMETRIC_KEYPAIR_COUNT */
|
||||
DEBUG("Asymmetric Slot Count: %d, Size: %d\n", PSA_ASYMMETRIC_KEYPAIR_COUNT,
|
||||
sizeof(psa_key_pair_slot_t));
|
||||
DEBUG("Asymmetric Slot Array Size: %d\n", sizeof(key_pair_slots));
|
||||
DEBUG("Asymmetric Slot Empty List Size: %d\n", clist_count(&key_pair_list_empty));
|
||||
#endif /* MODULE_PSA_ASYMMETRIC */
|
||||
|
||||
memset(single_key_slots, 0, sizeof(single_key_slots));
|
||||
#if PSA_SINGLE_KEY_COUNT
|
||||
for (size_t i = 0; i < PSA_SINGLE_KEY_COUNT; i++) {
|
||||
clist_rpush(&single_key_list_empty, &single_key_slots[i].node);
|
||||
}
|
||||
#endif
|
||||
DEBUG("Single Key Slot Count: %d, Size: %d\n", PSA_SINGLE_KEY_COUNT, sizeof(psa_key_slot_t));
|
||||
DEBUG("Single Key Slot Array Size: %d\n", sizeof(single_key_slots));
|
||||
DEBUG("Single Key Slot Empty List Size: %d\n", clist_count(&single_key_list_empty));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Wipe key slot with correct key slot size
|
||||
*
|
||||
* @param slot Key sloit to be wiped
|
||||
*/
|
||||
static void psa_wipe_real_slot_type(psa_key_slot_t *slot)
|
||||
{
|
||||
psa_key_attributes_t attr = slot->attr;
|
||||
|
||||
if (!psa_key_lifetime_is_external(attr.lifetime)) {
|
||||
if (!PSA_KEY_TYPE_IS_KEY_PAIR(attr.type)) {
|
||||
memset(slot, 0, sizeof(psa_key_slot_t));
|
||||
}
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC)
|
||||
else {
|
||||
|
||||
memset((psa_key_pair_slot_t *)slot, 0, sizeof(psa_key_pair_slot_t));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
else {
|
||||
memset((psa_prot_key_slot_t *)slot, 0, sizeof(psa_prot_key_slot_t));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
psa_status_t psa_wipe_key_slot(psa_key_slot_t *slot)
|
||||
{
|
||||
/* Get list the slot is stored in */
|
||||
clist_node_t *empty_list = psa_get_empty_key_slot_list(&slot->attr);
|
||||
|
||||
if (empty_list == NULL) {
|
||||
return PSA_ERROR_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
/* Get node to remove from key slot list */
|
||||
clist_node_t *n = clist_remove(&key_slot_list, &slot->node);
|
||||
|
||||
if (n == NULL) {
|
||||
return PSA_ERROR_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
psa_key_slot_t *tmp = container_of(n, psa_key_slot_t, node);
|
||||
|
||||
/* Wipe slot associated with node */
|
||||
psa_wipe_real_slot_type(tmp);
|
||||
|
||||
/* Append node to empty list for later reuse */
|
||||
clist_rpush(empty_list, n);
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
void psa_wipe_all_key_slots(void)
|
||||
{
|
||||
/* Move all list items to empty lists */
|
||||
while (!clist_is_empty(&key_slot_list)) {
|
||||
clist_node_t *to_remove = clist_rpop(&key_slot_list);
|
||||
psa_key_slot_t *slot = container_of(to_remove, psa_key_slot_t, node);
|
||||
clist_node_t *empty_list = psa_get_empty_key_slot_list(&slot->attr);
|
||||
|
||||
psa_wipe_real_slot_type(slot);
|
||||
clist_rpush(empty_list, to_remove);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check whether a given key ID equals the ID of the given node.
|
||||
*
|
||||
* This is the break condition of the @ref clist_foreach function used
|
||||
* in @ref psa_get_and_lock_key_slot_in_memory.
|
||||
* clist_foreach iterates over all key slots and calls this function
|
||||
* to compare each slot's key ID to the given input key ID.
|
||||
* If they are equal, this function returns True and breaks the foreach
|
||||
* loop.
|
||||
*
|
||||
* For more information see core/lib/include/clist.h.
|
||||
*
|
||||
* @param n Pointer to clist node referencing a key slot
|
||||
* @param arg Pointer to required key ID
|
||||
* @return int
|
||||
* 1 if input ID equals node ID
|
||||
* 0 otherwise
|
||||
*/
|
||||
static int node_id_equals_key_id(clist_node_t *n, void *arg)
|
||||
{
|
||||
psa_key_slot_t *slot = container_of(n, psa_key_slot_t, node);
|
||||
psa_key_id_t id = *((psa_key_id_t *)arg);
|
||||
|
||||
if (slot->attr.id == id) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find the key slot containing the key with a specified ID
|
||||
*
|
||||
* @param id ID of the required key
|
||||
* @param p_slot Pointer to the slot that will contain the required key
|
||||
*
|
||||
* @return @ref PSA_SUCCESS
|
||||
* @ref PSA_ERROR_INVALID_HANDLE
|
||||
* @ref PSA_ERROR_CORRUPTION_DETECTED
|
||||
* @ref PSA_ERROR_NOT_SUPPORTED
|
||||
*/
|
||||
static psa_status_t psa_get_and_lock_key_slot_in_memory(psa_key_id_t id, psa_key_slot_t **p_slot)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
if (psa_key_id_is_volatile(id)) {
|
||||
clist_node_t *slot_node = clist_foreach(&key_slot_list, node_id_equals_key_id, &id);
|
||||
if (slot_node == NULL) {
|
||||
return PSA_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
psa_key_slot_t *slot = container_of(slot_node, psa_key_slot_t, node);
|
||||
status = psa_lock_key_slot(slot);
|
||||
if (status == PSA_SUCCESS) {
|
||||
*p_slot = slot;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
psa_status_t psa_get_and_lock_key_slot(psa_key_id_t id, psa_key_slot_t **p_slot)
|
||||
{
|
||||
/* TODO validate ID */
|
||||
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
|
||||
*p_slot = NULL;
|
||||
|
||||
status = psa_get_and_lock_key_slot_in_memory(id, p_slot);
|
||||
if (status != PSA_ERROR_DOES_NOT_EXIST) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* TODO: get persistent key from storage and load into slot */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Allocate a free slot for a new key creation
|
||||
*
|
||||
* @param p_slot Pointer that will contain the free key slot.
|
||||
* @param attr Attributes of type @ref psa_key_attrubutes_t for the key to be created
|
||||
*
|
||||
* @return @ref PSA_SUCCESS
|
||||
* @ref PSA_ERROR_DOES_NOT_EXIST No key slots for this type of key exist
|
||||
* @ref PSA_ERROR_INSUFFICIENT_STORAGE
|
||||
*/
|
||||
static psa_status_t psa_allocate_key_slot_in_list(psa_key_slot_t **p_slot,
|
||||
const psa_key_attributes_t *attr)
|
||||
{
|
||||
clist_node_t *empty_list = psa_get_empty_key_slot_list(attr);
|
||||
|
||||
if (empty_list == NULL) {
|
||||
return PSA_ERROR_DOES_NOT_EXIST;
|
||||
}
|
||||
|
||||
/* Check if any empty elements of this key slot type are left */
|
||||
if (clist_is_empty(empty_list)) {
|
||||
DEBUG("Key Slot MGMT: No PSA Key Slot available\n");
|
||||
return PSA_ERROR_INSUFFICIENT_STORAGE;
|
||||
}
|
||||
|
||||
/* TODO: If no slots left: Look for slot in list with persistent key
|
||||
(key will be stored in persistent memory and slot can be reused) */
|
||||
|
||||
/* Remove key slote node from empty list and append to actual list */
|
||||
clist_node_t *new_slot = clist_rpop(empty_list);
|
||||
|
||||
clist_rpush(&key_slot_list, new_slot);
|
||||
|
||||
psa_key_slot_t *slot = container_of(new_slot, psa_key_slot_t, node);
|
||||
|
||||
*p_slot = slot;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_allocate_empty_key_slot( psa_key_id_t *id,
|
||||
const psa_key_attributes_t *attr,
|
||||
psa_key_slot_t **p_slot)
|
||||
{
|
||||
psa_status_t status = PSA_ERROR_CORRUPTION_DETECTED;
|
||||
psa_key_slot_t *new_slot = NULL;
|
||||
|
||||
/* Change later, when we also have persistent keys */
|
||||
if (key_id_count == PSA_KEY_ID_VOLATILE_MAX) {
|
||||
DEBUG("Key Slot MGMT: Maximum key ID reached\n");
|
||||
return PSA_ERROR_INSUFFICIENT_STORAGE;
|
||||
}
|
||||
|
||||
status = psa_allocate_key_slot_in_list(&new_slot, attr);
|
||||
if (status != PSA_SUCCESS) {
|
||||
*p_slot = NULL;
|
||||
*id = 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
if (new_slot != NULL) {
|
||||
status = psa_lock_key_slot(new_slot);
|
||||
if (status != PSA_SUCCESS) {
|
||||
*p_slot = NULL;
|
||||
*id = 0;
|
||||
return status;
|
||||
}
|
||||
*id = key_id_count++;
|
||||
*p_slot = new_slot;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
status = PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
*p_slot = NULL;
|
||||
*id = 0;
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_lock_key_slot(psa_key_slot_t *slot)
|
||||
{
|
||||
if (slot->lock_count >= SIZE_MAX) {
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
|
||||
slot->lock_count++;
|
||||
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_status_t psa_unlock_key_slot(psa_key_slot_t *slot)
|
||||
{
|
||||
if (slot == NULL) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
if (slot->lock_count > 0) {
|
||||
slot->lock_count--;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
|
||||
psa_status_t psa_validate_key_location(psa_key_lifetime_t lifetime, psa_se_drv_data_t **p_drv)
|
||||
{
|
||||
if (psa_key_lifetime_is_external(lifetime)) {
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
psa_se_drv_data_t *driver = psa_get_se_driver_data(lifetime);
|
||||
if (driver != NULL) {
|
||||
if (p_drv != NULL) {
|
||||
*p_drv = driver;
|
||||
}
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
#else
|
||||
(void)p_drv;
|
||||
#endif /* MODULE_PSA_SECURE_ELEMENT */
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
else {
|
||||
(void)p_drv;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
psa_status_t psa_validate_key_persistence(psa_key_lifetime_t lifetime)
|
||||
{
|
||||
if (PSA_KEY_LIFETIME_IS_VOLATILE(lifetime)) {
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
/* TODO: Implement persistent key storage */
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int psa_is_valid_key_id(psa_key_id_t id, int vendor)
|
||||
{
|
||||
if ((PSA_KEY_ID_USER_MIN <= id) &&
|
||||
(id <= PSA_KEY_ID_USER_MAX)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (vendor
|
||||
&& (PSA_KEY_ID_VENDOR_MIN <= id)
|
||||
&& (id <= PSA_KEY_ID_VENDOR_MAX)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t psa_get_key_data_from_key_slot(const psa_key_slot_t *slot, uint8_t **key_data,
|
||||
size_t **key_bytes)
|
||||
{
|
||||
psa_key_attributes_t attr = slot->attr;
|
||||
size_t key_data_size = 0;
|
||||
|
||||
*key_data = NULL;
|
||||
*key_bytes = NULL;
|
||||
|
||||
|
||||
if (!psa_key_lifetime_is_external(attr.lifetime)) {
|
||||
if (!PSA_KEY_TYPE_IS_KEY_PAIR(attr.type)) {
|
||||
*key_data = (uint8_t *)slot->key.data;
|
||||
*key_bytes = (size_t *)&slot->key.data_len;
|
||||
key_data_size = sizeof(slot->key.data);
|
||||
}
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC)
|
||||
else {
|
||||
*key_data = ((psa_key_pair_slot_t *)slot)->key.privkey_data;
|
||||
*key_bytes = &((psa_key_pair_slot_t *)slot)->key.privkey_data_len;
|
||||
key_data_size = sizeof(((psa_key_pair_slot_t *)slot)->key.privkey_data);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return key_data_size;
|
||||
}
|
||||
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT)
|
||||
psa_key_slot_number_t * psa_key_slot_get_slot_number(const psa_key_slot_t *slot)
|
||||
{
|
||||
return &(((psa_prot_key_slot_t *)slot)->key.slot_number);
|
||||
}
|
||||
#endif
|
||||
|
||||
void psa_get_public_key_data_from_key_slot(const psa_key_slot_t *slot, uint8_t **pubkey_data,
|
||||
size_t **pubkey_data_len)
|
||||
{
|
||||
psa_key_attributes_t attr = slot->attr;
|
||||
|
||||
/* If key type is not asymmetric, no public key exists */
|
||||
if (!PSA_KEY_TYPE_IS_ASYMMETRIC(attr.type)) {
|
||||
*pubkey_data = NULL;
|
||||
*pubkey_data_len = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!psa_key_lifetime_is_external(attr.lifetime)) {
|
||||
if (!PSA_KEY_TYPE_IS_KEY_PAIR(attr.type)) {
|
||||
*pubkey_data = ((psa_key_slot_t *)slot)->key.data;
|
||||
*pubkey_data_len = &((psa_key_slot_t *)slot)->key.data_len;
|
||||
return;
|
||||
}
|
||||
#if IS_USED(MODULE_PSA_ASYMMETRIC)
|
||||
else {
|
||||
*pubkey_data = ((psa_key_pair_slot_t *)slot)->key.pubkey_data;
|
||||
*pubkey_data_len = &((psa_key_pair_slot_t *)slot)->key.pubkey_data_len;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#if IS_USED(MODULE_PSA_SECURE_ELEMENT_ASYMMETRIC)
|
||||
*pubkey_data = ((psa_prot_key_slot_t *)slot)->key.pubkey_data;
|
||||
*pubkey_data_len = &((psa_prot_key_slot_t *)slot)->key.pubkey_data_len;
|
||||
#endif
|
||||
}
|
||||
53
sys/psa_crypto/psa_se_mgmt/Kconfig
Normal file
53
sys/psa_crypto/psa_se_mgmt/Kconfig
Normal file
@ -0,0 +1,53 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
menuconfig MODULE_PSA_SECURE_ELEMENT
|
||||
bool "PSA Secure Elements"
|
||||
select MODULE_PSA_KEY_SLOT_MGMT
|
||||
select MODULE_PSA_SE_MGMT
|
||||
|
||||
if MODULE_PSA_SECURE_ELEMENT
|
||||
|
||||
config MODULE_PSA_SECURE_ELEMENT_MULTIPLE
|
||||
bool "Use multiple secure elements"
|
||||
|
||||
config PSA_MAX_SE_COUNT
|
||||
int
|
||||
prompt "Maximum number of secure elements" if MODULE_PSA_SECURE_ELEMENT_MULTIPLE
|
||||
range 2 255 if MODULE_PSA_SECURE_ELEMENT_MULTIPLE
|
||||
range 1 255
|
||||
|
||||
menuconfig MODULE_PSA_SECURE_ELEMENT_ATECCX08A
|
||||
bool "Microchip ATECCX08A"
|
||||
select PACKAGE_CRYPTOAUTHLIB
|
||||
select MODULE_PSA_SECURE_ELEMENT_CONFIG
|
||||
depends on HAS_PERIPH_I2C
|
||||
help
|
||||
When using Cryptoauthlib as a backend for elliptic curve operations,
|
||||
please also choose the ECC symbol.
|
||||
|
||||
config MODULE_PSA_SECURE_ELEMENT_ATECCX08A_ECC_P256
|
||||
bool "Microchip ATECCX08A Elliptic Curve P256"
|
||||
select PSA_KEY_SIZE_256
|
||||
select MODULE_PSA_SECURE_ELEMENT_ASYMMETRIC
|
||||
depends on MODULE_PSA_SECURE_ELEMENT_ATECCX08A
|
||||
|
||||
config MODULE_PSA_SE_MGMT
|
||||
bool
|
||||
|
||||
config MODULE_PSA_SECURE_ELEMENT_ASYMMETRIC
|
||||
bool
|
||||
help
|
||||
Indicates that an asymmetric operation is used with secure elements.
|
||||
|
||||
config MODULE_PSA_SECURE_ELEMENT_CONFIG
|
||||
bool
|
||||
help
|
||||
Indicates that this SE driver defines a configuration structure for
|
||||
persistent driver data.
|
||||
|
||||
endif # MODULE_PSA_SECURE_ELEMENT
|
||||
3
sys/psa_crypto/psa_se_mgmt/Makefile
Normal file
3
sys/psa_crypto/psa_se_mgmt/Makefile
Normal file
@ -0,0 +1,3 @@
|
||||
MODULE := psa_se_mgmt
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
||||
193
sys/psa_crypto/psa_se_mgmt/psa_crypto_se_management.c
Normal file
193
sys/psa_crypto/psa_se_mgmt/psa_crypto_se_management.c
Normal file
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* 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 psa_crypto_se_mgmt
|
||||
* @{
|
||||
*
|
||||
* @brief PSA Crypto Secure Element Management implementation
|
||||
*
|
||||
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include "psa_crypto_se_management.h"
|
||||
#include "psa_crypto_se_driver.h"
|
||||
|
||||
#define ENABLE_DEBUG 0
|
||||
#include "debug.h"
|
||||
|
||||
/**
|
||||
* @brief Array containing the registered driver instances.
|
||||
*/
|
||||
static psa_se_drv_data_t driver_table[PSA_MAX_SE_COUNT];
|
||||
|
||||
/**
|
||||
* @brief Global counter for registered SE devices.
|
||||
|
||||
*/
|
||||
unsigned psa_se_count = 0;
|
||||
|
||||
psa_status_t psa_register_secure_element(psa_key_location_t location,
|
||||
const psa_drv_se_t *methods,
|
||||
void *psa_se_configuration,
|
||||
const void *drv_transient_data)
|
||||
{
|
||||
size_t i;
|
||||
psa_se_drv_data_t *temp;
|
||||
|
||||
if (psa_se_count >= PSA_MAX_SE_COUNT) {
|
||||
DEBUG("SE Registration: Maximum number of Secure Elements reached.\n");
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
if (methods->hal_version != PSA_DRV_SE_HAL_VERSION) {
|
||||
DEBUG("SE Registration: Driver HAL Version not supported.\n");
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (location == PSA_KEY_LOCATION_LOCAL_STORAGE) {
|
||||
DEBUG("SE Registration: Invalid driver location value.\n");
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (location > PSA_KEY_LOCATION_SE_MAX) {
|
||||
DEBUG("SE Registration: Exhausted maximum number of Secure Element location values.\n");
|
||||
return PSA_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (methods->persistent_data_size > PSA_MAX_PERSISTENT_DATA_SIZE) {
|
||||
DEBUG("SE Registration: Persistent Data is too large.\n");
|
||||
return PSA_ERROR_INSUFFICIENT_MEMORY;
|
||||
}
|
||||
|
||||
/* Find next free slot in driver table */
|
||||
for (i = 0; i < psa_se_count; i++) {
|
||||
if (driver_table[i].location == location) {
|
||||
DEBUG("SE Registration: Device with location 0x%x already exists.\n", (int)location);
|
||||
return PSA_ERROR_ALREADY_EXISTS;
|
||||
}
|
||||
|
||||
if (driver_table[i].location == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
temp = &driver_table[i];
|
||||
temp->location = location;
|
||||
temp->methods = methods;
|
||||
temp->ctx.internal.transient_data = (uintptr_t)drv_transient_data;
|
||||
temp->ctx.internal.persistent_data = psa_se_configuration;
|
||||
temp->ctx.internal.persistent_data_size = methods->persistent_data_size;
|
||||
|
||||
/* TODO: Load Persistent data if persistent_data_size != 0 */
|
||||
psa_se_count++;
|
||||
return PSA_SUCCESS;
|
||||
}
|
||||
|
||||
psa_se_drv_data_t *psa_get_se_driver_data(psa_key_lifetime_t lifetime)
|
||||
{
|
||||
psa_se_drv_data_t *drv = NULL;
|
||||
psa_key_location_t location = PSA_KEY_LIFETIME_GET_LOCATION(lifetime);
|
||||
|
||||
if (location == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < PSA_MAX_SE_COUNT; i++) {
|
||||
if (driver_table[i].location == location) {
|
||||
drv = &driver_table[i];
|
||||
}
|
||||
}
|
||||
|
||||
(void)lifetime;
|
||||
return drv;
|
||||
}
|
||||
|
||||
int psa_get_se_driver(psa_key_lifetime_t lifetime,
|
||||
const psa_drv_se_t **p_methods,
|
||||
psa_drv_se_context_t **p_drv_context)
|
||||
{
|
||||
psa_se_drv_data_t *driver = psa_get_se_driver_data(lifetime);
|
||||
|
||||
if (p_methods != NULL) {
|
||||
*p_methods = (driver ? driver->methods : NULL);
|
||||
}
|
||||
if (p_drv_context != NULL) {
|
||||
*p_drv_context = (driver ? &driver->ctx.context : NULL);
|
||||
}
|
||||
return (driver != NULL);
|
||||
}
|
||||
|
||||
const psa_drv_se_t *psa_get_se_driver_methods(const psa_se_drv_data_t *driver)
|
||||
{
|
||||
return driver->methods;
|
||||
}
|
||||
|
||||
psa_drv_se_context_t *psa_get_se_drv_context(psa_se_drv_data_t *driver)
|
||||
{
|
||||
return &driver->ctx.context;
|
||||
}
|
||||
|
||||
psa_status_t psa_find_free_se_slot(const psa_key_attributes_t *attributes,
|
||||
psa_key_creation_method_t method,
|
||||
psa_se_drv_data_t *driver,
|
||||
psa_key_slot_number_t *slot_number)
|
||||
{
|
||||
psa_status_t status;
|
||||
psa_key_location_t key_location =
|
||||
PSA_KEY_LIFETIME_GET_LOCATION(psa_get_key_lifetime(attributes));
|
||||
|
||||
if (driver->location != key_location) {
|
||||
return PSA_ERROR_CORRUPTION_DETECTED;
|
||||
}
|
||||
|
||||
if (driver->methods->key_management == NULL ||
|
||||
driver->methods->key_management->p_allocate == NULL) {
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
status = driver->methods->key_management->p_allocate(&driver->ctx.context,
|
||||
driver->ctx.internal.persistent_data,
|
||||
attributes, method, slot_number);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_se_key(psa_se_drv_data_t *driver,
|
||||
psa_key_slot_number_t slot_number)
|
||||
{
|
||||
if (driver->methods->key_management == NULL ||
|
||||
driver->methods->key_management->p_destroy == NULL) {
|
||||
return PSA_ERROR_NOT_PERMITTED;
|
||||
}
|
||||
return driver->methods->key_management->p_destroy(&driver->ctx.context,
|
||||
driver->ctx.internal.persistent_data,
|
||||
slot_number);
|
||||
|
||||
/* TODO: Store Persistent Data */
|
||||
}
|
||||
|
||||
psa_status_t psa_load_se_persistent_data(const psa_se_drv_data_t *driver)
|
||||
{
|
||||
(void)driver;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
psa_status_t psa_save_se_persistent_data(const psa_se_drv_data_t *driver)
|
||||
{
|
||||
(void)driver;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
psa_status_t psa_destroy_se_persistent_data(psa_key_location_t location)
|
||||
{
|
||||
(void)location;
|
||||
return PSA_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user