aboutsummaryrefslogtreecommitdiffhomepage
path: root/pyecsca/sca/target
diff options
context:
space:
mode:
authorJ08nY2021-01-20 20:24:11 +0100
committerJ08nY2021-01-20 20:24:11 +0100
commit9ec68bdb56882777e5b3670380bf1e1ad7d0a7a3 (patch)
treebb695e485808e4d0517d84053019e2f7ddb03679 /pyecsca/sca/target
parentadc3cd52147f35e0a7cc9008ac96619dd89cda48 (diff)
downloadpyecsca-9ec68bdb56882777e5b3670380bf1e1ad7d0a7a3.tar.gz
pyecsca-9ec68bdb56882777e5b3670380bf1e1ad7d0a7a3.tar.zst
pyecsca-9ec68bdb56882777e5b3670380bf1e1ad7d0a7a3.zip
The big documentation patch.
Diffstat (limited to 'pyecsca/sca/target')
-rw-r--r--pyecsca/sca/target/ISO7816.py4
-rw-r--r--pyecsca/sca/target/PCSC.py3
-rw-r--r--pyecsca/sca/target/base.py3
-rw-r--r--pyecsca/sca/target/binary.py6
-rw-r--r--pyecsca/sca/target/chipwhisperer.py13
-rw-r--r--pyecsca/sca/target/ectester.py19
-rw-r--r--pyecsca/sca/target/flash.py9
-rw-r--r--pyecsca/sca/target/serial.py19
-rw-r--r--pyecsca/sca/target/simpleserial.py14
9 files changed, 82 insertions, 8 deletions
diff --git a/pyecsca/sca/target/ISO7816.py b/pyecsca/sca/target/ISO7816.py
index 2bf37f9..233685e 100644
--- a/pyecsca/sca/target/ISO7816.py
+++ b/pyecsca/sca/target/ISO7816.py
@@ -1,3 +1,6 @@
+"""
+This module provides classes for working with ISO7816-4 APDUs and an abstract base class for an ISO7816-4 based target.
+"""
from abc import abstractmethod, ABC
from dataclasses import dataclass
from typing import Optional
@@ -86,6 +89,7 @@ class ISO7816Target(Target, ABC):
@public
class ISO7816:
+ """A bunch of ISO7816-4 constants (status words)."""
SW_FILE_FULL = 0x6A84
SW_UNKNOWN = 0x6F00
SW_CLA_NOT_SUPPORTED = 0x6E00
diff --git a/pyecsca/sca/target/PCSC.py b/pyecsca/sca/target/PCSC.py
index 6ffc8d4..a377751 100644
--- a/pyecsca/sca/target/PCSC.py
+++ b/pyecsca/sca/target/PCSC.py
@@ -1,3 +1,6 @@
+"""
+This module provides a smartcard target communicating via PC/SC (Personal Computer/Smart Card).
+"""
from typing import Union
from public import public
diff --git a/pyecsca/sca/target/base.py b/pyecsca/sca/target/base.py
index cc0436c..6747c66 100644
--- a/pyecsca/sca/target/base.py
+++ b/pyecsca/sca/target/base.py
@@ -1,3 +1,6 @@
+"""
+This module provides an abstract base class for targets.
+"""
from abc import ABC, abstractmethod
from public import public
diff --git a/pyecsca/sca/target/binary.py b/pyecsca/sca/target/binary.py
index 0455c75..3e2877b 100644
--- a/pyecsca/sca/target/binary.py
+++ b/pyecsca/sca/target/binary.py
@@ -1,3 +1,6 @@
+"""
+This module provides a binary target class which represents a target that is a runnable binary on the host.
+"""
import subprocess
from subprocess import Popen
from typing import Optional, Union, List
@@ -9,6 +12,7 @@ from .serial import SerialTarget
@public
class BinaryTarget(SerialTarget):
+ """A binary target that is runnable on the host and communicates using the stdin/stdout streams."""
binary: List[str]
process: Optional[Popen] = None
debug_output: bool
@@ -26,7 +30,7 @@ class BinaryTarget(SerialTarget):
self.process = Popen(self.binary, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
text=True, bufsize=1)
- def write(self, data: bytes):
+ def write(self, data: bytes) -> None:
if self.process is None:
raise ValueError
if self.debug_output:
diff --git a/pyecsca/sca/target/chipwhisperer.py b/pyecsca/sca/target/chipwhisperer.py
index 3dd5686..ac3fa42 100644
--- a/pyecsca/sca/target/chipwhisperer.py
+++ b/pyecsca/sca/target/chipwhisperer.py
@@ -1,4 +1,9 @@
-from typing import Optional
+"""
+This module provides a `ChipWhisperer <https://github.com/newaetech/chipwhisperer/>`_ target class.
+ChipWhisperer is a side-channel analysis tool and framework. A ChipWhisperer target is one
+that uses the ChipWhisperer's SimpleSerial communication protocol and is communicated with
+using ChipWhisperer-Lite or Pro.
+"""
from time import sleep
import chipwhisperer as cw
@@ -12,6 +17,10 @@ from .simpleserial import SimpleSerialTarget
@public
class ChipWhispererTarget(Flashable, SimpleSerialTarget): # pragma: no cover
+ """
+ A ChipWhisperer-based target, using the SimpleSerial protocol and communicating
+ using ChipWhisperer-Lite/Pro.
+ """
def __init__(self, target: SimpleSerial, scope: ScopeTemplate, programmer, **kwargs):
super().__init__()
@@ -32,7 +41,7 @@ class ChipWhispererTarget(Flashable, SimpleSerialTarget): # pragma: no cover
return False
return True
- def write(self, data: bytes):
+ def write(self, data: bytes) -> None:
self.target.flush()
self.target.write(data.decode())
diff --git a/pyecsca/sca/target/ectester.py b/pyecsca/sca/target/ectester.py
index 8391e32..6ab10be 100644
--- a/pyecsca/sca/target/ectester.py
+++ b/pyecsca/sca/target/ectester.py
@@ -1,3 +1,6 @@
+"""
+This module provides an `ECTester <https://github.com/crocs-muni/ECTester/>`_ target class.
+"""
from abc import ABC
from binascii import hexlify
from enum import IntEnum, IntFlag
@@ -45,6 +48,7 @@ class ShiftableFlag(IntFlag): # pragma: no cover
@public
class KeypairEnum(ShiftableFlag): # pragma: no cover
+ """ECTester's KeyPair type."""
KEYPAIR_LOCAL = 0x01
KEYPAIR_REMOTE = 0x02
KEYPAIR_BOTH = KEYPAIR_LOCAL | KEYPAIR_REMOTE
@@ -52,6 +56,7 @@ class KeypairEnum(ShiftableFlag): # pragma: no cover
@public
class InstructionEnum(IntEnum): # pragma: no cover
+ """ECTester's instruction (INS)."""
INS_ALLOCATE = 0x5a
INS_CLEAR = 0x5b
INS_SET = 0x5c
@@ -74,12 +79,14 @@ class InstructionEnum(IntEnum): # pragma: no cover
@public
class KeyBuildEnum(IntEnum): # pragma: no cover
+ """ECTester's key builder type."""
BUILD_KEYPAIR = 0x01
BUILD_KEYBUILDER = 0x02
@public
class ExportEnum(IntEnum): # pragma: no cover
+ """ECTester's export boolean."""
EXPORT_TRUE = 0xff
EXPORT_FALSE = 0x00
@@ -90,12 +97,14 @@ class ExportEnum(IntEnum): # pragma: no cover
@public
class RunModeEnum(IntEnum): # pragma: no cover
+ """ECTester's run mode."""
MODE_NORMAL = 0xaa
MODE_DRY_RUN = 0xbb
@public
class KeyEnum(ShiftableFlag): # pragma: no cover
+ """ECTester's key enum."""
PUBLIC = 0x01
PRIVATE = 0x02
BOTH = PRIVATE | PUBLIC
@@ -103,18 +112,21 @@ class KeyEnum(ShiftableFlag): # pragma: no cover
@public
class AppletBaseEnum(IntEnum): # pragma: no cover
+ """ECTester's JavaCard applet base version."""
BASE_221 = 0x0221
BASE_222 = 0x0222
@public
class KeyClassEnum(IntEnum): # pragma: no cover
+ """JavaCard EC-based key class."""
ALG_EC_F2M = 4
ALG_EC_FP = 5
@public
class KeyAgreementEnum(IntEnum): # pragma: no cover
+ """JavaCard `KeyAgreement` type values."""
ALG_EC_SVDP_DH = 1
ALG_EC_SVDP_DH_KDF = 1
ALG_EC_SVDP_DHC = 2
@@ -127,6 +139,7 @@ class KeyAgreementEnum(IntEnum): # pragma: no cover
@public
class SignatureEnum(IntEnum): # pragma: no cover
+ """JavaCard `Signature` type values."""
ALG_ECDSA_SHA = 17
ALG_ECDSA_SHA_224 = 37
ALG_ECDSA_SHA_256 = 33
@@ -136,6 +149,7 @@ class SignatureEnum(IntEnum): # pragma: no cover
@public
class TransformationEnum(ShiftableFlag): # pragma: no cover
+ """ECTester's point/value transformation types."""
NONE = 0x00
FIXED = 0x01
FULLRANDOM = 0x02
@@ -152,6 +166,7 @@ class TransformationEnum(ShiftableFlag): # pragma: no cover
@public
class FormatEnum(IntEnum): # pragma: no cover
+ """ECTester's point format types."""
UNCOMPRESSED = 0
COMPRESSED = 1
HYBRID = 2
@@ -159,6 +174,7 @@ class FormatEnum(IntEnum): # pragma: no cover
@public
class CurveEnum(IntEnum): # pragma: no cover
+ """ECTester's curve constants."""
default = 0x00
external = 0xff
secp112r1 = 0x01
@@ -178,6 +194,7 @@ class CurveEnum(IntEnum): # pragma: no cover
@public
class ParameterEnum(ShiftableFlag): # pragma: no cover
+ """ECTester's parameter ids."""
NONE = 0x00
FP = 0x01
F2M = 0x02
@@ -196,10 +213,12 @@ class ParameterEnum(ShiftableFlag): # pragma: no cover
@public
class ChunkingException(Exception): # pragma: no cover
+ """An exception that is raised if an error happened during the chunking process of a large APDU."""
pass
class Response(ABC): # pragma: no cover
+ """An abstract base class of a response APDU."""
resp: ResponseAPDU
sws: List[int]
params: List[bytes]
diff --git a/pyecsca/sca/target/flash.py b/pyecsca/sca/target/flash.py
index bfdb79f..d1fc16a 100644
--- a/pyecsca/sca/target/flash.py
+++ b/pyecsca/sca/target/flash.py
@@ -1,3 +1,6 @@
+"""
+This module provides a mix-in class of a flashable target (e.g. one where the code gets flashed to it before running).
+"""
from public import public
from abc import ABC, abstractmethod
@@ -8,4 +11,10 @@ class Flashable(ABC):
@abstractmethod
def flash(self, fw_path: str) -> bool:
+ """
+ Flash the firmware at `fw_path` to the target.
+
+ :param fw_path: The path to the firmware blob.
+ :return: Whether the flashing was successful.
+ """
...
diff --git a/pyecsca/sca/target/serial.py b/pyecsca/sca/target/serial.py
index ccde326..d0e276c 100644
--- a/pyecsca/sca/target/serial.py
+++ b/pyecsca/sca/target/serial.py
@@ -1,5 +1,7 @@
+"""
+This module provides an abstract serial target, that communicates by writing and reading a stream of bytes.
+"""
from abc import abstractmethod
-from typing import Optional
from public import public
@@ -8,11 +10,24 @@ from .base import Target
@public
class SerialTarget(Target):
+ """A serial target."""
@abstractmethod
- def write(self, data: bytes):
+ def write(self, data: bytes) -> None:
+ """
+ Write the `data` bytes to the target's serial input.
+
+ :param data: The data to write.
+ """
...
@abstractmethod
def read(self, num: int = 0, timeout: int = 0) -> bytes:
+ """
+ Read upto `num` bytes or until `timeout` milliseconds from the target's serial output.
+
+ :param num: The number of bytes to read, `0` for all available.
+ :param timeout: The timeout in milliseconds.
+ :return: The bytes read.
+ """
...
diff --git a/pyecsca/sca/target/simpleserial.py b/pyecsca/sca/target/simpleserial.py
index 1ad0b68..03e5768 100644
--- a/pyecsca/sca/target/simpleserial.py
+++ b/pyecsca/sca/target/simpleserial.py
@@ -1,3 +1,7 @@
+"""
+This module provides an abstract target class communicating using the
+`ChipWhisperer's <https://github.com/newaetech/chipwhisperer/>`_ SimpleSerial protocol.
+"""
from time import time_ns, sleep
from typing import Mapping, Union
@@ -8,6 +12,7 @@ from .serial import SerialTarget
@public
class SimpleSerialMessage(object):
+ """A SimpleSerial message consisting of a starting character and a hexadecimal string."""
char: str
data: str
@@ -33,6 +38,7 @@ class SimpleSerialMessage(object):
@public
class SimpleSerialTarget(SerialTarget):
+ """A SimpleSerial target, sends and receives SimpleSerial messages over a serial link."""
def recv_msgs(self, timeout: int) -> Mapping[str, SimpleSerialMessage]:
start = time_ns() // 1000000
@@ -56,10 +62,12 @@ class SimpleSerialTarget(SerialTarget):
def send_cmd(self, cmd: SimpleSerialMessage, timeout: int) -> Mapping[str, SimpleSerialMessage]:
"""
+ Send a :py:class:`SimpleSerialMessage` and receive the response messages that the command produces,
+ within a `timeout`.
- :param cmd:
- :param timeout:
- :return:
+ :param cmd: The command message to send.
+ :param timeout: The timeout value to wait for the responses.
+ :return: A mapping of the starting character of the message to the message.
"""
data = bytes(cmd)
for i in range(0, len(data), 64):