diff --git a/main/zk_auth.h b/main/zk_auth.h index fdd769b..85bd2da 100644 --- a/main/zk_auth.h +++ b/main/zk_auth.h @@ -92,22 +92,99 @@ public: } // Marked as static so it can be passed as a C callback to libssh2 + // Helper to safely format SSH integers (mpint) exactly how OpenSSH demands + static uint32_t write_mpint(uint8_t *buf, const uint8_t *val, uint32_t size) { + uint32_t start = 0; + + // Strip unnecessary leading zeros + while (start < (size - 1) && val[start] == 0x00) { + start++; + } + + // If the most significant bit is 1, we must prepend a 0x00 padding byte + bool pad = (val[start] & 0x80) != 0; + uint32_t len = (size - start) + (pad ? 1 : 0); + + uint32_t offset = 0; + buf[offset++] = (len >> 24) & 0xFF; + buf[offset++] = (len >> 16) & 0xFF; + buf[offset++] = (len >> 8) & 0xFF; + buf[offset++] = len & 0xFF; + + if (pad) { + buf[offset++] = 0x00; + } + memcpy(&buf[offset], &val[start], size - start); + return offset + (size - start); + } + + // The main signing callback static int sign_callback(LIBSSH2_SESSION *session, unsigned char **sig, size_t *sig_len, const unsigned char *data, size_t data_len, void **abstract) { - ATCA_STATUS status; - uint8_t signature[64]; + uint8_t digest[32]; + uint8_t raw_sig[64]; - // sign the data hash with ATECC608B - status = atcab_sign(0x0, data, signature); - if (status != ATCA_SUCCESS) { + printf("\n--- SSH SIGNATURE DIAGNOSTICS ---\n"); + + // 1. Hash the challenge and strictly check for failure + int hash_err = mbedtls_sha256(data, data_len, digest, 0); + if (hash_err != 0) { + printf("CRITICAL: mbedtls_sha256 failed with code %d\n", hash_err); return -1; } - // TODO: implement DER encoding and allocate output blob - // ... + printf("SHA-256 Digest: "); + for (int i = 0; i < 32; i++) + printf("%02x", digest[i]); + printf("\n"); - return 0; + // 2. Request the signature from the secure element + if (atcab_sign(0, digest, raw_sig) != ATCA_SUCCESS) { + printf("CRITICAL: ATECC608B Signing Failed!\n"); + return -1; + } + + printf("Raw Sig R: "); + for (int i = 0; i < 32; i++) + printf("%02x", raw_sig[i]); + printf("\nRaw Sig S: "); + for (int i = 32; i < 64; i++) + printf("%02x", raw_sig[i]); + printf("\n---------------------------------\n"); + + // 3. Allocate and format (Identical to previous step) + unsigned char *buf = (unsigned char *)malloc(150); + if (!buf) + return -1; + + uint32_t offset = 0; + const char *type = "ecdsa-sha2-nistp256"; + uint32_t type_len = 19; + + buf[offset++] = (type_len >> 24) & 0xFF; + buf[offset++] = (type_len >> 16) & 0xFF; + buf[offset++] = (type_len >> 8) & 0xFF; + buf[offset++] = type_len & 0xFF; + memcpy(&buf[offset], type, type_len); + offset += type_len; + + uint32_t inner_len_idx = offset; + offset += 4; + + offset += write_mpint(&buf[offset], &raw_sig[0], 32); // R + offset += write_mpint(&buf[offset], &raw_sig[32], 32); // S + + uint32_t inner_len = offset - inner_len_idx - 4; + buf[inner_len_idx] = (inner_len >> 24) & 0xFF; + buf[inner_len_idx + 1] = (inner_len >> 16) & 0xFF; + buf[inner_len_idx + 2] = (inner_len >> 8) & 0xFF; + buf[inner_len_idx + 3] = inner_len & 0xFF; + + *sig = buf; + *sig_len = offset; + + return 0; // Success! } // Helper function to write a 32-bit integer in big-endian format