Skip to content

Commit

Permalink
Merge pull request #113 from sehlen-bsi/doc/ms4.2_sca_sphincsplus
Browse files Browse the repository at this point in the history
Side-channel report for SPHINCS+, MS 4.2
  • Loading branch information
reneme authored Aug 16, 2023
2 parents 5d10de2 + 49e079b commit d49a541
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 4 deletions.
10 changes: 9 additions & 1 deletion docs/audit_report/src/06_bibliography.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
Botan Test Report",
Release TBD
.. [BOTAN_GIT] https://github.com/randombit/botan/tree/3.1.1
.. [BOTAN_GIT_300] https://github.com/randombit/botan/tree/3.0.0
.. [BOTAN_GIT_311] https://github.com/randombit/botan/tree/3.1.1
.. [DATA] https://www.usenix.org/conference/usenixsecurity18/presentation/weiser
Expand Down Expand Up @@ -80,4 +82,10 @@
.. [BOTAN_XMSS_MSG_INIT] https://github.com/randombit/botan/blob/3.0.0/src/lib/pubkey/xmss/xmss_hash.cpp#L36
.. [BOTAN_SPHINCSPLUS_TREEHASH] https://github.com/randombit/botan/blob/3.1.1/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_treehash.cpp#L73
.. [BOTAN_SPHINCSPLUS_WOTS_SIGN_AND_PKGEN_SIG_NODE] https://github.com/randombit/botan/blob/3.1.1/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_wots.cpp#L153
.. [BOTAN_SPHINCSPLUS_WOTS_SIGN_AND_PKGEN_SIG_NODE_HC] https://github.com/randombit/botan/blob/3.1.1/src/lib/pubkey/sphincsplus/sphincsplus_common/sp_wots.cpp#L153
.. [NIST_SP_800_208] https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-208.pdf
197 changes: 197 additions & 0 deletions docs/audit_report/src/side_channels/02_04_sphincsplus.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
""""""""
SPHINCS+
""""""""

Analysierte Variante:

- SphincsPlus-sha2-128s-r3.1, deterministic & randomized

Für die Analyse von SPHINCS+ wurde ein Hilfsprogramm geschrieben, das ähnlich wie das Botan CLI die zu analysierenden Funktionen aufruft.
Für die Erzeugung der Signatur wird folgender Aufruf verwendet:

.. code-block:: cpp
auto params = Botan::Sphincs_Parameters::create("SphincsPlus-sha2-128s-r3.1");
Botan::SphincsPlus_PrivateKey priv_key(params.algorithm_identifier(), priv_key_bits);
#if DETERMINISTIC
Botan::PK_Signer sig(priv_key, rng, "Deterministic");
#else
Botan::PK_Signer sig(priv_key, rng, "Randomized");
#endif
signature = sig.sign_message(message, rng);
Der SPHINCS+ Standard verwendet innerhalb des Hypertrees eine Variante von XMSS und bezeichnet diese verkürzt als XMSS.
Dem Standard folgend wird dieses Verfahren auch in diesem Abschnitt als XMSS bezeichnet.

**Modifikation des Hypertrees**

Die Laufzeit zur Erzeugung einer Signatur hängt von der Höhe des Hypertrees und der Anzahl der Merkle-Bäume ab.
Um die Laufzeit zu reduzieren, wird die Gesamthöhe auf vier beschränkt und es werden zwei Merkle-Bäume mit jeweils einer Höhe von zwei verwendet.
Der Algorithmus selbst benötigt diese Einschränkung im Produktiveinsatz nicht.
Die Anpassung erfolgt lediglich, um die Analyse in angemessener Zeit durchführen zu können.
Diese Änderung hat keinen Einfluss auf die Code-Coverage der durchgeführten Seitenkanalanalyse.

**Leakage Zusammenfassung**

DATA detektiert keine Leaks in der analysierten SPHINCS+ Implementierung.
Es werden lediglich Unterschiede in der Programmausführung in Phase 1 von DATA gefunden.
In Phase 2 kann jedoch keine statistische Abhängigkeit zu den verwendeten, geheimen kryptografischen Schlüsseln nachgewiesen werden.

Als Hintergrundinformation sind in den folgenden Abschnitten die Gründe für die Ausführungsunterschiede erläutert.
Insgesamt zeigt die Analyse fünf Unterschiede in der Ausführung auf.
Ein Unterschied wurde innerhalb des FORS-Verfahrens gefunden, die restlichen vier Unterschiede betreffen das XMSS-Verfahren.

**Ausführungsunterschied: FORS - treehash**

Das FORS-Verfahren basiert auf der Verwendung von Merkle-Bäumen.
Der öffentliche FORS-Schlüssel ist der Wurzelknoten in einem Merkle-Baum.
Die Kinder dieses Knotens sind Wurzelknoten einzelner Merkle-Bäume, die zur Signatur einer Nachricht verwendet werden.

Die `treehash` Routine berechnet mithilfe der Blätter eines Merkle-Baums die darüber liegenden Knoten.
Während der Verifikation wird ein Teil der Blätter anhand der Nachricht und der Signatur berechnet.
Die restlichen Blätter oder Knoten eines Merkle-Baums, welche zur Verifikation benötigt werden, sind im sogenannten Authentisierungspfad enthalten.
Dieser ist Bestandteil einer FORS-Signatur und wird bei der Signaturerzeugung generiert.

Die `treehash` Routine detektiert während der Ausführung, ob der aktuell berechnete Knoten dem Authentisierungspfad hinzugefügt werden muss [BOTAN_SPHINCSPLUS_TREEHASH]_.
Ist dies der Fall, kommt es zur Erfüllung einer Kondition im Programmablauf und zu einer geänderten Programmausführung.
Dieser Kontrollflussunterschied wird durch DATA aufgezeigt.
Der Unterschied ist unkritisch, weil die Werte der Knoten innerhalb dieser Merkle-Bäume öffentlich sind.
Folglich ist es auch unkritsch, wenn anhand der Unterschiede ersichtlich ist, welche Knoten zum Authentisierungspfad gehören.
Dieses Wissen ist auch von einer Nachricht und der zugehörigen Signatur ableitbar.

.. code-block:: cpp
void treehash(StrongSpan<SphincsTreeNode> out_root,
StrongSpan<SphincsAuthenticationPath> out_auth_path,
const Sphincs_Parameters& params,
Sphincs_Hash_Functions& hashes,
std::optional<TreeNodeIndex> leaf_idx,
uint32_t idx_offset,
uint32_t total_tree_height,
const GenerateLeafFunction& gen_leaf,
Sphincs_Address& tree_address) {
...
for(TreeNodeIndex idx(0); true; ++idx) {
...
// Now combine the freshly generated right node with previously generated
// left ones
...
for(TreeLayerIndex h(0); true; ++h) {
// Check if we hit the top of the tree
...
// Check if the node we have is a part of the authentication path; if
// it is, write it out. The XOR sum of both nodes (at internal_idx and internal_leaf)
// is 1 iff they have the same parent node in the FORS tree
if(internal_leaf.has_value() && (internal_idx ^ internal_leaf.value()) == 0x01U) {
...
}
**Ausführungsunterschied: WOTS - treehash**

Das XMSS-Verfahren basiert auf dem WOTS-Verfahren und der Verwendung von Merkle-Bäumen.
Ähnlich zum FORS-Verfahren verwendet auch das XMSS-Verfahren die `treehash` Routine.
Auch hier kommt es zu einem ähnlichen Unterschied in der Programmausführung bei dem Hinzufügen einzelner Knoten zu den Authentisierungsdaten einer Signatur [BOTAN_SPHINCSPLUS_TREEHASH]_.
Analog zum FORS-Verfahren ist dieser Unterschied auch beim XMSS-Verfahren unkritisch.

.. code-block:: cpp
void treehash(StrongSpan<SphincsTreeNode> out_root,
StrongSpan<SphincsAuthenticationPath> out_auth_path,
const Sphincs_Parameters& params,
Sphincs_Hash_Functions& hashes,
std::optional<TreeNodeIndex> leaf_idx,
uint32_t idx_offset,
uint32_t total_tree_height,
const GenerateLeafFunction& gen_leaf,
Sphincs_Address& tree_address) {
...
for(TreeNodeIndex idx(0); true; ++idx) {
...
// Now combine the freshly generated right node with previously generated
// left ones
...
for(TreeLayerIndex h(0); true; ++h) {
// Check if we hit the top of the tree
...
// Check if the node we have is a part of the authentication path; if
// it is, write it out. The XOR sum of both nodes (at internal_idx and internal_leaf)
// is 1 iff they have the same parent node in the FORS tree
if(internal_leaf.has_value() && (internal_idx ^ internal_leaf.value()) == 0x01U) {
...
}
**Ausführungsunterschied: WOTS - wots_sign_and_pkgen**

Neben den Unterschieden in der `treehash` Routine werden auch drei Unterschiede in der Funktion `wots_sign_and_pkgen` detektiert.
Diese Funktion generiert die Signaturdaten für das WOTS-Verfahren und die öffentlichen WOTS-Schlüssel für die anderen Blätter im Merkle-Baum.

Der erste Unterschied ist ein Kontrollflussunterschied.
Die Implementierung unterscheidet, ob Signaturdaten für das WOTS-Verfahren erstellt werden müssen oder ob nur der öffentliche WOTS-Schlüssel benötigt wird [BOTAN_SPHINCSPLUS_WOTS_SIGN_AND_PKGEN_SIG_NODE]_.
Diese Information kann auch mithilfe der Nachricht und der zugehörigen Signatur berechnet werden, wodurch der Unterschied als unkritisch eingestuft wird.

.. code-block:: cpp
void wots_sign_and_pkgen(StrongSpan<WotsSignature> sig_out,
StrongSpan<SphincsTreeNode> leaf_out,
const SphincsSecretSeed& secret_seed,
TreeNodeIndex leaf_idx,
std::optional<TreeNodeIndex> sign_leaf_idx,
const std::vector<WotsHashIndex>& wots_steps,
Sphincs_Address& leaf_addr,
Sphincs_Address& pk_addr,
const Sphincs_Parameters& params,
Sphincs_Hash_Functions& hashes) {
...
for(WotsChainIndex i(0); i < params.wots_len(); i++) {
// If the current leaf is part of the signature wots_k stores the chain index
// of the value neccessary for the signature. Otherwise: nullopt (no signature)
const auto wots_k = [&]() -> std::optional<WotsHashIndex> {
if(sign_leaf_idx.has_value() && leaf_idx == sign_leaf_idx.value()) {
return wots_steps[i.get()];
} else {
return std::nullopt;
}
}();
...
Die anderen beiden Ausführungsunterschiede betreffen das Hinzufügen eines Zwischenwerts einer Hash-Kette zu den WOTS-Signaturdaten [BOTAN_SPHINCSPLUS_WOTS_SIGN_AND_PKGEN_SIG_NODE_HC]_.
Bei der Erstellung einer WOTS-Signatur werden die Hash-Ketten nur partiell durchlaufen.
Das Ergebnis wird der WOTS-Signatur hinzugefügt.
Dabei wird die Anzahl der durchgeführten Schritte in einer Hash-Kette ersichtlich.
Das ist unkritisch, weil diese Information auch während der Verifikation anhand der Nachricht und Signatur berechnet wird.

.. code-block:: cpp
void wots_sign_and_pkgen(StrongSpan<WotsSignature> sig_out,
StrongSpan<SphincsTreeNode> leaf_out,
const SphincsSecretSeed& secret_seed,
TreeNodeIndex leaf_idx,
std::optional<TreeNodeIndex> sign_leaf_idx,
const std::vector<WotsHashIndex>& wots_steps,
Sphincs_Address& leaf_addr,
Sphincs_Address& pk_addr,
const Sphincs_Parameters& params,
Sphincs_Hash_Functions& hashes) {
...
for(WotsChainIndex i(0); i < params.wots_len(); i++) {
// If the current leaf is part of the signature wots_k stores the chain index
// of the value neccessary for the signature. Otherwise: nullopt (no signature)
...
// Start with the secret seed
...
// Iterates down the WOTS chain
for(WotsHashIndex k(0);; k++) {
// Check if this is the value that needs to be saved as a part of the WOTS signature
if(wots_k.has_value() && k == wots_k.value()) {
std::copy(buffer_s.begin(), buffer_s.end(), sig.next<WotsNode>(params.n()).begin());
}
9 changes: 6 additions & 3 deletions docs/audit_report/src/side_channels/02_results.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
Evaluierung ausgewählter Algorithmen in Botan
---------------------------------------------

Dieses Kapitel beschreibt die Ergebnisse der Analyse ausgewählter Algorithmen in Botan Version 3.0.0 [BOTAN_GIT]_.
Dieses Kapitel beschreibt die Ergebnisse der Analyse ausgewählter Algorithmen in Botan Version 3.
Dazu wurden die ersten beiden Phasen von DATA verwendet.
Die dritte Phase wurde für die Auswertung der Ergebnisse zunächst nicht benötigt.
Die betrachteten Algorithmen sind CRYSTALS-Kyber, CRYSTALS-Dilithium und XMSS.
Die betrachteten Algorithmen sind CRYSTALS-Kyber, CRYSTALS-Dilithium, XMSS und SPHINCS+.
Die Code-Basis für Kyber, Dilithium und XMSS ist Botan Version 3.0.0 [BOTAN_GIT_300]_.
Die Code-Basis für SPHINCS+ ist Botan Version 3.1.1 [BOTAN_GIT_311]_.
Für jeden Algorithmus wurde ein Hilfsprogramm geschrieben.
In den folgenden Kapiteln werden die verwendeten Analyseparameter erläutert und die gefundenen Leaks beschrieben.

Expand Down Expand Up @@ -33,7 +35,7 @@ Die Anzahl der Traces für die Analyse mit DATA entspricht daher in der Regel ei
Ergebnisse
^^^^^^^^^^

Die folgenden Kapitel enthalten die Ergebnisse der analysierten Implementierungen für CRYSTALS-Kyber, CRYSTALS-Dilithium und XMSS.
Die folgenden Kapitel enthalten die Ergebnisse der analysierten Implementierungen für CRYSTALS-Kyber, CRYSTALS-Dilithium, XMSS und SPHINCS+.
Wenn es mehrere Implementierungsvarianten eines Algorithmus gibt, werden diese am Anfang der Kapitel aufgeführt.
Wenn das Botan CLI verwendet wird, ist das Kommando für den Aufruf angegeben.
Details zur Kompilierung von Botan und zum Aufruf außerhalb der CLI sind ebenfalls angegeben.
Expand All @@ -46,3 +48,4 @@ Die Beschreibungen enthalten in der Regel auch den zugehörigen Quellcode und gg
02_01_kyber
02_02_dilithium
02_03_xmss
02_04_sphincsplus

0 comments on commit d49a541

Please sign in to comment.