diff options
| author | J08nY | 2021-01-20 20:24:11 +0100 |
|---|---|---|
| committer | J08nY | 2021-01-20 20:24:11 +0100 |
| commit | 9ec68bdb56882777e5b3670380bf1e1ad7d0a7a3 (patch) | |
| tree | bb695e485808e4d0517d84053019e2f7ddb03679 /pyecsca/sca/target | |
| parent | adc3cd52147f35e0a7cc9008ac96619dd89cda48 (diff) | |
| download | pyecsca-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.py | 4 | ||||
| -rw-r--r-- | pyecsca/sca/target/PCSC.py | 3 | ||||
| -rw-r--r-- | pyecsca/sca/target/base.py | 3 | ||||
| -rw-r--r-- | pyecsca/sca/target/binary.py | 6 | ||||
| -rw-r--r-- | pyecsca/sca/target/chipwhisperer.py | 13 | ||||
| -rw-r--r-- | pyecsca/sca/target/ectester.py | 19 | ||||
| -rw-r--r-- | pyecsca/sca/target/flash.py | 9 | ||||
| -rw-r--r-- | pyecsca/sca/target/serial.py | 19 | ||||
| -rw-r--r-- | pyecsca/sca/target/simpleserial.py | 14 |
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): |
