diff options
| -rw-r--r-- | Makefile | 8 | ||||
| -rw-r--r-- | docs/_static/kerckhoff_rwc26_slides.pdf | bin | 0 -> 3946557 bytes | |||
| -rw-r--r-- | docs/papers.rst | 53 | ||||
| -rw-r--r-- | pyecsca/sca/re/epa.py | 2 | ||||
| -rw-r--r-- | pyecsca/sca/re/rpa.py | 7 | ||||
| -rw-r--r-- | pyproject.toml | 2 | ||||
| -rw-r--r-- | test/sca/test_epa.py | 6 |
7 files changed, 66 insertions, 12 deletions
@@ -3,16 +3,16 @@ PERF_SCRIPTS = test.ec.perf_mod test.ec.perf_formula test.ec.perf_mult test.sca. all: help test: - pytest -m "not slow" --cov=pyecsca --doctest-ignore-import-errors + pytest -m "not slow" --cov=pyecsca test-plots: - env PYECSCA_TEST_PLOTS=1 pytest -m "not slow" --doctest-ignore-import-errors + env PYECSCA_TEST_PLOTS=1 pytest -m "not slow" test-all: - pytest --cov=pyecsca --doctest-ignore-import-errors + pytest --cov=pyecsca test-notebooks: - pytest -m "not slow" --doctest-ignore-import-errors --nbmake --cov=pyecsca --cov-append notebook/simulation.ipynb notebook/visualization.ipynb + pytest -m "not slow" --nbmake --cov=pyecsca --cov-append notebook/simulation.ipynb notebook/visualization.ipynb typecheck: mypy --namespace-packages -p pyecsca --ignore-missing-imports --show-error-codes --check-untyped-defs diff --git a/docs/_static/kerckhoff_rwc26_slides.pdf b/docs/_static/kerckhoff_rwc26_slides.pdf Binary files differnew file mode 100644 index 0000000..2ebf316 --- /dev/null +++ b/docs/_static/kerckhoff_rwc26_slides.pdf diff --git a/docs/papers.rst b/docs/papers.rst index cb7be9a..32e11e6 100644 --- a/docs/papers.rst +++ b/docs/papers.rst @@ -1,6 +1,8 @@ -============================ -:fas:`file-alt;fa-fw` Papers -============================ +====================================== +:fas:`file-alt;fa-fw` Papers and Talks +====================================== + + pyecsca: Reverse engineering black-box elliptic curve cryptography via side-channel analysis ============================================================================================ @@ -162,3 +164,48 @@ also the exact value of the random mask used. Using the techniques, we successfu reverse-engineered the countermeasures on 13 cryptographic smartcards from 5 major manufacturers – all but one we tested on. Finally, we discuss what mitigations can be applied to prevent such reverse engineering, and whether it is possible at all. + + + +Kerckhoff's Principle in Practice: Addressing Security by Obscurity in Secure Hardware +====================================================================================== + +Vojtech Suchanek, Jan Jancar, Jan Kvapil, Petr Svenda, Lukasz Chmielewski + +`RWC 2026, Taipei, Taiwan <https://rwc.iacr.org/2026/>`_ + +.. grid:: + :margin: 2 0 0 2 + :padding: 2 0 0 2 + + + .. grid-item:: + :columns: auto + + .. button-link:: _static/kerckhoff_rwc26_slides.pdf + :color: secondary + + :fas:`file-alt;fa-fw` Slides + +Abstract +-------- + +The Kerckhoff's principle, a cornerstone of cryptographic theory, states that a cryptosystem's +security should not rely on secrecy, but rather on the secrecy of the key. However, in the +secure hardware space, secrecy is widespread, with vendors revealing minimal information about +their implementations. This secrecy can lead to the delayed discovery of vulnerabilities, +leading to more impactful attacks. What can we do to address this gap between cryptographic +theory (Kerckhoff's) and the practice in the secure hardware space (security by obscurity)? + +In this talk, we make the case against security by obscurity by demonstrating automated +reverse-engineering of black-box elliptic curve cryptography (ECC) implementations on real-world +devices, thereby showing that obscurity provides only a limited defense. We showcase two +approaches to recovering key details of ECC implementations on JavaCards: using side-channels +and using out-of-spec parameters. + +Using our techniques, we were able to reverse-engineer scalar randomization countermeasures +in several real-world implementations of JavaCards from major vendors. We will demonstrate +how simple algebra and lying can be used to bypass the obscurity around these devices. Finally, +we will discuss how security certifications reward obscurity and how we believe that there is +a usable compromise that provides transparency and keeps the vendors' intellectual property +secret. We take first steps towards this in the sec-certs.org project. diff --git a/pyecsca/sca/re/epa.py b/pyecsca/sca/re/epa.py index 4ef1b74..37c0b98 100644 --- a/pyecsca/sca/re/epa.py +++ b/pyecsca/sca/re/epa.py @@ -57,7 +57,7 @@ def graph_to_check_inputs( affine_points = {out} def _necessary(ctx, for_what): - res = {out} + res = {*for_what} queue = {*for_what} while queue: point = queue.pop() diff --git a/pyecsca/sca/re/rpa.py b/pyecsca/sca/re/rpa.py index 2fd5973..12b8371 100644 --- a/pyecsca/sca/re/rpa.py +++ b/pyecsca/sca/re/rpa.py @@ -59,7 +59,12 @@ class MultipleContext(Context): formulas: MutableMapping[Point, str] """The mapping of points to the formula types they are a result of.""" precomp: MutableMapping[int, Point] - """The mapping of precomputed multiples to the points they represent.""" + """ + The mapping of precomputed points the scalar multiplier stored. + + .. note:: + The keys are the indices used by the scalar multiplier, not (necessarily) the multiples. + """ result: Optional[Point] """The resulting point of the computation.""" inside: List[Action] diff --git a/pyproject.toml b/pyproject.toml index da0a9f1..625af65 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -94,7 +94,7 @@ markers = [ "slow: marks tests as slow (deselect with '-m \"not slow\"')", ] - addopts = ["--doctest-modules"] + addopts = ["--doctest-modules", "--doctest-ignore-import-errors"] filterwarnings = [ "ignore:(?s).*pkg_resources is deprecated as an API:UserWarning:chipwhisperer.capture.trace.TraceWhisperer", # ChipWhisperer "ignore:Deprecated call to `pkg_resources.declare_namespace", # sphinxcontrib diff --git a/test/sca/test_epa.py b/test/sca/test_epa.py index 65caa92..89745cc 100644 --- a/test/sca/test_epa.py +++ b/test/sca/test_epa.py @@ -1,4 +1,5 @@ import random +import sys from functools import partial import networkx as nx @@ -145,7 +146,7 @@ def test_errors_out_precomp(secp128r1): use_init=True, use_multiply=False, ) - assert set(affine_multiples) == set(precomp_ctx.precomp.keys()) + assert set(affine_multiples) == set(precomp_ctx.points[pt] for pt in precomp_ctx.precomp.values()) assert set(add_multiples) == {(1, 2)} # Here we check all, during both precomp and final multiply. @@ -163,7 +164,7 @@ def test_errors_out_precomp(secp128r1): use_multiply=True, ) # There should be all of the results of the precomp, plus the final multiply result. - assert set(affine_multiples) == set(precomp_ctx.precomp.keys()) | { + assert set(affine_multiples) == set(precomp_ctx.points[pt] for pt in precomp_ctx.precomp.values()) | { full_ctx.points[out] } # The add multiples should be the same as before, plus any inputs to add that happened @@ -343,6 +344,7 @@ def toy_params(): return DomainParameters(curve, g, 0xCB5E1D94601A3AC5, 1) +@pytest.mark.skipif(sys.version_info < (3, 11), reason="Requires Python 3.11 or higher (networkx >= 3.5)") def test_plot(toy_params, mult, plot_path): mult_class, mult_factory = mult precomp_ctx, full_ctx, out = multiple_graph( |
