Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge develop into master #4

Merged
merged 41 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
aaebd42
Standardize Fuzzing
coderofstuff Nov 11, 2023
2509000
Increase strictness of P2SH check
coderofstuff Nov 11, 2023
6a00134
Update documentation for P2SH
coderofstuff Nov 11, 2023
e968ff8
Cover new validation in unit test
coderofstuff Nov 11, 2023
2be0d30
Merge pull request #56 from readd-fuzzing
coderofstuff Nov 11, 2023
a07dc4d
Add fuzzing github actions
coderofstuff Nov 13, 2023
0bb6969
User correct data size for tx_out_deser
coderofstuff Nov 13, 2023
6f7c03e
Updated fuzzing docs and remove pre-built headers
coderofstuff Nov 13, 2023
fac44fd
Check if we can read txout buf before doing so
coderofstuff Nov 13, 2023
a386b9e
Merge pull request #57 from coderofstuff/fuzzing-actions
coderofstuff Nov 13, 2023
37f1155
Fail signing if anything in sighash fails
coderofstuff Nov 13, 2023
2bf65d7
Update test_sighash
coderofstuff Nov 13, 2023
7984359
Remove gcc diagnostic ignored flags
coderofstuff Nov 13, 2023
73000a3
Fix buffer usage in sighash
coderofstuff Nov 13, 2023
1ae9619
Fix buffer check in transaction_serialize
coderofstuff Nov 13, 2023
9f32a65
Check buffers for address.h
coderofstuff Nov 13, 2023
3dd4fd8
Fix buffer checks for utils
coderofstuff Nov 13, 2023
71eb32a
Lint fixes
coderofstuff Nov 13, 2023
8720204
Merge pull request #58 from coderofstuff/fix-audit-comments
coderofstuff Nov 13, 2023
ce3c260
Even more buffer checks
coderofstuff Nov 14, 2023
016e61c
Merge pull request #59 from coderofstuff/buffer-checks
coderofstuff Nov 14, 2023
82d0ecd
Fix multiple definition of apdu_parser
cedelavergne-ledger Nov 17, 2023
8867557
Fix unit-tests
cedelavergne-ledger Nov 17, 2023
944e9b6
Update version
cedelavergne-ledger Nov 17, 2023
6da0e28
Merge pull request #1 from LedgerHQ/cev/B2CA-1408_conflict-name
cedelavergne-ledger Nov 20, 2023
648c585
[auto]: add PR template
sgliner-ledger Nov 29, 2023
9eb1dce
Add ledger_app.toml
coderofstuff Dec 5, 2023
34be8b0
Merge pull request #61 from LedgerHQ/develop
coderofstuff Dec 18, 2023
9cf2dfd
Bump version to 1.0.2
coderofstuff Dec 18, 2023
2e5b288
Merge pull request #62 from coderofstuff/bump-version-1-0-2
coderofstuff Dec 18, 2023
5016868
Account Support
coderofstuff Dec 5, 2023
20859eb
Fix C unit tests
coderofstuff Dec 5, 2023
e5c77ee
Documentation changes
coderofstuff Dec 5, 2023
3f3d07c
Increased test coverage for multi-account
coderofstuff Dec 5, 2023
1cd6a09
Golden image updates
coderofstuff Dec 5, 2023
ce1ea0b
More stax golden images
coderofstuff Dec 5, 2023
a12d186
Sign message doc update
coderofstuff Dec 27, 2023
ae2bff4
Merge pull request #60 from coderofstuff/account-support
coderofstuff Dec 27, 2023
1d19f4f
Merge pull request #2 from coderofstuff/main
agrojean-ledger Jan 3, 2024
e982868
[auto] Update screenshot
Jan 10, 2024
1919af5
Merge pull request #3 from LedgerHQ/auto-update-screenshots
sgliner-ledger Jan 11, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .clusterfuzzlite/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-lite:latest AS LITE_BUILDER

FROM gcr.io/oss-fuzz-base/base-builder:v1
COPY . $SRC/app-kaspa
COPY ./.clusterfuzzlite/build.sh $SRC/
COPY --from=LITE_BUILDER /opt/ledger-secure-sdk $SRC/app-kaspa/BOLOS_SDK
WORKDIR $SRC/app-kaspa
11 changes: 11 additions & 0 deletions .clusterfuzzlite/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash -eu

# build fuzzers

pushd fuzzing
cmake -DBOLOS_SDK=../BOLOS_SDK -Bbuild -H.
make -C build
mv ./build/fuzz_tx_parser $OUT
mv ./build/fuzz_txin_parser $OUT
mv ./build/fuzz_txout_parser $OUT
popd
1 change: 1 addition & 0 deletions .clusterfuzzlite/project.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
language: c
8 changes: 8 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Checklist
<!-- Put an `x` in each box when you have completed the items. -->
- [ ] App update process has been followed <!-- See comment below -->
- [ ] Target branch is `develop` <!-- unless you have a very good reason -->
- [ ] Application version has been bumped <!-- required if your changes are to be deployed -->

<!-- Make sure you followed the process described in https://developers.ledger.com/docs/embedded-app/maintenance/ before opening your Pull Request.
Don't hesitate to contact us directly on Discord if you have any questions ! https://developers.ledger.com/discord -->
40 changes: 40 additions & 0 deletions .github/workflows/cflite_cron.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: ClusterFuzzLite cron tasks
on:
workflow_dispatch:
push:
branches:
- main # Use your actual default branch here.
schedule:
- cron: '0 13 * * 6' # At 01:00 PM, only on Saturday
permissions: read-all
jobs:
Fuzzing:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- mode: batch
sanitizer: address
- mode: batch
sanitizer: memory
- mode: prune
sanitizer: address
- mode: coverage
sanitizer: coverage
steps:
- name: Build Fuzzers (${{ matrix.mode }} - ${{ matrix.sanitizer }})
id: build
uses: google/clusterfuzzlite/actions/build_fuzzers@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
language: c # Change this to the language you are fuzzing.
sanitizer: ${{ matrix.sanitizer }}
- name: Run Fuzzers (${{ matrix.mode }} - ${{ matrix.sanitizer }})
id: run
uses: google/clusterfuzzlite/actions/run_fuzzers@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
fuzz-seconds: 300 # 5 minutes
mode: ${{ matrix.mode }}
sanitizer: ${{ matrix.sanitizer }}
43 changes: 43 additions & 0 deletions .github/workflows/cflite_pr.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: ClusterFuzzLite PR fuzzing
on:
pull_request:
paths:
- '**'
permissions: read-all
jobs:
PR:
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ matrix.sanitizer }}-${{ github.ref }}
cancel-in-progress: true
strategy:
fail-fast: false
matrix:
sanitizer: [address, undefined, memory] # Override this with the sanitizers you want.
steps:
- name: Build Fuzzers (${{ matrix.sanitizer }})
id: build
uses: google/clusterfuzzlite/actions/build_fuzzers@v1
with:
language: c # Change this to the language you are fuzzing.
github-token: ${{ secrets.GITHUB_TOKEN }}
sanitizer: ${{ matrix.sanitizer }}
# Optional but recommended: used to only run fuzzers that are affected
# by the PR.
# storage-repo: https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/OWNER/STORAGE-REPO-NAME.git
# storage-repo-branch: main # Optional. Defaults to "main"
# storage-repo-branch-coverage: gh-pages # Optional. Defaults to "gh-pages".
- name: Run Fuzzers (${{ matrix.sanitizer }})
id: run
uses: google/clusterfuzzlite/actions/run_fuzzers@v1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
fuzz-seconds: 300 # 5 minutes
mode: 'code-change'
sanitizer: ${{ matrix.sanitizer }}
output-sarif: true
# Optional but recommended: used to download the corpus produced by
# batch fuzzing.
# storage-repo: https://${{ secrets.PERSONAL_ACCESS_TOKEN }}@github.com/OWNER/STORAGE-REPO-NAME.git
# storage-repo-branch: main # Optional. Defaults to "main"
# storage-repo-branch-coverage: gh-pages # Optional. Defaults to "gh-pages".
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ APPNAME = "Kaspa"
# Application version
APPVERSION_M = 1
APPVERSION_N = 0
APPVERSION_P = 0
APPVERSION_P = 2
APPVERSION = "$(APPVERSION_M).$(APPVERSION_N).$(APPVERSION_P)"

ifeq ($(TARGET_NAME),TARGET_NANOS)
Expand Down
20 changes: 11 additions & 9 deletions doc/COMMANDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
| `GET_APP_NAME` | 0x04 | Get ASCII encoded application name |
| `GET_PUBLIC_KEY` | 0x05 | Get public key given BIP32 path |
| `SIGN_TX` | 0x06 | Sign transaction given transaction info, utxos and outputs |
| `SIGN_MESSAGE` | 0x07 | Sign the personal message |

## GET_VERSION

Expand Down Expand Up @@ -55,11 +56,11 @@ Keys for kaspa normally use the derivation path `m/44'/111111'/<account>'/<type>

| CData Part | Description |
| --- | --- |
| `purpose` | Must be `44'` or `80000002c` |
| `coin_type` | Must be `111111'` or `8001b207` |
| `account` | Current wallets all use `80000000` (aka. `0'`) for default account but any value from `00000000` to `11111111` is accepted if passed |
| `type` | Current wallets use either `00000000` for Receive Address or `00000001` for Change Address, but any value from `00000000` to `11111111` is accepted if passed |
| `index` | Any value from `00000000` to `11111111` if passed |
| `purpose` | Must be `44'` or `0x80000002c` |
| `coin_type` | Must be `111111'` or `0x8001b207` |
| `account` | Current wallets all use `0x80000000` (aka. `0'`) for default account but any value from `0x80000000` to `0xFFFFFFFF` is accepted if passed |
| `type` | Current wallets use either `0x00000000` for Receive Address or `0x00000001` for Change Address, but any value from `0x00000000` to `0xFFFFFFFF` is accepted if passed |
| `index` | Any value from `0x00000000` to `0xFFFFFFFF` if passed |

If you want to generate addresses using a root public key,

Expand Down Expand Up @@ -88,7 +89,7 @@ Transactions signed with ECDSA are currently not supported.

| P1 Value | Usage | CData |
| --- | --- | --- |
| 0x00 | Sending transaction metadata | `version (2)` \|\| `output_len (1)` \|\| `input_len (1)` |
| 0x00 | Sending transaction metadata | `version (2)` \|\| `output_len (1)` \|\| `input_len (1)` \|\| `change_address_type (1)` \|\| `change_address_index (4)` \|\| `account (4)` |
| 0x01 | Sending a tx output | `value (8)` \|\| `script_public_key (34/35)` |
| 0x02 | Sending a tx input | `value (8)` \|\| `tx_id (32)` \|\| `address_type (1)` \|\| `address_index (4)` \|\| `outpoint_index (1)` |
| 0x03 | Requesting for next signature | - |
Expand All @@ -102,7 +103,7 @@ Transactions signed with ECDSA are currently not supported.
`P2` value is used only if `P1 in {0x00, 0x01, 0x02}`. If `P1 = 0x03`, `P2` is ignored.

#### Flow
1. Send the first APDU `P1 = 0x00` with the version, output length and input length
1. Send the first APDU `P1 = 0x00` with the version, output length and input length, change address type and index, and account (for UTXOs and change)
2. For each output (up to 2), send `P1 = 0x01` with the output CData
3. For each UTXO input send `P1 = 0x02` with the input CData. When sending the last UTXO input set `P2 = 0x00` to indicate that it is the last APDU. The signatures will later be sent back to you in the same order these inputs come in.
4. [Display] User will be able to view the transaction info and choose to `Approve` or `Reject`.
Expand Down Expand Up @@ -133,12 +134,13 @@ Transactions signed with ECDSA are currently not supported.

| CLA | INS | P1 | P2 | Lc | CData |
| --- | --- | --- | --- | --- | --- |
| 0xE0 | 0x07 | 0x00 | 0x00 | var | `address_type (1)` \|\| `address_index (4)` \|\|<br>`message_len (1 bytes)` \|\| `message (var bytes)` |
| 0xE0 | 0x07 | 0x00 | 0x00 | var | `address_type (1)` \|\| `address_index (4)` \|\|<br>`account (4)` \|\|<br>`message_len (1 bytes)` \|\| `message (var bytes)` |

| CData Part | Description |
| --- | --- |
| `address_type` | Either `00` for Receive Address or `01` for Change Address |
| `address_index` | Any value from `00000000` to `11111111` |
| `address_index` | Any value from `00000000` to `FFFFFFFF` |
| `account` | Any value from `80000000` to `FFFFFFFF` |
| `message_len` | How long the message is. Must be a value from `1` to `128`, inclusive |
| `message` | The message to sign |

Expand Down
6 changes: 5 additions & 1 deletion doc/TRANSACTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,16 @@ For ECDSA-signed addresses (supported by this app only as a send address), it be
| `n_outputs` | 1 | The number of outputs. Exactly 1 or 2.
| `change_address_type` | 1 | `0` if `RECEIVE` or `1` if `CHANGE`* |
| `change_address_index` | 4 | `0x00000000` to `0xFFFFFFFF`**|
| `account` | 4 | `0x80000000` to `0xFFFFFFFF`, normally should use `0x80000000` (the default account)***|

\* While this will be used for the change, the path may be either `RECEIVE` or `CHANGE`.
This is necessary in case the user wants to send the change back to the same address.
In this case, the `change_address_type` has to be set to `RECEIVE`.

\*\* `change_address_type` and `change_address_index` are ignored if `n_outputs == 1`. If `n_outputs == 2` then the path defined here must resolve to the same `script_public_key` in `outputs[1]`.

\*\*\* `account` is the BIP44 account. A transaction can only come from a single account. Current Kaspa ecosystem only uses `0'` (or `0x80000000`) but support this is in anticipation of wider account-based support.

### Transaction Input

Total bytes: 46
Expand All @@ -54,7 +58,7 @@ Total bytes: 43 (max)
| Field | Size (bytes) | Description |
| --- | --- | --- |
| `value` | 8 | The amount of KAS in sompi that will go send to the address |
| `script_public_key` | 35 | Schnorr: `20` + public_key (32 bytes) + `ac` <br/> ECDSA: `20` + public_key (33 bytes) + `ab` <br/> P2SH: `aa20` + public_key (32 bytes) + `87` |
| `script_public_key` | 35 | Schnorr: `0x20` + public_key (32 bytes) + `0xac` <br/> ECDSA: `0x20` + public_key (33 bytes) + `0xab` <br/> P2SH: `0xaa, 0x20` + script_hash (32 bytes) + `0x87` |

### Transaction Requirements
- Fee = (total inputs amount) - (total outputs amount)
Expand Down
60 changes: 33 additions & 27 deletions fuzzing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,53 @@ endif()
project(FuzzTxParser
VERSION 1.0
DESCRIPTION "Fuzzing of transaction parser"
LANGUAGES CXX)
LANGUAGES C)

# guard against bad build-type strings
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug")
endif()

if (NOT CMAKE_C_COMPILER_ID MATCHES "Clang")
message(FATAL_ERROR "Fuzzer needs to be built with Clang")
endif()

if (NOT DEFINED BOLOS_SDK)
message(FATAL_ERROR "BOLOS_SDK environment variable not found.")
endif()

# guard against in-source builds
if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt. ")
endif()

# compatible with ClusterFuzzLite
if (NOT DEFINED ENV{LIB_FUZZING_ENGINE})
set(COMPILATION_FLAGS_ "-g -Wall -fsanitize=fuzzer,address,undefined")
else()
set(COMPILATION_FLAGS_ "$ENV{LIB_FUZZING_ENGINE} $ENV{CXXFLAGS}")
endif()

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

add_compile_definitions(MAX_INPUT_COUNT=15 MAX_MESSAGE_LEN=200 USB_SEGMENT_SIZE=64)

string(REPLACE " " ";" COMPILATION_FLAGS ${COMPILATION_FLAGS_})

include(extra/TxParser.cmake)

add_executable(fuzz_tx_parser fuzz_tx_parser.cc)
add_executable(fuzz_txout_parser fuzz_txout_parser.cc)
add_executable(fuzz_txin_parser fuzz_txin_parser.cc)

target_compile_options(fuzz_tx_parser
PRIVATE $<$<C_COMPILER_ID:Clang>:-g -O2 -fsanitize=fuzzer,address,undefined>
)
target_compile_options(fuzz_txout_parser
PRIVATE $<$<C_COMPILER_ID:Clang>:-g -O2 -fsanitize=fuzzer,address,undefined>
)
target_compile_options(fuzz_txin_parser
PRIVATE $<$<C_COMPILER_ID:Clang>:-g -O2 -fsanitize=fuzzer,address,undefined>
)

target_link_libraries(fuzz_tx_parser
PRIVATE $<$<C_COMPILER_ID:Clang>:-fsanitize=fuzzer,address,undefined>
PUBLIC txparser
)
target_link_libraries(fuzz_txout_parser
PRIVATE $<$<C_COMPILER_ID:Clang>:-fsanitize=fuzzer,address,undefined>
PUBLIC txparser
)
target_link_libraries(fuzz_txin_parser
PRIVATE $<$<C_COMPILER_ID:Clang>:-fsanitize=fuzzer,address,undefined>
PUBLIC txparser
)
add_executable(fuzz_tx_parser fuzz_tx_parser.c)
add_executable(fuzz_txout_parser fuzz_txout_parser.c)
add_executable(fuzz_txin_parser fuzz_txin_parser.c)

target_compile_options(fuzz_tx_parser PUBLIC ${COMPILATION_FLAGS})
target_link_options(fuzz_tx_parser PUBLIC ${COMPILATION_FLAGS})
target_link_libraries(fuzz_tx_parser PUBLIC txparser)

target_compile_options(fuzz_txout_parser PUBLIC ${COMPILATION_FLAGS})
target_link_options(fuzz_txout_parser PUBLIC ${COMPILATION_FLAGS})
target_link_libraries(fuzz_txout_parser PUBLIC txparser)

target_compile_options(fuzz_txin_parser PUBLIC ${COMPILATION_FLAGS})
target_link_options(fuzz_txin_parser PUBLIC ${COMPILATION_FLAGS})
target_link_libraries(fuzz_txin_parser PUBLIC txparser)
43 changes: 31 additions & 12 deletions fuzzing/README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
# Fuzzing on transaction parser

## Setup

Change `~/ledger/app-kaspa` to wherever you actual `app-kaspa` folder is.

```
docker run --rm -it -v ~/kaspa/ledger/app-kaspa:/app ghcr.io/ledgerhq/ledger-app-builder/ledger-app-builder-legacy:latest bash
```

## Compilation


In `fuzzing` folder

```
cmake -DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++ -Bbuild -H.
cmake -DBOLOS_SDK=$NANOSP_SDK -DCMAKE_C_COMPILER=/usr/bin/clang -Bbuild -H.
```

cmake -DCMAKE_C_COMPILER=/tmp/llvm-project/build/bin/clang \
-DCMAKE_CXX_COMPILER=/tmp/llvm-project/build/bin/clang++ \
-DGCC_INSTALL_PREFIX=/usr/lib/gcc/x86_64-alpine-linux-musl/10.3.1/ \
-Bbuild -H.

then

```
Expand All @@ -23,22 +27,37 @@ make -C build

```
./build/fuzz_tx_parser
./build/fuzz_txin_parser
./build/fuzz_txout_parser
```

## Extra installs
## LLVM Compile

Use this if you want to build the LLVM from scratch and use it

A pre-compiled version of the ones this fuzzing needs is in `llvm-headers`.

Update your docker run to:
```
apk add build-base libc-dev linux-headers libexecinfo-dev llvm12 compiler-rt
docker run -it -v ~/ledger/app-kaspa:/app -v ~/llvm-project:/tmp/llvm-project ghcr.io/ledgerhq/ledger-app-builder/ledger-app-dev-tools:latest bash
apk add build-base libc-dev linux-headers libexecinfo-dev compiler-rt
apk del llvm15
```

## LLVM Compile
Clone the LLVM project from: https://github.com/llvm/llvm-project
```
git clone https://github.com/llvm/llvm-project ~/llvm-project
```

```
cd /tmp/llvm-project
mkdir build
cd build

cmake ../llvm/ -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/tmp/llvm-project/build/ -DBUILD_SHARED_LIBS=on -DLLVM_ENABLE_PROJECTS="clang;compiler-rt" -DLLVM_ENABLE_BACKTRACES=OFF -DCOMPILER_RT_BUILD_GWP_ASAN=OFF
cmake ../llvm/ -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/tmp/llvm-project/build/ -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=on -DLLVM_ENABLE_PROJECTS="clang;compiler-rt" -DLLVM_ENABLE_BACKTRACES=OFF -DCOMPILER_RT_BUILD_GWP_ASAN=OFF

make -j8

cp /tmp/llvm-project/build/lib/clang/15.0.0/lib/linux/libclang* /usr/lib/clang/12.0.1/lib/linux/
```
cp /tmp/llvm-project/build/lib/clang/16/lib/x86_64-unknown-linux-gnu/libclang_rt.asan.a /usr/lib/clang/12.0.1/lib/linux/libclang_rt.asan-x86_64.a
cp /tmp/llvm-project/build/lib/clang/16/lib/x86_64-unknown-linux-gnu/libclang_rt.fuzzer.a /usr/lib/clang/12.0.1/lib/linux/libclang_rt.fuzzer-x86_64.a
```
Loading
Loading