Commit d1e781c8 authored by jan.koester's avatar jan.koester
Browse files

test

parent 5673f282
Loading
Loading
Loading
Loading

test/tls.cpp

0 → 100644
+167 −0
Original line number Diff line number Diff line
// tls13_selftest.cpp
#include <vector>
#include <cstdint>
#include <cstring>
#include <iostream>
#include <stdexcept>

#include "../src/socket.h"
#include "../src/crypto/aes.h"
#include "../src/exception.h"

static void dumpHex(const char* tag, const uint8_t* p, size_t n, size_t max=96) {
    std::cout << tag << " (" << n << " bytes)\n";
    size_t m = (n > max) ? max : n;
    for (size_t i=0;i<m;i++) {
        printf("%02x ", p[i]);
        if ((i % 16) == 15) printf("\n");
    }
    if (m % 16) printf("\n");
    if (n > max) std::cout << "...\n";
}

namespace netplus {

// In ssl-Klasse hinzufügen:
//   friend class TestSSL;

class TestSSL {
public:
    explicit TestSSL(netplus::ssl& s) : S(s) {}

    void run_tls13_record_loopback() {
        std::cout << "\n=== TLS1.3 AEAD Record Loopback Selftest ===\n";

        // ---- deterministic test key
        const key128 KEY = {
            0x2b,0x7e,0x15,0x16,0x28,0xae,0xd2,0xa6,
            0xab,0xf7,0x15,0x88,0x09,0xcf,0x4f,0x3c
        };

        uint8_t iv[12];
        for (int i=0;i<12;i++) iv[i] = uint8_t(0xA0 + i);

        // install HS keys (loopback: same key/iv both dirs)
        S._aes13_hs_send.reset(new aes(KEY));
        S._aes13_hs_recv.reset(new aes(KEY));
        std::memcpy(S._tls13_hs_iv_s2c, iv, 12);
        std::memcpy(S._tls13_hs_iv_c2s, iv, 12);
        S._tls13_hs_send_seq = 0;
        S._tls13_hs_recv_seq = 0;

        // record #1
        std::vector<uint8_t> msg1 = { 0x08,0x00,0x00,0x02,0x00,0x00 };
        auto rec1 = send_record_capture(/*inner_type=*/0x16, msg1, /*handshake_keys=*/true);
        dumpHex("Captured rec1", rec1.data(), rec1.size());

        auto dec1 = recv_record_parse(rec1, /*handshake_keys=*/true);
        if (dec1.inner_type != 0x16) throw std::runtime_error("rec1 inner_type mismatch");
        if (dec1.plain != msg1)      throw std::runtime_error("rec1 plaintext mismatch");

        if (S._tls13_hs_send_seq != 1) throw std::runtime_error("send seq not 1 after rec1");
        if (S._tls13_hs_recv_seq != 1) throw std::runtime_error("recv seq not 1 after rec1");
        std::cout << "✅ PASS: rec1 loopback OK\n";

        // record #2 (anders lang => triggert GHASH partial differently)
        std::vector<uint8_t> msg2 = { 0x14,0x00,0x00,0x00 };
        auto rec2 = send_record_capture(0x16, msg2, true);
        dumpHex("Captured rec2", rec2.data(), rec2.size());

        auto dec2 = recv_record_parse(rec2, true);
        if (dec2.inner_type != 0x16) throw std::runtime_error("rec2 inner_type mismatch");
        if (dec2.plain != msg2)      throw std::runtime_error("rec2 plaintext mismatch");

        if (S._tls13_hs_send_seq != 2) throw std::runtime_error("send seq not 2 after rec2");
        if (S._tls13_hs_recv_seq != 2) throw std::runtime_error("recv seq not 2 after rec2");
        std::cout << "✅ PASS: rec2 loopback OK\n";

        // tag corruption test
        auto rec3 = send_record_capture(0x16, msg1, true);
        rec3.back() ^= 0x01;

        bool rejected = false;
        try {
            (void)recv_record_parse(rec3, true);
        } catch (...) {
            rejected = true;
        }
        if (!rejected) throw std::runtime_error("corrupted tag was NOT rejected");
        std::cout << "✅ PASS: corrupted tag rejected\n";
    }

private:
    netplus::ssl& S;

    struct Dec {
        std::vector<uint8_t> plain;
        uint8_t inner_type = 0;
    };

    void clear_send_queue() {
        S._send_queue.clear();
    }

    std::vector<uint8_t> drain_send_queue_bytes() {
        std::vector<uint8_t> out;
        for (auto& chunk : S._send_queue) {
            out.insert(out.end(), chunk.begin(), chunk.end());
        }
        S._send_queue.clear();
        return out;
    }

    std::vector<uint8_t> send_record_capture(uint8_t inner_type,
                                             const std::vector<uint8_t>& content,
                                             bool handshake_keys)
    {
        clear_send_queue();
        S._tls13_send_record(inner_type, content, handshake_keys);
        auto bytes = drain_send_queue_bytes();
        if (bytes.size() < 5 + 16) throw std::runtime_error("captured record too small");
        return bytes;
    }

    Dec recv_record_parse(const std::vector<uint8_t>& rec, bool handshake_keys) {
        if (rec.size() < 5 + 16) throw std::runtime_error("record too short");

        uint8_t  rtype = rec[0];
        uint16_t ver   = (uint16_t(rec[1])<<8) | rec[2];
        uint16_t rlen  = (uint16_t(rec[3])<<8) | rec[4];
        if (5 + rlen != rec.size()) throw std::runtime_error("record length mismatch");

        Dec d;
        std::vector<uint8_t> plain;
        uint8_t inner = 0;

        S._tls13_recv_record(
            rtype, ver,
            rec.data() + 5, rlen,
            plain, inner,
            handshake_keys
        );

        d.plain = std::move(plain);
        d.inner_type = inner;
        return d;
    }
};

} // namespace netplus

int main() {
    try {
        // du brauchst irgendeine ssl instanz.
        // Wenn dein ssl ctor ein cert braucht: erzeuge dummy cert etc.
        netplus::x509cert cert;
        netplus::ssl ssl(cert);

        netplus::TestSSL T(ssl);
        T.run_tls13_record_loopback();

        std::cout << "\n✅ ALL TLS13 SELFTESTS PASSED\n";
        return 0;
    } catch (const netplus::NetException& e) {
        std::cerr << "\n❌ TLS13 SELFTEST FAILED: " << e.what() << "\n";
        return 1;
    }
}

test/x25519.cpp

0 → 100644
+173 −0
Original line number Diff line number Diff line
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cstdint>

#include "../src/crypto/curve25519.h"

void print_hex(const std::vector<uint8_t>& v, size_t n = 0, std::ostream& os = std::cout) {
    if (n == 0) n = v.size();
    for (size_t i = 0; i < n && i < v.size(); ++i)
        os << std::hex << std::setw(2) << std::setfill('0') << (int)v[i];
}

bool equal32(const std::vector<uint8_t>& x, const std::vector<uint8_t>& y) {
    return x.size() == 32 && y.size() == 32 && std::equal(x.begin(), x.end(), y.begin());
}

int main() {
    std::cout << "Running X25519 RFC7748 vectors + 1000-iteration KAT...\n";

    std::vector<uint8_t> out;
    int ok = 1;

    // ---------------------------------------------------------
    // RFC7748 vector #1: scalar1 * base(9)
    // ---------------------------------------------------------
    const std::vector<uint8_t> scalar1 = {
        0xa5,0x46,0xe3,0x6b,0xf0,0x52,0x7c,0x9d,
        0x3b,0x16,0x15,0x4b,0x82,0x46,0x5e,0xdd,
        0x62,0x14,0x4c,0x0a,0xc1,0xfc,0x5a,0x18,
        0x50,0x6a,0x22,0x44,0xba,0x44,0x9a,0xc4
    };

    const  std::vector<uint8_t> expect1 = {
        0xe6,0xdb,0x68,0x67,0x58,0x30,0x30,0xdb,
        0x35,0x94,0xc1,0xa4,0x24,0xb1,0x5f,0x7c,
        0x72,0x66,0x24,0xec,0x26,0xb3,0x35,0x3b,
        0x10,0xa9,0x03,0xa6,0xd0,0xab,0x1c,0x4c
    };

    netplus::scalarmult_curve25519_base(out, scalar1);
    if (!equal32(out, expect1)) {
        ok = 0;
        std::cerr << "FAIL: RFC7748 vector #1 (scalar1*base)\n";
        std::cerr << "  got: "; print_hex(out, 32, std::cerr); std::cerr << "\n";
        std::cerr << "  exp: "; print_hex(expect1, 32, std::cerr); std::cerr << "\n";
    } else {
        std::cout << "PASS: RFC7748 vector #1\n";
    }

    // ---------------------------------------------------------
    // RFC7748 vector #2: scalar2 * point2
    // ---------------------------------------------------------
    const  std::vector<uint8_t> scalar2 = {
        0x4b,0x66,0xe9,0xd4,0xd1,0xb4,0x67,0x3c,
        0x5a,0xd2,0x26,0x91,0x95,0x7d,0x6a,0xf5,
        0xc1,0x1b,0x64,0x21,0xe0,0xea,0x01,0xd4,
        0x2c,0xa4,0x16,0x9e,0x79,0x18,0xba,0x0d
    };

    const  std::vector<uint8_t> point2 = {
        0xe5,0x21,0x0f,0x12,0x78,0x68,0x11,0xd3,
        0xf4,0xb7,0x95,0x9d,0x05,0x38,0xae,0x2c,
        0x31,0xdb,0xe7,0x10,0x6f,0xc0,0x3c,0x3e,
        0xfc,0x4c,0xd5,0x49,0xc7,0x15,0xa4,0x93
    };

    const  std::vector<uint8_t> expect2 = {
        0x95,0xcb,0xde,0x94,0x76,0xe8,0x90,0x7d,
        0x7a,0xad,0xe4,0x5c,0xb4,0xb8,0x73,0xf8,
        0x8b,0x59,0x5a,0x68,0x79,0x9f,0xa1,0x52,
        0xe6,0xf8,0xf7,0x64,0x7a,0xac,0x79,0x57
    };

    std::cout << "Test harness: scalar2: "; print_hex(scalar2); std::cout << "\n";
    std::cout << "Test harness: point2:  "; print_hex(point2); std::cout << "\n";
    if (!netplus::scalarmult_curve25519(out, scalar2, point2)) {
        ok = 0;
        std::cerr << "FAIL: RFC7748 vector #2 (returned zero)\n";
    } else if (!equal32(out, expect2)) {
        ok = 0;
        std::cerr << "FAIL: RFC7748 vector #2 (scalar2*point2)\n";
        std::cerr << "  got: "; print_hex(out, 32, std::cerr); std::cerr << "\n";
        std::cerr << "  exp: "; print_hex(expect2, 32, std::cerr); std::cerr << "\n";
    } else {
        std::cout << "PASS: RFC7748 vector #2\n";
    }

    // ---------------------------------------------------------
    // RFC7748 1000-iteration KAT
    // (Section 5.2, test with iterated scalarmult)
    // ---------------------------------------------------------


    std::cout << "Running 1000-iteration KAT...\n";

    std::vector<uint8_t> k(32, 0);
    std::vector<uint8_t> u(32, 0);
    k[0] = 9;
    u[0] = 9;

    std::cout << "After initialization: k = "; print_hex(k); std::cout << "\n";
    std::cout << "After initialization: u = "; print_hex(u); std::cout << "\n";

    for (int i = 0; i < 1000; ++i) {
        std::vector<uint8_t> r;
        std::vector<uint8_t> prev_k = k;
/*
        std::cout << "KAT loop: k: "; print_hex(k); std::cout << "\n";
        std::cout << "KAT loop: u: "; print_hex(u); std::cout << "\n";
        std::cout << "Before scalarmult_curve25519: k = "; print_hex(k); std::cout << "\n";
        std::cout << "Before scalarmult_curve25519: u = "; print_hex(u); std::cout << "\n";
*/
        netplus::scalarmult_curve25519(r, k, u);

        u = prev_k;
        k = r;
        k.resize(32, 0);
        u.resize(32, 0);

        if (i == 0 || i == 1 || i == 999) {
            std::cout << "  iter " << (i + 1) << ": ";
            print_hex(k, 8); std::cout << "...\n";
        }
    }

    // expected after 1000 iterations
    const  std::vector<uint8_t> kat_k = {
        0x68,0x4c,0xf5,0x9b,0xa8,0x33,0x09,0x55,
        0x28,0x00,0xef,0x56,0x6f,0x2f,0x4d,0x3c,
        0x1c,0x38,0x87,0xc4,0x93,0x60,0xe3,0x87,
        0x5f,0x2e,0xb9,0x4d,0x99,0x53,0x2c,0x51
    };

    const  std::vector<uint8_t> kat_u = {
        0x7c,0x39,0x11,0xe0,0xab,0x25,0x86,0xfd,
        0x86,0x44,0x97,0x29,0x7e,0x57,0x5e,0x6f,
        0x3b,0xc6,0x01,0xc0,0x88,0x3c,0x30,0xdf,
        0x5f,0x4d,0xd2,0xd2,0x4f,0x66,0x54,0x24
    };

    // RFC says final k and u should match these

    if (!equal32(k, kat_k)) {
        ok = 0;
        std::cerr << "FAIL: KAT 1000 - final k mismatch\n";
        std::cerr << "  got k: "; print_hex(k, 32, std::cerr); std::cerr << "\n";
        std::cerr << "  exp k: "; print_hex(kat_k, 32, std::cerr); std::cerr << "\n";
    } else {
        std::cout << "PASS: KAT 1000 final k\n";
    }

    if (!equal32(u, kat_u)) {
        ok = 0;
        std::cerr << "FAIL: KAT 1000 - final u mismatch\n";
        std::cerr << "  got u: "; print_hex(u, 32, std::cerr); std::cerr << "\n";
        std::cerr << "  exp u: "; print_hex(kat_u, 32, std::cerr); std::cerr << "\n";
    } else {
        std::cout << "PASS: KAT 1000 final u\n";
    }

    // ---------------------------------------------------------
    // Summary
    // ---------------------------------------------------------
    if (ok) {
        std::cout << "ALL RFC7748 X25519 tests PASSED ✅\n";
        return 0;
    }

    std::cerr << "RFC7748 X25519 tests FAILED ❌\n";
    return 1;
}