From 522b7d5841118bfb6a3d76ce8afe212342093a1c Mon Sep 17 00:00:00 2001 From: MageDelfador <9780339+MageDelfador@users.noreply.github.com> Date: Wed, 15 Oct 2025 23:43:38 +0800 Subject: [PATCH 1/8] Update sdkconfig.defaults --- sdkconfig.defaults | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 0420fe8..30e56b4 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -10,6 +10,8 @@ CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="pico-keys-sdk/config/esp32/partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="pico-keys-sdk/config/esp32/partitions.csv" CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y +CONFIG_ESPTOOLPY_FLASHMODE_QIO=y +CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_MODE_PERF=y COMPILER_OPTIMIZATION="Performance" From 8b086188758ad3f60e912acd969b80d6801cfab3 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 26 Oct 2025 20:45:37 +0100 Subject: [PATCH 2/8] Update license models and add ENTERPRISE.md Signed-off-by: Pol Henarejos --- ENTERPRISE.md | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 27 ++++++++++-- 2 files changed, 139 insertions(+), 4 deletions(-) create mode 100644 ENTERPRISE.md diff --git a/ENTERPRISE.md b/ENTERPRISE.md new file mode 100644 index 0000000..f550fed --- /dev/null +++ b/ENTERPRISE.md @@ -0,0 +1,116 @@ +# Enterprise / Commercial Edition + +This project is offered under two editions: + +## 1. Community Edition (FOSS) + +The Community Edition is released under the GNU Affero General Public License v3 (AGPLv3). + +Intended for: +- individual users and researchers +- evaluation / prototyping +- internal lab / security testing + +You are allowed to: +- read and study the source code +- modify it +- run it internally + +Obligations under AGPLv3: +- If you distribute modified firmware/binaries/libraries to third parties, you must provide the corresponding source code of your modifications. +- If you run a modified version of this project as a network-accessible service (internal or external), you must offer the source code of those modifications to the users of that service. +- No warranty, no support, no SLA. +- Enterprise features (bulk provisioning, multi-user policy enforcement, device inventory / revocation, corporate PIN rules, custom attestation/identity, etc.) are NOT included. + +The Community Edition will continue to exist. + +## 2. Enterprise / Commercial Edition + +The Enterprise / Commercial Edition is a proprietary license for organizations that need to: + +- deploy this in production at scale (multiple devices / multiple users / multiple teams) +- integrate it into their own physical product or appliance +- run it as an internal service (VM / container / private cloud "HSM / auth backend") for multiple internal teams or tenants +- enforce internal security policy (admin vs user roles, mandatory PIN rules, secure offboarding / revocation) +- avoid any AGPLv3 disclosure obligations for their own modifications and integration code + +### What the Enterprise Edition provides + +**Base license package (always included):** +- **Commercial license (proprietary).** + You may run and integrate the software/firmware in production — including virtualized / internal-cloud style deployments — without being required to disclose derivative source code under AGPLv3. +- **Official signed builds.** + You receive signed builds from the original developer so you can prove integrity and provenance. +- **Onboarding call (up to 1 hour).** + A live remote session to get you from "we have it" to "it’s actually running in our environment" with minimal guesswork. + +**Optional enterprise components (available on demand, scoped and priced per customer):** +- **Production / multi-user readiness.** + Permission to operate the system with multiple users, multiple devices and multiple teams in real environments. +- **Bulk / fleet provisioning.** + Automated enrollment for many tokens/devices/users at once (CSV / directory import), scripted onboarding of new users, initial PIN assignment / reset workflows, and role-based access (admin vs user). +- **Policy & lifecycle tooling.** + Corporate PIN policy enforcement, per-user / per-team access control, device inventory / traceability, and secure revocation / retirement when someone leaves. +- **Custom attestation / per-organization identity.** + Per-company certificate chains and attestation keys so devices can prove "this token/HSM is officially ours," including anti-cloning / unique device identity for OEM and fleet use. +- **Virtualization / internal cloud deployment support.** + Guidance and components to run this as an internal service (VM, container, private-cloud HSM/auth backend) serving multiple internal teams or tenants under your brand. +- **Post-quantum (PQC) key material handling.** + Integration/roadmap support for PQC algorithms (auth / signing) and secure PQC key storage inside the device or service. +- **Hierarchical deterministic key derivation (HD).** + Wallet-style hierarchical key trees (BIP32-like concepts adapted to this platform) for issuing per-user / per-tenant / per-purpose subkeys without exporting the root secret — e.g. embedded wallet logic, tenant isolation, firmware signing trees, large fleets. +- **Cryptographically signed audit trail / tamper-evident event logging.** + High-assurance logging of sensitive actions (key use, provisioning, PIN resets, revocations) with integrity protection for forensic / compliance needs. +- **Dual-control / two-person approval ("four-eyes").** + Require multi-party authorization for high-risk actions such as firmware signing, key export, or critical configuration changes — standard in high-assurance / regulated environments. +- **Secure key escrow / disaster recovery design.** + Split-secret or escrowed backup strategies so you don’t lose critical signing keys if a single admin disappears or hardware is lost. +- **Release-signing / supply-chain hardening pipeline.** + Reference tooling and process so every production firmware/binary is signed with hardware-backed keys, proving origin and preventing tampering in transit or at manufacturing. +- **Policy-locked hardened mode ("FIPS-style profile").** + Restricted algorithms, debug disabled, no raw key export, tamper-evident configuration for regulated / high-assurance deployments. +- **Priority support / security response SLA.** + A direct line and guaranteed response window for production-impacting security issues. +- **White-label demo / pre-sales bundle.** + Branded demo firmware + safe onboarding script so you can show "your product" to your own customers without exposing real production secrets. + +These components are NOT automatically bundled. They are available case-by-case depending on your use case and are priced separately. + +### Licensing models + +- **Internal Use License** + Internal production use within one legal entity (your company), including internal private cloud / virtualized deployments for multiple internal teams. + Optional enterprise components can be added as needed. + +- **OEM / Redistribution / Service License** + Integration into a product/appliance you ship to customers, OR operating this as a managed service / hosted feature for external clients or third parties. + Optional enterprise components (attestation branding, PQC support, HD key derivation, multi-tenant service hardening, audit trail, etc.) can be added as required. + +Pricing depends on scope, fleet size, number of users/tenants, regulatory requirements, and which optional components you select. + +### Request a quote + +Email: pol@henarejos.me +Subject: `ENTERPRISE LICENSE ` + +Please include: +- Company name and country +- Intended use: + - Internal private deployment + - OEM / external service to third parties +- Approximate scale (number of devices/tokens, number of users/tenants) +- Which optional components you are interested in (bulk provisioning, policy & lifecycle tooling, attestation branding / anti-cloning, virtualization/cloud, PQC, HD key derivation, audit trail, dual-control, key escrow, supply-chain signing, hardened mode, SLA, white-label demo) + +You will receive: +1. A short commercial license agreement naming your company. +2. Access to the base package (and any optional components agreed). +3. Scheduling of the onboarding call. + +## Why Enterprise exists + +- Companies often need hardware-backed security (HSM, FIDO2, OpenPGP, etc.) under their own control, but cannot or will not open-source their internal security workflows. +- They also need multi-user / fleet-management features that hobby users do not. +- The commercial license funds continued development, maintenance and new hardware support. + +The Community Edition remains AGPLv3. +The Enterprise Edition is for production, scale, and legal clarity. diff --git a/README.md b/README.md index af13003..77f34ce 100644 --- a/README.md +++ b/README.md @@ -152,19 +152,38 @@ This project is available under two editions: - run this in production with multiple users/devices, - integrate it into their own product/appliance, - enforce corporate policies (PIN policy, admin/user roles, revocation), + - deploy it as an internal virtualized / cloud-style service, - and *not* be required to publish derivative source code. -- Includes access to enterprise-only features (bulk provisioning, multi-user policy controls, device inventory & revocation, custom attestation/identity), official signed builds, and an onboarding call. +- Base package includes: + - commercial license (no AGPLv3 disclosure obligation for your modifications / integration) + - onboarding call + - access to officially signed builds +- Optional / on-demand enterprise components that can be added case-by-case: + - ability to operate in multi-user / multi-device environments + - device inventory, traceability and secure revocation/offboarding + - custom attestation, per-organization device identity / anti-cloning + - virtualization / internal "HSM or auth backend" service for multiple teams or tenants + - post-quantum (PQC) key material handling and secure PQC credential storage + - hierarchical deterministic key derivation (HD wallet–style key trees for per-user / per-tenant keys, firmware signing trees, etc.) + - cryptographically signed audit trail / tamper-evident logging + - dual-control / two-person approval for high-risk operations + - secure key escrow / disaster recovery strategy + - release-signing / supply-chain hardening toolchain + - policy-locked hardened mode ("FIPS-style profile") + - priority security-response SLA + - white-label demo / pre-sales bundle Typical licensing models: -- Internal use (within one legal entity). -- Redistribution / OEM (shipping this as part of your product). +- Internal use (single legal entity, including internal private cloud / virtualized deployments). +- OEM / Redistribution / Service (ship in your product OR offer it as a service to third parties). + +These options are scoped and priced individually depending on which components you actually need. For commercial licensing and enterprise features, email pol@henarejos.me Subject: `ENTERPRISE LICENSE ` See `ENTERPRISE.md` for details. - ## Credits Pico FIDO uses the following libraries or portion of code: - MbedTLS for cryptographic operations. From c54a6fa6feec69eb13c268f901cdb9cb6b205225 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 27 Oct 2025 08:53:08 +0100 Subject: [PATCH 3/8] Add CONTRIBUTING Signed-off-by: Pol Henarejos --- CONTRIBUTING.md | 105 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..ac193da --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,105 @@ +# Contributing + +Thank you for your interest in contributing to this project. + +This repository is published in two forms: +- a Community Edition released under AGPLv3, and +- a proprietary / commercial / Enterprise Edition offered to organizations. + +To keep that model legally clean, we need to be explicit about how contributions can be used. + +By opening a pull request, you agree to all of the following: + +1. **You have the right to contribute this code.** + You are either the original author of the contribution, or you have obtained the necessary rights/permissions to contribute it under these terms. + +2. **Dual licensing permission.** + You agree that your contribution may be: + - merged into this repository, and + - used, copied, modified, sublicensed, and redistributed + - under the AGPLv3 Community Edition, and + - under any proprietary / commercial / Enterprise editions of this project, + now or in the future. + + In other words: you are granting the project maintainer(s) the right to include + your contribution in both the open-source (AGPLv3) codebase and in closed-source / + commercially licensed builds, without any additional approval or payment. + +3. **Attribution.** + The maintainers may keep or add attribution lines such as + `Copyright (c) ` or an AUTHORS / CONTRIBUTORS list. + The maintainers may also make changes for clarity, style, security, refactoring, + or integration reasons. + +4. **No automatic SLA.** + Submitting a pull request does *not* create any support obligation, + service-level agreement, warranty, or guarantee that the contribution + will be reviewed, merged, or maintained. + +5. **Potential rejection for business reasons.** + Features that fall under "Enterprise / Commercial" functionality + (e.g. multi-tenant provisioning at scale, centralized audit trails, + corporate policy enforcement, attestation/branding flows, key escrow / dual-control, + etc.) may be declined for the public AGPLv3 tree even if technically valid. + That is normal: some functionality is intentionally offered only + under commercial terms. + +If you are not comfortable with these terms, **do not open a pull request yet.** +Instead, please open an Issue to start a discussion. + +## How to contribute (technical side) + +### 1. Bug reports / issues +- Please include: + - hardware / board revision + - firmware / commit hash + - exact steps to reproduce + - expected vs actual behavior + - logs / traces if available (strip secrets) + +Security-sensitive findings: do **not** post publicly. +Send a short report by email instead so it can be triaged responsibly. + +### 2. Small fixes / minor improvements +- You can open a PR directly for: + - bug fixes + - portability fixes / new board definitions + - clarifications in code comments + - build / tooling cleanup + - documentation of existing behavior + +Please keep PRs focused (one logical change per PR if possible). + +### 3. Larger features / behavior changes +- Please open an Issue first and describe: + - what problem you're solving (not just "add feature X") + - impact on existing flows / security model + - any new dependencies + +This helps avoid doing a bunch of work on something that won't be accepted +in the Community Edition. + +### 4. Coding style / security posture +- Aim for clarity and small, auditable changes. This code runs in places + where secrets live. +- No debug backdoors, no "just for testing" shortcuts left enabled. +- Keep external dependencies minimal and license-compatible + (MIT / Apache 2.0 / similarly permissive is usually fine). + +### 5. Commit / PR format +- Use descriptive commit messages ("Fix PIN retry counter wrap" is better than "fix stuff"). +- In the PR description, please include a short summary of what was changed and why. +- At the bottom of the PR description, **copy/paste and confirm the licensing line below**: + + > I confirm that I have read `CONTRIBUTING.md` and I agree that this contribution may be used under both the AGPLv3 Community Edition and any proprietary / commercial / Enterprise editions of this project, now or in the future. + +A PR without that confirmation may be delayed or closed without merge. + +## Thank you + +This project exists because people build on it, break it, fix it, +and push it into places it wasn't originally designed to go. + +Whether you are here for research, hacking on hardware, +rolling out secure keys for a team, or building a commercial product: +thank you for helping improve it. From cf0686f857b8f6d78cbebc3c604df6814b463dc0 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Mon, 27 Oct 2025 08:57:59 +0100 Subject: [PATCH 4/8] Add template for pull requests. Signed-off-by: Pol Henarejos --- .github/PULL_REQUEST_TEMPLATE.md | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..07a08ad --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,50 @@ +## Summary + +Describe in plain language what this PR does and why. + +- What problem does it solve? +- Is it a bug fix, a new feature, a cleanup/refactor…? + + +## Details / Impact + +Please include any relevant details: + +- Hardware / board(s) tested: +- Firmware / commit/base version: +- Security impact (if any): + - e.g. changes PIN handling, touches key storage, affects attestation, etc. +- Behavior changes: + - e.g. new command, new API surface, different defaults, etc. + + +## Testing + +How did you test this change? + +- Steps to reproduce / validate: +- Expected vs actual results: +- Any logs / traces (please remove secrets): + + +## Licensing confirmation (required) + +By checking the box below, you confirm ALL of the following: + +- You are the author of this contribution, or you have the right to contribute it. +- You have read `CONTRIBUTING.md`. +- You agree that this contribution may be merged, used, modified, and redistributed: + - under the AGPLv3 Community Edition, **and** + - under any proprietary / commercial / Enterprise editions of this project, + now or in the future. +- You understand that submitting this PR does not create any support obligation, + SLA, or guarantee of merge. + +**I confirm the above licensing terms:** + +- [ ] Yes, I agree + + +## Anything else? + +Optional: mention known limitations, follow-ups, or if this is related to an existing Issue. From b0180711e7ba8c3848f1d91a2233cbd658627192 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 28 Oct 2025 09:36:55 +0100 Subject: [PATCH 5/8] Fix build. Signed-off-by: Pol Henarejos --- pico-keys-sdk | 2 +- src/fido/cbor.c | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/pico-keys-sdk b/pico-keys-sdk index 8f907b2..9b6d6f6 160000 --- a/pico-keys-sdk +++ b/pico-keys-sdk @@ -1 +1 @@ -Subproject commit 8f907b25ba28cea4f8312e627862352fc012a8a2 +Subproject commit 9b6d6f67364aeb378a6fcb32389ae745c145e6b9 diff --git a/src/fido/cbor.c b/src/fido/cbor.c index 29a1b98..fec4d2f 100644 --- a/src/fido/cbor.c +++ b/src/fido/cbor.c @@ -135,9 +135,6 @@ void *cbor_thread(void *arg) { flag = EV_EXEC_FINISHED; queue_add_blocking(&card_to_usb_q, &flag); } -#ifdef ESP_PLATFORM - vTaskDelete(NULL); -#endif return NULL; } From 5b778f2e27d6c1ae8ad6d84c0b0e9b0bd3822a20 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Tue, 28 Oct 2025 10:19:48 +0100 Subject: [PATCH 6/8] Fix CI/CD Signed-off-by: Pol Henarejos --- tests/docker/bookworm/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/docker/bookworm/Dockerfile b/tests/docker/bookworm/Dockerfile index db2074a..d55b718 100644 --- a/tests/docker/bookworm/Dockerfile +++ b/tests/docker/bookworm/Dockerfile @@ -21,8 +21,9 @@ RUN apt install -y libccid \ swig \ cmake \ libfuse-dev \ + python3-pyscard \ && rm -rf /var/lib/apt/lists/* -RUN pip3 install pytest pycvc cryptography pyscard inputimeout fido2==2.0.0 --break-system-packages +RUN pip3 install pytest pycvc cryptography inputimeout fido2==2.0.0 --break-system-packages WORKDIR / RUN git clone https://github.com/frankmorgner/vsmartcard.git WORKDIR /vsmartcard/virtualsmartcard From 65194e37754725ccf34cb9d23530b44608537fb0 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 9 Nov 2025 20:13:04 +0100 Subject: [PATCH 7/8] Remove debug. Signed-off-by: Pol Henarejos --- src/fido/cbor_client_pin.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/fido/cbor_client_pin.c b/src/fido/cbor_client_pin.c index 75fcd62..7a4097c 100644 --- a/src/fido/cbor_client_pin.c +++ b/src/fido/cbor_client_pin.c @@ -271,7 +271,6 @@ int check_keydev_encrypted(const uint8_t pin_token[32]) { uint8_t tmp_keydev[61]; tmp_keydev[0] = 0x02; // Change format to encrypted encrypt_with_aad(pin_token, file_get_data(ef_keydev) + 1, 32, tmp_keydev + 1); - DEBUG_DATA(tmp_keydev, sizeof(tmp_keydev)); file_put_data(ef_keydev, tmp_keydev, sizeof(tmp_keydev)); mbedtls_platform_zeroize(tmp_keydev, sizeof(tmp_keydev)); low_flash_available(); From 0d89a21be7ef1b67c64fa0eadd36c6d593962272 Mon Sep 17 00:00:00 2001 From: Pol Henarejos Date: Sun, 9 Nov 2025 20:13:45 +0100 Subject: [PATCH 8/8] Fix if/else logic. Fixes #199. Signed-off-by: Pol Henarejos --- src/fido/cbor_config.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/fido/cbor_config.c b/src/fido/cbor_config.c index 2ee716d..f00cf83 100644 --- a/src/fido/cbor_config.c +++ b/src/fido/cbor_config.c @@ -210,12 +210,6 @@ int cbor_config(const uint8_t *data, size_t len) { else if (vendorCommandId == CTAP_CONFIG_PHY_OPTS) { phy_data.opts = (uint16_t)vendorParamInt; } - else { - CBOR_ERROR(CTAP2_ERR_UNSUPPORTED_OPTION); - } - if (is_phy && phy_save() != PICOKEY_OK) { - CBOR_ERROR(CTAP2_ERR_PROCESSING); - } #endif else if (vendorCommandId == CTAP_CONFIG_EA_UPLOAD) { if (vendorParamByteString.present == false) { @@ -245,6 +239,11 @@ int cbor_config(const uint8_t *data, size_t len) { else { CBOR_ERROR(CTAP2_ERR_INVALID_SUBCOMMAND); } +#ifndef ENABLE_EMULATION + if (is_phy && phy_save() != PICOKEY_OK) { + CBOR_ERROR(CTAP2_ERR_PROCESSING); + } +#endif goto err; } else if (subcommand == 0x03) {