cryptnox-sdk-arduino 1.0.0
Arduino library for Cryptnox Hardware Wallet
Loading...
Searching...
No Matches
VerifyPin.ino

Minimal Cryptnox example: open a secure channel and submit a PIN.

Minimal Cryptnox example: open a secure channel and submit a PIN.Wiring & prerequisites:

  • PN532 NFC reader on SPI, with SS on pin PN532_SS_PIN.
  • A Cryptnox card initialised with a known PIN (use the Cryptnox CLI: cryptnox init, then cryptnox seed generate).
  • DEMO_PIN must match the PIN set on the card.

What the sketch does in each loop iteration:

  1. Connect to the card and establish the secure channel.
  2. Submit DEMO_PIN over the secure channel.
  3. Print "PIN accepted" if the card returned SW 0x9000, otherwise "PIN rejected (or channel error)". When the SW is not 0x9000 the SDK also prints the raw bytes (e.g. "Secured APDU: bad SW 0x63C2" means wrong PIN with 2 retries remaining).
  4. Disconnect.
Warning
Every wrong PIN attempt decrements the card's retry counter. Reaching 0 retries permanently blocks the PIN; recovery then requires the PUK via cryptnox unblock_pin. Halt the sketch as soon as CryptnoxWallet::verifyPin returns false and check DEMO_PIN before retrying.
Note
The PIN "000000000" used by the project examples is a demo placeholder. In real deployments set a strong PIN, never commit source files containing a real PIN, and keep this value out of any version-controlled config.
/*
* SPDX-License-Identifier: LGPL-3.0-or-later
* Copyright (c) 2026 Cryptnox SA
*/
#include <CryptnoxWallet.h>
#include <SPI.h>
#define PN532_SS_PIN (10U)
#define DEMO_PIN "000000000"
void setup() {
serialAdapter.begin(115200);
delay(1000); /* Arduino R4: wait for Serial */
SPI.begin();
if (!wallet.begin()) {
serialAdapter.println(F("PN532 init failed"));
while (1);
}
}
void loop() {
if (!wallet.connect(session)) {
serialAdapter.println(F("Card not detected"));
wallet.disconnect(session);
delay(1000);
return;
}
if (!wallet.verifyPin(session,
reinterpret_cast<const uint8_t*>(DEMO_PIN),
(uint8_t)strlen(DEMO_PIN))) {
/* CRITICAL: do NOT loop on failure — each wrong PIN attempt
* decrements the card's retry counter (typically 3-5 tries) and
* permanently blocks the PIN at zero. Halt and let the developer
* inspect the Serial output / fix DEMO_PIN before retrying. */
serialAdapter.println(F("PIN rejected — halting to protect retry counter"));
wallet.disconnect(session);
while (1);
}
serialAdapter.println(F("PIN accepted"));
wallet.disconnect(session);
delay(1000);
}
void setup()
Arduino setup function.
CryptnoxWallet wallet(nfc, serialAdapter, cryptoProvider, platform)
PN532Adapter nfc(serialAdapter, PN532_SS, &SPI)
ArduinoLoggerAdapter serialAdapter
ArduinoPlatform platform
ArduinoCryptoProvider cryptoProvider
void loop()
Arduino main loop.
#define PN532_SS_PIN
SPI slave-select (CS) pin connected to the PN532 module.
Definition Connect.ino:31
#define DEMO_PIN
Demo PIN used by this example. Must match the PIN that the card was initialised with (4–9 ASCII digit...
Definition Sign.ino:50
CW_CryptoProvider implementation for the Arduino UNO R4 (RA4M1).
CW_Logger implementation wrapping Arduino's HardwareSerial.
CW_Platform implementation using Arduino's blocking delay().
High-level interface for interacting with a Cryptnox Hardware Wallet over NFC.
CW_NfcTransport implementation over the Adafruit_PN532 driver.
#define F(string_literal)
Holds cryptographic session state for reentrant secure channel operations.
Definition CW_Defs.h:168