|
SharkSSL C/C++ Reference
TLS, cryptography, certificates, and PSA integration
|
Check that a firmware image matches a signature made with your trusted signing key before accepting an update. This small C example connects the two parts of that workflow: OpenSSL signs on the development computer; SharkSSL verifies on the device.
The demo uses ECDSA (Elliptic Curve Digital Signature Algorithm) with the P-256 curve and a SHA-256 digest. The digest is a 32-byte fingerprint of the firmware. The signature lets the device check that fingerprint using the public key paired with the signing private key.
Start with the included data to check your SharkSSL integration, then adapt the same verification call to your firmware. All data needed for the first run is inside ecdsa-demo.c.
You need an existing SharkSSL application with SHA-256, ECC (elliptic curve cryptography), ECDSA, the ECDSA API and P-256 enabled. The corresponding options must be 1 when compiling the library and the application:
ecdsa-demo.c to your application using its normal SharkSSL headers and platform configuration. Keep the three test-data arrays unchanged.int sharkssl_ecdsa_demo(void); and call it after your normal platform initialization. The verifier uses SharkSSL's memory allocator.printf, or route it to your serial console/logger.The function takes no arguments. It returns 0 only when the valid signature is accepted and the deliberately changed digest is rejected. It returns 1 if either check fails. This function is a self-test; the first verification call inside it is the operation to adapt for your update code.
Expected output:
The second result is an intentional failure. The C code compares it with SHARKSSL_ECDSA_VERIFICATION_FAIL and prints the expected numeric value. The device test needs no files, private key, PEM parser or application random number generator initialization.
From a Visual Studio Developer Command Prompt, change to examples\ECDSA-Verify in your SharkSSL source SDK and run the included build script:
If you copied the demo elsewhere, supply the SDK's full path instead:
The SDK directory must contain inc\SharkSSL.h and src. The script supports the original source tree and an amalgamated SDK with src\SharkSSL.c. It builds and runs build\ecdsa-demo.exe using settings local to this desktop build.
If you use your own desktop project, define ECDSA_DEMO_MAIN to enable the supplied main(). Leave it undefined when your application already has an entry point. A desktop pass does not replace running the test on your target.
The C file follows three steps: hash the message, verify its signature, and run the deliberate failure test. The accompanying files let you check the same inputs independently on your computer:
| File | What it contains |
|---|---|
| message.bin | The 37 signed bytes, including the final newline |
| public.pem | The demo public key in PEM text format |
| signature.der | The 71-byte binary signature of message.bin |
DER (Distinguished Encoding Rules) encodes the ECDSA signature as a sequence of two integers, called r and s. The verifier expects this complete structure. PEM is the text representation used to exchange the public key with OpenSSL; the C array already contains the converted SharkSSL key.
With OpenSSL installed, run these commands from this folder:
The digest must match the demo output, verification must report Verified OK, and the signature must contain a sequence with two integers.
In a separate test directory containing your firmware.bin, run:
These commands create a new key pair. Use its public key with its signatures; it will not match the demo's included signature. Keep the private key on the signing computer and use the generated SharkSSL public-key array on the device. For a product, provision the verification key through a trusted process.
SharkSslSha256Ctx once. Pass each firmware block, in order, to SharkSslSha256Ctx_append() using its actual byte count. Hash exactly the bytes signed on the computer, excluding any attached signature.SharkSslSha256Ctx_finish() once to obtain the raw 32-byte digest.sharkssl_ECDSA_verify_hash() as in step 2 of the C example. Supply your trusted public key, the binary contents of firmware.sig, its actual byte length, the digest and SHARKSSL_HASHID_SHA256.SHARKSSL_ECDSA_OK. Every other result is a failure.siglen is a U16 byte count. If your package parser stores the length in a wider type, check its bounds before converting it to U16. A P-256 signature needs at most 72 bytes in DER form, but pass the actual length, not the buffer capacity. Do not obtain the verification key from an untrusted update package.
This example covers signature verification. A complete updater also needs protected key storage, version/rollback policy and a safe installation process.
| Check | What the verifier needs |
|---|---|
| Digest | 32 binary SHA-256 bytes, not a 64-character hexadecimal string |
| Signature | Complete binary DER, not a raw 64-byte concatenation of r and s or encoded text |
| Signature length | Exact bytes received, with no added terminator or padding |
| Hash argument | SHARKSSL_HASHID_SHA256, not SHARKSSL_SHA256_HASH_LEN |
| Signed data | The original firmware bytes, hashed once |
| Public key | The SharkSSL-format key corresponding to the signing private key |
openssl dgst -sha256 -sign hashes its input before signing. Give it the original firmware file. Passing a previously calculated digest file would hash that digest again. The SharkSSL verification API uses the supplied digest directly, without hashing it again.
Run the unchanged demo first. If it fails, record the printed digest, numeric return codes, SharkSSL version, target processor and library configuration. If it passes but your update fails, compare the exact key, signature bytes, signature length and digest at the call. A generic verification failure can also indicate a parsing, curve-support or allocation problem.
The SDK's RayCrypto-ECDSA.c demonstrates signing and verification within SharkSSL, including different key representations and curves. This example focuses on an OpenSSL-generated signature and a small device verification call.