Ejemplo n.º 1
0
/** https://github.com/cjdelisle/cjdns/issues/179 */
static void test179(struct Allocator* alloc, struct Log* logger)
{
    uint8_t buff[32] = {0};
    uint8_t buff2[32] = {0};

    struct Random* rand = Random_new(alloc, logger, NULL);
    struct Random* rand2 = Random_new(alloc, logger, NULL);

    Random_bytes(rand, buff, 32);
    Random_bytes(rand2, buff, 32);

    Assert_true(Bits_memcmp(buff, buff2, 32));
}
Ejemplo n.º 2
0
static void checkBytes(struct Random* rand, int alignment, int length)
{
    Assert_true(length < 128 && alignment < 8);

    uint64_t buff64[20] = {0};
    uint8_t* buff = (uint8_t*) (&buff64[1]);
    buff += alignment;

    // Check for bytes which are always the same, a few \0s are ok
    // but if every cycle they are always zero then there's a bug.
    uint8_t oldBuff[128] = {0};
    // Preload into the output buff so alignment is same.
    Random_bytes(rand, buff, length);
    Bits_memcpy(oldBuff, buff, length);

    uint8_t sameAsOld[128];
    Bits_memset(sameAsOld, 0xff, 128);

    // Check for bytes which are the same as other bytes every time.
    // if buff[3] always equals buff[8] then there's a bug.
    uint8_t sameBytes[128+128];
    Bits_memset(sameBytes, 0xff, 128+128);

    for (int i = 0; i < 100; i++) {
        Random_bytes(rand, buff, length);

        for (int j = 0; j < length; j++) {
            for (int jj = j; jj < length; jj++) {
                sameBytes[j+jj] &= (jj != j && buff[j] == buff[jj]);
            }
        }

        for (int j = 0; j < length; j++) {
            sameAsOld[j] &= (oldBuff[i] == buff[i]);
        }

        // Check that the function did not write after or before the buffer.
        uint8_t* origBuff = (uint8_t*) (buff64);
        Assert_true(Bits_isZero(origBuff, 8+alignment));
        Assert_true(Bits_isZero(buff+length, 8));
    }

    for (int i = 0; i < length+length-1; i++) {
        Assert_true(!sameBytes[i]);
    }
    for (int i = 0; i < length; i++) {
        Assert_true(!sameAsOld[i]);
    }
}
Ejemplo n.º 3
0
void Sign_signMsg(uint8_t keyPair[64], struct Message* msg, struct Random* rand)
{
    // az is set to the secret key followed by another secret value
    // which since we don't have a secret seed in this algorithm is just the
    // hash of the secret key and 32 bytes of random
    uint8_t az[64];
    uint8_t r[64];
    ge_p3 R;
    uint8_t hram[64];

    Bits_memcpy(az, keyPair, 32);
    Random_bytes(rand, &az[32], 32);
    crypto_hash_sha512(az,az,64);
    Bits_memcpy(az, keyPair, 32);
    az[0] &= 248;
    az[31] &= 63;
    az[31] |= 64;

    // hash message + secret number
    Message_push(msg, &az[32], 32, NULL);
    crypto_hash_sha512(r, msg->bytes, msg->length);

    // Replace secret number with public key
    Bits_memcpy(msg->bytes, &keyPair[32], 32);

    // push pointMul(r) to message
    sc_reduce(r);
    ge_scalarmult_base(&R,r);
    Message_shift(msg, 32, NULL);
    ge_p3_tobytes(msg->bytes,&R);

    crypto_hash_sha512(hram, msg->bytes, msg->length);
    sc_reduce(hram);
    sc_muladd(&msg->bytes[32], hram, az, r);
}
Ejemplo n.º 4
0
static void testDuplicates(struct Random* rand)
{
    uint16_t randomShorts[8192];
    uint16_t out[8192];
    struct ReplayProtector rp = {.bitfield = 0};

    Random_bytes(rand, (uint8_t*)randomShorts, sizeof(randomShorts));

    uint32_t outIdx = 0;
    for (uint32_t i = 0; i < 1024; i++) {
        if (ReplayProtector_checkNonce((randomShorts[i] % (i + 20)), &rp)) {
            out[outIdx] = (randomShorts[i] % (i + 20));
            outIdx++;
        }
    }

    for (uint32_t i = 0; i < outIdx; i++) {
        for (uint32_t j = i + 1; j < outIdx; j++) {
            Assert_always(out[i] != out[j]);
        }
    }
}

int main()
{
    struct Allocator* alloc = MallocAllocator_new(4096);
    struct Random* rand = Random_new(alloc, NULL, NULL);
    for (int i = 0; i < CYCLES; i++) {
        testDuplicates(rand);
    }
    return 0;
}
Ejemplo n.º 5
0
struct CryptoAuth* CryptoAuth_new(struct Allocator* allocator,
                                  const uint8_t* privateKey,
                                  struct EventBase* eventBase,
                                  struct Log* logger,
                                  struct Random* rand)
{
    struct CryptoAuth_pvt* ca = Allocator_calloc(allocator, sizeof(struct CryptoAuth_pvt), 1);
    Identity_set(ca);
    ca->allocator = allocator;
    ca->eventBase = eventBase;
    ca->logger = logger;
    ca->pub.resetAfterInactivitySeconds = CryptoAuth_DEFAULT_RESET_AFTER_INACTIVITY_SECONDS;
    ca->rand = rand;

    if (privateKey != NULL) {
        Bits_memcpyConst(ca->privateKey, privateKey, 32);
    } else {
        Random_bytes(rand, ca->privateKey, 32);
    }
    crypto_scalarmult_curve25519_base(ca->pub.publicKey, ca->privateKey);

    if (Defined(Log_KEYS)) {
        uint8_t publicKeyHex[65];
        printHexKey(publicKeyHex, ca->pub.publicKey);
        uint8_t privateKeyHex[65];
        printHexKey(privateKeyHex, ca->privateKey);
        Log_keys(logger,
                  "Initialized CryptoAuth:\n    myPrivateKey=%s\n     myPublicKey=%s\n",
                  privateKeyHex,
                  publicKeyHex);
    }

    return &ca->pub;
}
Ejemplo n.º 6
0
int main()
{
    struct Allocator* alloc = MallocAllocator_new(1048576);
    struct Log* logger = FileWriterLog_new(stdout, alloc);
    struct Random* rand = Random_new(alloc, logger, NULL);

    uint8_t curve25519private[32];
    Random_bytes(rand, curve25519private, 32);
    uint8_t curve25519public[32];
    crypto_scalarmult_curve25519_base(curve25519public, curve25519private);

    uint8_t signingKeyPair[64];
    Sign_signingKeyPairFromCurve25519(signingKeyPair, curve25519private);
    struct Message* msg = Message_new(0, 512, alloc);
    Message_push(msg, "hello world", 12, NULL);
    Sign_signMsg(signingKeyPair, msg, rand);

    uint8_t curve25519publicB[32];
    Assert_true(!Sign_verifyMsg(&signingKeyPair[32], msg));
    Assert_true(!Sign_publicSigningKeyToCurve25519(curve25519publicB, &signingKeyPair[32]));
    Assert_true(!Bits_memcmp(curve25519publicB, curve25519public, 32));

    Allocator_free(alloc);
    return 0;
}
Ejemplo n.º 7
0
int main()
{
    struct Allocator* alloc = MallocAllocator_new(1<<22);
    struct Random* rand = Random_new(alloc, NULL, NULL);
    struct Log* log = FileWriterLog_new(stdout, alloc);

    uint8_t ip[16];
    uint8_t printedIp[40];
    uint8_t printedShortIp[40];
    uint8_t ipFromFull[16];
    uint8_t ipFromShort[16];

    for (int i = 0; i < 1024; ++i) {
        Random_bytes(rand, ip, 16);

        for (int j = 0; j < 16; j++) {
            // make the random result have lots of zeros since that's what we're looking for.
            ip[j] = (ip[j] % 2) ? 0 : ip[j];
        }

        AddrTools_printIp(printedIp, ip);
        AddrTools_printShortIp(printedShortIp, ip);
        //printf("%s\n%s\n\n", printedIp, printedShortIp);

        AddrTools_parseIp(ipFromFull, printedIp);
        AddrTools_parseIp(ipFromShort, printedShortIp);

        Log_debug(log, "print/parse %s", printedIp);

        Assert_true(0 == Bits_memcmp(ip, ipFromFull, 16));
        Assert_true(0 == Bits_memcmp(ipFromFull, ipFromShort, 16));
    }
    Allocator_free(alloc);
    return 0;
}
Ejemplo n.º 8
0
int main()
{
    struct Allocator* alloc = MallocAllocator_new(1<<22);
    struct Random* rand = Random_new(alloc, NULL, NULL);

    uint8_t ip[16];
    uint8_t printedIp[40];
    uint8_t printedShortIp[40];
    uint8_t ipFromFull[16];
    uint8_t ipFromShort[16];

    for (int i = 0; i < 1024; ++i) {
        Random_bytes(rand, ip, 16);

        AddrTools_printIp(printedIp, ip);
        AddrTools_printShortIp(printedShortIp, ip);
        printf("%s\n%s\n\n", printedIp, printedShortIp);

        AddrTools_parseIp(ipFromFull, printedIp);
        AddrTools_parseIp(ipFromShort, printedShortIp);

        Assert_true(0 == Bits_memcmp(ip, ipFromFull, 16));
        Assert_true(0 == Bits_memcmp(ipFromFull, ipFromShort, 16));
    }

    return 0;
}
Ejemplo n.º 9
0
/**
 * If we don't know her key, the handshake has to be done backwards.
 * Reverse handshake requests are signaled by sending a non-obfuscated zero nonce.
 */
static uint8_t genReverseHandshake(struct Message* message,
                                   struct CryptoAuth_Wrapper* wrapper,
                                   union Headers_CryptoAuth* header)
{
    wrapper->nextNonce = 0;
    Message_shift(message, -Headers_CryptoAuth_SIZE);

    // Buffer the packet so it can be sent ASAP
    if (wrapper->bufferedMessage == NULL) {
        cryptoAuthDebug0(wrapper, "Buffered a message");
        wrapper->bufferedMessage =
            Message_clone(message, wrapper->externalInterface.allocator);
        Assert_true(wrapper->nextNonce == 0);
    } else {
        cryptoAuthDebug0(wrapper, "Expelled a message because a session has not yet been setup");
        Message_copyOver(wrapper->bufferedMessage,
                         message,
                         wrapper->externalInterface.allocator);
        Assert_true(wrapper->nextNonce == 0);
    }
    wrapper->hasBufferedMessage = true;

    Message_shift(message, Headers_CryptoAuth_SIZE);
    header = (union Headers_CryptoAuth*) message->bytes;
    header->nonce = UINT32_MAX;
    message->length = Headers_CryptoAuth_SIZE;

    // sessionState must be 0, auth and 24 byte nonce are garbaged and public key is set
    // now garbage the authenticator and the encrypted key which are not used.
    Random_bytes(wrapper->context->rand, (uint8_t*) &header->handshake.authenticator, 48);

    return wrapper->wrappedInterface->sendMessage(message, wrapper->wrappedInterface);
}
Ejemplo n.º 10
0
/**
 * If we don't know her key, the handshake has to be done backwards.
 * Reverse handshake requests are signaled by sending a non-obfuscated zero nonce.
 */
static uint8_t genReverseHandshake(struct Message* message,
                                   struct CryptoAuth_Wrapper* wrapper,
                                   union Headers_CryptoAuth* header)
{
    reset(wrapper);
    Message_shift(message, -Headers_CryptoAuth_SIZE, NULL);

    // Buffer the packet so it can be sent ASAP
    if (wrapper->bufferedMessage != NULL) {
        // Not exactly a drop but a message is not going to reach the destination.
        cryptoAuthDebug0(wrapper,
            "DROP Expelled a message because a session has not yet been setup");
        Allocator_free(wrapper->bufferedMessage->alloc);
    }

    cryptoAuthDebug0(wrapper, "Buffered a message");
    struct Allocator* bmalloc = Allocator_child(wrapper->externalInterface.allocator);
    wrapper->bufferedMessage = Message_clone(message, bmalloc);
    Assert_ifParanoid(wrapper->nextNonce == 0);

    Message_shift(message, Headers_CryptoAuth_SIZE, NULL);
    header = (union Headers_CryptoAuth*) message->bytes;
    header->nonce = UINT32_MAX;
    message->length = Headers_CryptoAuth_SIZE;

    // sessionState must be 0, auth and 24 byte nonce are garbaged and public key is set
    // now garbage the authenticator and the encrypted key which are not used.
    Random_bytes(wrapper->context->rand, (uint8_t*) &header->handshake.authenticator, 48);

    // This is a special packet which the user should never see.
    Headers_setSetupPacket(&header->handshake.auth, 1);

    return wrapper->wrappedInterface->sendMessage(message, wrapper->wrappedInterface);
}
Ejemplo n.º 11
0
static void cryptoAuth(struct Context* ctx)
{
    Log_info(ctx->log, "Setting up salsa20/poly1305 benchmark (encryption and decryption only)");
    struct Allocator* alloc = Allocator_child(ctx->alloc);
    struct CryptoAuth* ca1 = CryptoAuth_new(alloc, NULL, ctx->base, ctx->log, ctx->rand);
    struct CryptoAuth* ca2 = CryptoAuth_new(alloc, NULL, ctx->base, ctx->log, ctx->rand);

    struct CryptoAuth_Session* sess1 =
        CryptoAuth_newSession(ca1, alloc, ca2->publicKey, NULL, false, "bench");
    struct CryptoAuth_Session* sess2 =
        CryptoAuth_newSession(ca2, alloc, ca1->publicKey, NULL, false, "bench");

    int size = 1500;
    int count = 100000;
    struct Message* msg = Message_new(size, 256, alloc);
    Random_bytes(ctx->rand, msg->bytes, msg->length);

    // setup session
    for (int i = 0; i < 2; i++) {
        Assert_true(!CryptoAuth_encrypt(sess1, msg));
        Assert_true(!CryptoAuth_decrypt(sess2, msg));
        Assert_true(!CryptoAuth_encrypt(sess2, msg));
        Assert_true(!CryptoAuth_decrypt(sess1, msg));
    }

    begin(ctx, "salsa20/poly1305", (count * size * 8) / 1024, "kilobits");
    for (int i = 0; i < count; i++) {
        Assert_true(!CryptoAuth_encrypt(sess1, msg));
        Assert_true(!CryptoAuth_decrypt(sess2, msg));
    }
    done(ctx);
    Allocator_free(alloc);
}
Ejemplo n.º 12
0
int main()
{
    uint16_t randomShorts[8192];
    uint16_t out[8192];
    struct ReplayProtector rp = {0,0};

    struct Allocator* alloc;
    BufferAllocator_STACK(alloc, 1024);

    struct Random* rand = Random_new(alloc, NULL, NULL);

    Random_bytes(rand, (uint8_t*)randomShorts, sizeof(randomShorts));

    uint32_t outIdx = 0;
    for (uint32_t i = 0; i < 1024; i++) {
        if (ReplayProtector_checkNonce((randomShorts[i] % (i + 20)), &rp)) {
            out[outIdx] = (randomShorts[i] % (i + 20));
            outIdx++;
        }
    }

    for (uint32_t i = 0; i < outIdx; i++) {
        for (uint32_t j = i + 1; j < outIdx; j++) {
            Assert_always(out[i] != out[j]);
        }
    }

    return 0;
}
Ejemplo n.º 13
0
// Just make sure random crap doesn't crash it.
static void fuzzTest(struct Allocator* parent, struct Random* rand)
{
    struct Allocator* alloc = Allocator_child(parent);
    String* data = String_newBinary(NULL, Random_uint32(rand) % 1024, alloc);
    Random_bytes(rand, (uint8_t*)data->bytes, data->len);
    EncodingScheme_deserialize(data, alloc);
    Allocator_free(alloc);
}
Ejemplo n.º 14
0
int main()
{
    struct Allocator* alloc = MallocAllocator_new(1<<20);
    struct Random* rand = Random_new(alloc, NULL, NULL);

    // mock interface controller.
    struct Context ctx = {
        .ic = {
            .registerPeer = registerPeer,
            .getPeerState = getPeerState
        }
    };

    struct Interface externalIf = {
        .sendMessage = sendMessage,
        .allocator = alloc,
        .senderContext = &ctx
    };

    /*struct MultiInterface* mif = */MultiInterface_new(KEY_SIZE, &externalIf, &ctx.ic);

    struct Entry* entries = Allocator_malloc(alloc, sizeof(struct Entry) * ENTRY_COUNT);
    Random_bytes(rand, (uint8_t*)entries, ENTRY_COUNT * sizeof(struct Entry));

    struct Interface** ifaces = Allocator_calloc(alloc, sizeof(char*), ENTRY_COUNT);

    // seed the list with some near collisions.
    for (int i = 0; i < 10; i++) {
        int rnd = (((uint32_t*)entries)[i] >> 1) % ENTRY_COUNT;
        ((uint32_t*) (&entries[rnd]))[0] = ((uint32_t*) (&entries[i]))[0];
    }

    for (int i = 0; i < CYCLES; i++) {
        int rnd = ((uint32_t*)entries)[i] % ENTRY_COUNT;
        struct Entry* entry = &entries[rnd];
        struct Interface* iface = ifaces[rnd];

        struct Message* msg;
        Message_STACK(msg, 0, 128);

        Message_push(msg, "hello world", 12);
        Message_push(msg, entry, 16);

        externalIf.receiveMessage(msg, &externalIf);

        //printf("Received message for iface [%u] from [%p]\n", rnd, (void*)ctx.receivedOn);
        if (iface) {
            Assert_always(ctx.receivedOn == iface);
        } else {
            ifaces[rnd] = ctx.receivedOn;
        }
    }

    Allocator_free(alloc);
}
Ejemplo n.º 15
0
static void subscribe(Dict* args, void* vcontext, String* txid)
{
    struct AdminLog* log = (struct AdminLog*) vcontext;
    String* levelName = Dict_getString(args, String_CONST("level"));
    enum Log_Level level = (levelName) ? Log_levelForName(levelName->bytes) : Log_Level_DEBUG;
    int64_t* lineNumPtr = Dict_getInt(args, String_CONST("line"));
    String* fileStr = Dict_getString(args, String_CONST("file"));
    const char* file = (fileStr && fileStr->len > 0) ? fileStr->bytes : NULL;
    char* error = "2+2=5";
    if (level == Log_Level_INVALID) {
        level = Log_Level_KEYS;
    }
    if (lineNumPtr && *lineNumPtr < 0) {
        error = "Invalid line number, must be positive or 0 to signify any line is acceptable.";
    } else if (log->subscriptionCount >= MAX_SUBSCRIPTIONS) {
        error = "Max subscription count reached.";
    } else {
        struct Subscription* sub = &log->subscriptions[log->subscriptionCount];
        sub->level = level;
        sub->alloc = Allocator_child(log->alloc);
        if (file) {
            int i;
            for (i = 0; i < FILE_NAME_COUNT; i++) {
                if (log->fileNames[i] && !strcmp(log->fileNames[i], file)) {
                    file = log->fileNames[i];
                    sub->internalName = true;
                    break;
                }
            }
            if (i == FILE_NAME_COUNT) {
                file = String_new(file, sub->alloc)->bytes;
                sub->internalName = false;
            }
        }
        sub->file = file;
        sub->lineNum = (lineNumPtr) ? *lineNumPtr : 0;
        sub->txid = String_clone(txid, sub->alloc);
        Random_bytes(log->rand, (uint8_t*) sub->streamId, 8);
        uint8_t streamIdHex[20];
        Hex_encode(streamIdHex, 20, sub->streamId, 8);
        Dict response = Dict_CONST(
            String_CONST("error"), String_OBJ(String_CONST("none")), Dict_CONST(
            String_CONST("streamId"), String_OBJ(String_CONST((char*)streamIdHex)), NULL
        ));
        Admin_sendMessage(&response, txid, log->admin);
        log->subscriptionCount++;
        return;
    }

    Dict response = Dict_CONST(
        String_CONST("error"), String_OBJ(String_CONST(error)), NULL
    );
    Admin_sendMessage(&response, txid, log->admin);
}
Ejemplo n.º 16
0
int main()
{
    struct Allocator* alloc = MallocAllocator_new(1024);
    struct Random* rand = Random_new(alloc, NULL, NULL);

    FILE* tmp = tmpfile();
    uint8_t buffer1[2048];
    size_t checkSize;
    Random_bytes(rand, buffer1, 2048);
    checkSize = fwrite(buffer1, 1, 2048, tmp);
    if (checkSize != 2048)
    {
        return 1;
    }

    uint8_t buffer2[1024];
    rewind(tmp);
    struct Reader* r = FileReader_new(tmp, alloc);

    Reader_read(r, buffer2, 128);
    Reader_skip(r, 128);
    Reader_read(r, buffer2+128, 128);
    Reader_skip(r, 512);
    Reader_read(r, buffer2+128+128, 256);
    Reader_skip(r, 300);
    Reader_read(r, buffer2+128+128+256, 128);

    Assert_true(r->bytesRead == 128+128+128+512+256+300+128);

    uint8_t* ptr1 = buffer1;
    uint8_t* ptr2 = buffer2;

    #define SKIP(x) ptr1 += x
    #define CMP(x) Assert_true(!Bits_memcmp(ptr1, ptr2, x)); ptr1 += x; ptr2 += x

    CMP(128);
    SKIP(128);
    CMP(128);
    SKIP(512);
    CMP(256);
    SKIP(300);
    CMP(128);

    Allocator_free(alloc);
    return 0;
}
Ejemplo n.º 17
0
int main()
{
    struct Allocator* stackAlloc;
    BufferAllocator_STACK(stackAlloc, 2048);
    struct Random* rand = Random_new(stackAlloc, NULL, NULL);

    for (int cycles = 0; cycles < CYCLES; cycles++) {
        struct Allocator* alloc = MallocAllocator_new(1<<18);
        struct Map_OfLongsByInteger* map = Map_OfLongsByInteger_new(alloc);
        uint32_t size;
        Random_bytes(rand, (uint8_t*) &size, 4);
        size = (size % 4096) + 101;

        uint32_t key = 3;
        uint64_t val = 4;
        for (uint32_t i = 0; i < size; i++) {
            Map_OfLongsByInteger_put(&key, &val, map);
            key += val >> 13 ^ size << 19;
            val += key >> 19 ^ i << 13;
        }

        // If a key is duplicated, the entry will br replaced.
        size = map->count;

        for (uint32_t i = size - 1; i > size - 100; i--) {
            int index = map->keys[i] % size;
            uint32_t handle = map->handles[index];
            if (index != Map_OfLongsByInteger_indexForHandle(handle, map)) {
                uint32_t num = 0;
                for (int i = 0; i < (int)map->count; i++) {
                    if (num > map->handles[i]) {
                        Assert_true(!"map out of order");
                    }
                    num = map->handles[i];
                }
                printf("failed to find the correct index for the handle "
                       "handle[%u], index[%u], indexForHandle[%u]\n",
                       handle, index, Map_OfLongsByInteger_indexForHandle(handle, map));
                Assert_true(false);
            }
        }
        Allocator_free(alloc);
    }
}
Ejemplo n.º 18
0
static void randomForm(struct EncodingScheme_Form* form, struct Random* rand)
{
    for (;;) {
        Random_bytes(rand, (uint8_t*)form, sizeof(struct EncodingScheme_Form));
        //Bits_memset(form, 0xff, sizeof(struct EncodingScheme_Form));
        form->bitCount &= ((1<<5)-1);
        if (!form->bitCount) {
            form->bitCount++;
        }
        form->prefixLen &= ((1<<5)-1);
        if (!form->prefixLen) {
            form->prefixLen++;
        }
        if (EncodingScheme_formSize(form) > 59) { continue; }
        if (form->prefixLen > 3 && (form->prefix & 0xf) == 1) { continue; }
        break;
    }
    form->prefix &= ((((uint64_t)1)<<form->prefixLen)-1);
}
Ejemplo n.º 19
0
static int genAddress(uint8_t addressOut[40],
                      uint8_t privateKeyHexOut[65],
                      uint8_t publicKeyBase32Out[53],
                      struct Random* rand)
{
    struct Address address;
    uint8_t privateKey[32];

    for (;;) {
        Random_bytes(rand, privateKey, 32);
        crypto_scalarmult_curve25519_base(address.key, privateKey);
        // Brute force for keys until one matches FC00:/8
        if (AddressCalc_addressForPublicKey(address.ip6.bytes, address.key)) {
            Hex_encode(privateKeyHexOut, 65, privateKey, 32);
            Base32_encode(publicKeyBase32Out, 53, address.key, 32);
            Address_printIp(addressOut, &address);
            return 0;
        }
    }
}
Ejemplo n.º 20
0
int main()
{
    struct Allocator* alloc;
    BufferAllocator_STACK(alloc, 512);
    struct Random* rand = Random_new(alloc, NULL);

    uint8_t bytes[32];
    Random_bytes(rand, bytes, 32);

    uint8_t base32[64];
    Bits_memset(base32, 0, 64);

    Assert_always(Base32_encode(base32, 64, bytes, 32) == 52);

    //printf("base32 encoded: %s\n", base32);

    uint8_t bytes2[32];
    Assert_always(Base32_decode(bytes2, 32, base32, 52) == 32);

    Assert_always(Bits_memcmp(bytes, bytes2, 32) == 0);
}
Ejemplo n.º 21
0
int main(int argc, char** argv)
{
    struct Allocator* alloc = MallocAllocator_new(1<<22);
    struct Random* rand = Random_new(alloc, NULL, NULL);

    uint8_t privateKey[32];
    uint8_t publicKey[32];
    uint8_t ip[16];
    uint8_t hexPrivateKey[65];
    uint8_t printedIp[40];

    for (;;) {
        Random_bytes(rand, privateKey, 32);
        crypto_scalarmult_curve25519_base(publicKey, privateKey);
        if (AddressCalc_addressForPublicKey(ip, publicKey)) {
            Hex_encode(hexPrivateKey, 65, privateKey, 32);
            AddrTools_printIp(printedIp, ip);
            printf("%s %s\n", hexPrivateKey, printedIp);
        }
    }
    return 0;
}
Ejemplo n.º 22
0
int main()
{
    struct Allocator* alloc = MallocAllocator_new(20000);
    struct Random* rand = Random_new(alloc, NULL, NULL);

    uint8_t bytes[32];
    Random_bytes(rand, bytes, 32);

    uint8_t hex[65] = {0};

    Assert_true(Hex_encode(hex, 65, bytes, 32) == 64);

    //printf("hex encoded: %s\n", hex);

    uint8_t bytes2[32];
    Assert_true(Hex_decode(bytes2, 32, hex, 64) == 32);

    Assert_true(Bits_memcmp(bytes, bytes2, 32) == 0);

    Allocator_free(alloc);
    return 0;
}
Ejemplo n.º 23
0
struct CryptoAuth* CryptoAuth_new(struct Allocator* allocator,
                                  const uint8_t* privateKey,
                                  struct event_base* eventBase,
                                  struct Log* logger,
                                  struct Random* rand)
{
    struct CryptoAuth_pvt* ca = allocator->calloc(sizeof(struct CryptoAuth_pvt), 1, allocator);
    ca->allocator = allocator;

    ca->passwords = allocator->calloc(sizeof(struct CryptoAuth_Auth), 256, allocator);
    ca->passwordCount = 0;
    ca->passwordCapacity = 256;
    ca->eventBase = eventBase;
    ca->logger = logger;
    ca->pub.resetAfterInactivitySeconds = CryptoAuth_DEFAULT_RESET_AFTER_INACTIVITY_SECONDS;
    ca->rand = rand;
    Identity_set(ca);

    if (privateKey != NULL) {
        Bits_memcpyConst(ca->privateKey, privateKey, 32);
    } else {
        Random_bytes(rand, ca->privateKey, 32);
    }
    crypto_scalarmult_curve25519_base(ca->pub.publicKey, ca->privateKey);

    #ifdef Log_KEYS
        uint8_t publicKeyHex[65];
        printHexKey(publicKeyHex, ca->pub.publicKey);
        uint8_t privateKeyHex[65];
        printHexKey(privateKeyHex, ca->privateKey);
        Log_keys(logger,
                  "Initialized CryptoAuth:\n    myPrivateKey=%s\n     myPublicKey=%s\n",
                  privateKeyHex,
                  publicKeyHex);
    #endif

    return &ca->pub;
}
Ejemplo n.º 24
0
int main()
{
    struct Allocator* alloc = MallocAllocator_new(20000);
    struct Random* rand = Random_new(alloc, NULL, NULL);

    uint8_t bytes[32];
    Random_bytes(rand, bytes, 32);

    uint8_t base32[64];
    Bits_memset(base32, 0, 64);

    Assert_always(Base32_encode(base32, 64, bytes, 32) == 52);

    //printf("base32 encoded: %s\n", base32);

    uint8_t bytes2[32];
    Assert_always(Base32_decode(bytes2, 32, base32, 52) == 32);

    Assert_always(Bits_memcmp(bytes, bytes2, 32) == 0);

    Allocator_free(alloc);
    return 0;
}
Ejemplo n.º 25
0
static void encryptHandshake(struct Message* message,
                             struct CryptoAuth_Session_pvt* session,
                             int setupMessage)
{
    Message_shift(message, sizeof(union CryptoHeader), NULL);

    union CryptoHeader* header = (union CryptoHeader*) message->bytes;

    // garbage the auth challenge and set the nonce which follows it
    Random_bytes(session->context->rand, (uint8_t*) &header->handshake.auth,
                 sizeof(union CryptoHeader_Challenge) + 24);

    // set the permanent key
    Bits_memcpyConst(&header->handshake.publicKey, session->context->pub.publicKey, 32);

    Assert_true(knowHerKey(session));

    uint8_t calculatedIp6[16];
    AddressCalc_addressForPublicKey(calculatedIp6, session->pub.herPublicKey);
    if (!Bits_isZero(session->pub.herIp6, 16)) {
        // If someone starts a CA session and then discovers the key later and memcpy's it into the
        // result of getHerPublicKey() then we want to make sure they didn't memcpy in an invalid
        // key.
        Assert_true(!Bits_memcmp(session->pub.herIp6, calculatedIp6, 16));
    }

    // Password auth
    uint8_t* passwordHash = NULL;
    uint8_t passwordHashStore[32];
    if (session->password != NULL) {
        hashPassword(passwordHashStore,
                     &header->handshake.auth,
                     session->login,
                     session->password,
                     session->authType);
        passwordHash = passwordHashStore;
    } else {
        header->handshake.auth.challenge.type = session->authType;
        header->handshake.auth.challenge.additional = 0;
    }

    // Set the session state
    header->nonce = Endian_hostToBigEndian32(session->nextNonce);

    if (session->nextNonce == 0 || session->nextNonce == 2) {
        // If we're sending a hello or a key
        // Here we make up a temp keypair
        Random_bytes(session->context->rand, session->ourTempPrivKey, 32);
        crypto_scalarmult_curve25519_base(session->ourTempPubKey, session->ourTempPrivKey);

        if (Defined(Log_KEYS)) {
            uint8_t tempPrivateKeyHex[65];
            Hex_encode(tempPrivateKeyHex, 65, session->ourTempPrivKey, 32);
            uint8_t tempPubKeyHex[65];
            Hex_encode(tempPubKeyHex, 65, session->ourTempPubKey, 32);
            Log_keys(session->context->logger, "Generating temporary keypair\n"
                                                "    myTempPrivateKey=%s\n"
                                                "     myTempPublicKey=%s\n",
                      tempPrivateKeyHex, tempPubKeyHex);
        }
    }

    Bits_memcpyConst(header->handshake.encryptedTempKey, session->ourTempPubKey, 32);

    if (Defined(Log_KEYS)) {
        uint8_t tempKeyHex[65];
        Hex_encode(tempKeyHex, 65, header->handshake.encryptedTempKey, 32);
        Log_keys(session->context->logger,
                  "Wrapping temp public key:\n"
                  "    %s\n",
                  tempKeyHex);
    }

    cryptoAuthDebug(session, "Sending %s%s packet",
                    ((session->nextNonce & 1) ? "repeat " : ""),
                    ((session->nextNonce < 2) ? "hello" : "key"));

    uint8_t sharedSecret[32];
    if (session->nextNonce < 2) {
        getSharedSecret(sharedSecret,
                        session->context->privateKey,
                        session->pub.herPublicKey,
                        passwordHash,
                        session->context->logger);

        session->isInitiator = true;

        Assert_true(session->nextNonce <= 1);
        session->nextNonce = 1;
    } else {
        // Handshake2
        // herTempPubKey was set by decryptHandshake()
        Assert_ifParanoid(!Bits_isZero(session->herTempPubKey, 32));
        getSharedSecret(sharedSecret,
                        session->context->privateKey,
                        session->herTempPubKey,
                        passwordHash,
                        session->context->logger);

        Assert_true(session->nextNonce <= 3);
        session->nextNonce = 3;

        if (Defined(Log_KEYS)) {
            uint8_t tempKeyHex[65];
            Hex_encode(tempKeyHex, 65, session->herTempPubKey, 32);
            Log_keys(session->context->logger,
                      "Using their temp public key:\n"
                      "    %s\n",
                      tempKeyHex);
        }
    }

    // Shift message over the encryptedTempKey field.
    Message_shift(message, 32 - CryptoHeader_SIZE, NULL);

    encryptRndNonce(header->handshake.nonce, message, sharedSecret);

    if (Defined(Log_KEYS)) {
        uint8_t sharedSecretHex[65];
        printHexKey(sharedSecretHex, sharedSecret);
        uint8_t nonceHex[49];
        Hex_encode(nonceHex, 49, header->handshake.nonce, 24);
        uint8_t cipherHex[65];
        printHexKey(cipherHex, message->bytes);
        Log_keys(session->context->logger,
                  "Encrypting message with:\n"
                  "    nonce: %s\n"
                  "   secret: %s\n"
                  "   cipher: %s\n",
                  nonceHex, sharedSecretHex, cipherHex);
    }

    // Shift it back -- encryptRndNonce adds 16 bytes of authenticator.
    Message_shift(message, CryptoHeader_SIZE - 32 - 16, NULL);
}
Ejemplo n.º 26
0
static uint8_t encryptHandshake(struct Message* message,
                                struct CryptoAuth_Wrapper* wrapper,
                                int setupMessage)
{
    Message_shift(message, sizeof(union Headers_CryptoAuth));

    union Headers_CryptoAuth* header = (union Headers_CryptoAuth*) message->bytes;

    // garbage the auth challenge and set the nonce which follows it
    Random_bytes(wrapper->context->rand, (uint8_t*) &header->handshake.auth,
                 sizeof(union Headers_AuthChallenge) + 24);

    // set the permanent key
    Bits_memcpyConst(&header->handshake.publicKey, wrapper->context->pub.publicKey, 32);

    if (!knowHerKey(wrapper)) {
        return genReverseHandshake(message, wrapper, header);
    }

    if (wrapper->bufferedMessage) {
        // We wanted to send a message but we didn't know the peer's key so we buffered it
        // and sent a connectToMe, this or it's reply was lost in the network.
        // Now we just discovered their key and we're sending a hello packet.
        // Lets send 2 hello packets instead and on one will attach our buffered message.

        // This can never happen when the machine is beyond the first hello packet because
        // it should have been sent either by this or in the recipet of a hello packet from
        // the other node.
        Assert_true(wrapper->nextNonce == 0);

        struct Message* bm = wrapper->bufferedMessage;
        wrapper->bufferedMessage = NULL;
        cryptoAuthDebug0(wrapper, "Sending buffered message");
        sendMessage(bm, &wrapper->externalInterface);
        Allocator_free(bm->alloc);
    }

    // Password auth
    uint8_t* passwordHash = NULL;
    struct CryptoAuth_Auth auth;
    if (wrapper->password != NULL) {
        passwordHash = hashPassword(&auth, wrapper->password, wrapper->authType);
        Bits_memcpyConst(header->handshake.auth.bytes,
                         &auth.challenge,
                         sizeof(union Headers_AuthChallenge));
    }
    header->handshake.auth.challenge.type = wrapper->authType;

    Headers_setPacketAuthRequired(&header->handshake.auth, wrapper->authenticatePackets);

    // This is a special packet which the user should never see.
    Headers_setSetupPacket(&header->handshake.auth, setupMessage);

    // Set the session state
    uint32_t sessionState_be = Endian_hostToBigEndian32(wrapper->nextNonce);
    header->nonce = sessionState_be;

    if (wrapper->nextNonce == 0 || wrapper->nextNonce == 2) {
        // If we're sending a hello or a key
        Random_bytes(wrapper->context->rand, wrapper->secret, 32);
        crypto_scalarmult_curve25519_base(header->handshake.encryptedTempKey,  wrapper->secret);

        #ifdef Log_KEYS
            uint8_t tempPrivateKeyHex[65];
            Hex_encode(tempPrivateKeyHex, 65, wrapper->secret, 32);
            uint8_t tempPubKeyHex[65];
            Hex_encode(tempPubKeyHex, 65, header->handshake.encryptedTempKey, 32);
            Log_keys(wrapper->context->logger, "Generating temporary keypair\n"
                                                "    myTempPrivateKey=%s\n"
                                                "     myTempPublicKey=%s\n",
                      tempPrivateKeyHex, tempPubKeyHex);
        #endif
        if (wrapper->nextNonce == 0) {
            Bits_memcpyConst(wrapper->tempKey, header->handshake.encryptedTempKey, 32);
        }
        #ifdef Log_DEBUG
            Assert_true(!Bits_isZero(header->handshake.encryptedTempKey, 32));
            Assert_true(!Bits_isZero(wrapper->secret, 32));
        #endif
    } else if (wrapper->nextNonce == 3) {
        // Dupe key
        // If nextNonce is 1 then we have our pubkey stored in wrapper->tempKey,
        // If nextNonce is 3 we need to recalculate it each time
        // because tempKey the final secret.
        crypto_scalarmult_curve25519_base(header->handshake.encryptedTempKey,
                                          wrapper->secret);
    } else {
        // Dupe hello
        // wrapper->nextNonce == 1
        // Our public key is cached in wrapper->tempKey so lets copy it out.
        Bits_memcpyConst(header->handshake.encryptedTempKey, wrapper->tempKey, 32);
    }
    #ifdef Log_KEYS
        uint8_t tempKeyHex[65];
        Hex_encode(tempKeyHex, 65, header->handshake.encryptedTempKey, 32);
        Log_keys(wrapper->context->logger,
                  "Wrapping temp public key:\n"
                  "    %s\n",
                  tempKeyHex);
    #endif

    cryptoAuthDebug(wrapper, "Sending %s%s packet",
                    ((wrapper->nextNonce & 1) ? "repeat " : ""),
                    ((wrapper->nextNonce < 2) ? "hello" : "key"));

    uint8_t sharedSecret[32];
    if (wrapper->nextNonce < 2) {
        getSharedSecret(sharedSecret,
                        wrapper->context->privateKey,
                        wrapper->herPerminentPubKey,
                        passwordHash,
                        wrapper->context->logger);

        wrapper->isInitiator = true;
        wrapper->nextNonce = 1;
    } else {
        // Handshake2 wrapper->tempKey holds her public temp key.
        // it was put there by receiveMessage()
        getSharedSecret(sharedSecret,
                        wrapper->context->privateKey,
                        wrapper->tempKey,
                        passwordHash,
                        wrapper->context->logger);
        wrapper->nextNonce = 3;

        #ifdef Log_KEYS
            uint8_t tempKeyHex[65];
            Hex_encode(tempKeyHex, 65, wrapper->tempKey, 32);
            Log_keys(wrapper->context->logger,
                      "Using their temp public key:\n"
                      "    %s\n",
                      tempKeyHex);
        #endif
    }

    // Shift message over the encryptedTempKey field.
    Message_shift(message, 32 - Headers_CryptoAuth_SIZE);

    encryptRndNonce(header->handshake.nonce, message, sharedSecret);

    #ifdef Log_KEYS
        uint8_t sharedSecretHex[65];
        printHexKey(sharedSecretHex, sharedSecret);
        uint8_t nonceHex[49];
        Hex_encode(nonceHex, 49, header->handshake.nonce, 24);
        uint8_t cipherHex[65];
        printHexKey(cipherHex, message->bytes);
        Log_keys(wrapper->context->logger,
                  "Encrypting message with:\n"
                  "    nonce: %s\n"
                  "   secret: %s\n"
                  "   cipher: %s\n",
                  nonceHex, sharedSecretHex, cipherHex);
    #endif
    #ifdef Log_DEBUG
        Assert_true(!Bits_isZero(header->handshake.encryptedTempKey, 32));
    #endif

    // Shift it back -- encryptRndNonce adds 16 bytes of authenticator.
    Message_shift(message, Headers_CryptoAuth_SIZE - 32 - 16);

    return wrapper->wrappedInterface->sendMessage(message, wrapper->wrappedInterface);
}
Ejemplo n.º 27
0
static struct Address* createAddress(int mostSignificantAddressSpaceByte, int* hops)
{
    uint64_t path = getPath(hops);
    struct Address address = { .path = 0 };

    if (!genKeys) {
        if ((int)(sizeof(KEYS) / sizeof(*KEYS)) < (nextKey + 1)) {
            missingKey();
        }
        Bits_memcpyConst(address.key, KEYS[nextKey], 32);
        if (AddressCalc_addressForPublicKey(address.ip6.bytes, address.key)
            && (mostSignificantAddressSpaceByte == -1
                || address.ip6.bytes[8] == mostSignificantAddressSpaceByte))
        {
            nextKey++;
            uint8_t publicKeyHex[65];
            Hex_encode(publicKeyHex, 65, address.key, 32);
            printf("created new key: [%s]\n", publicKeyHex);

            address.path = path;
            return Allocator_clone(alloc, &address);
        } else {
            uint8_t publicKeyHex[65];
            Hex_encode(publicKeyHex, 65, address.key, 32);
            printf("bad key: [%s]\n", publicKeyHex);
            if (address.ip6.ints.three) {
                uint8_t printedAddr[40];
                AddrTools_printIp(printedAddr, address.ip6.bytes);
                printf("addr: [%s]\n", printedAddr);
            }
                missingKey();
        }
    }

    for (;;) {
        Random_bytes(rand, address.key, 32);
        // Brute force for keys until one matches FC00:/8
        if (AddressCalc_addressForPublicKey(address.ip6.bytes, address.key)
            && (mostSignificantAddressSpaceByte == -1
                || address.ip6.bytes[8] == mostSignificantAddressSpaceByte))
        {

            uint8_t publicKeyHex[65];
            Hex_encode(publicKeyHex, 65, address.key, 32);
            printf("created new key: [%s]\n", publicKeyHex);

            address.path = path;
            return Allocator_clone(alloc, &address);
        }
    }
}

static struct Address* randomIp(int* hops)
{
    return createAddress(-1, hops);
}

// This creates a random address which is a peer
static struct Address* randomAddress()
{
    return randomIp((int[]){0,1}/*0x13*/);
}
Ejemplo n.º 28
0
static uint8_t encryptHandshake(struct Message* message, struct CryptoAuth_Wrapper* wrapper)
{
    Message_shift(message, sizeof(union Headers_CryptoAuth));

    union Headers_CryptoAuth* header = (union Headers_CryptoAuth*) message->bytes;

    // garbage the auth field to frustrate DPI and set the nonce (next 24 bytes after the auth)
    Random_bytes(wrapper->context->rand,
                 (uint8_t*) &header->handshake.auth,
                 sizeof(union Headers_AuthChallenge) + 24);
    Bits_memcpyConst(&header->handshake.publicKey, wrapper->context->pub.publicKey, 32);

    if (!knowHerKey(wrapper)) {
        return genReverseHandshake(message, wrapper, header);
    }

    // Password auth
    uint8_t* passwordHash = NULL;
    struct CryptoAuth_Auth auth;
    if (wrapper->password != NULL) {
        passwordHash = hashPassword(&auth, wrapper->password, wrapper->authType);
        Bits_memcpyConst(header->handshake.auth.bytes,
                         &auth.challenge,
                         sizeof(union Headers_AuthChallenge));
    }
    header->handshake.auth.challenge.type = wrapper->authType;

    Headers_setPacketAuthRequired(&header->handshake.auth, wrapper->authenticatePackets);

    // set the session state
    uint32_t sessionState_be = Endian_hostToBigEndian32(wrapper->nextNonce);
    header->nonce = sessionState_be;

    if (wrapper->nextNonce == 0 || wrapper->nextNonce == 2) {
        // If we're sending a hello or a key
        Random_bytes(wrapper->context->rand, wrapper->secret, 32);
        crypto_scalarmult_curve25519_base(header->handshake.encryptedTempKey,  wrapper->secret);

        #ifdef Log_KEYS
            uint8_t tempPrivateKeyHex[65];
            Hex_encode(tempPrivateKeyHex, 65, wrapper->secret, 32);
            uint8_t tempPubKeyHex[65];
            Hex_encode(tempPubKeyHex, 65, header->handshake.encryptedTempKey, 32);
            Log_keys(wrapper->context->logger, "Generating temporary keypair\n"
                                                "    myTempPrivateKey=%s\n"
                                                "     myTempPublicKey=%s\n",
                      tempPrivateKeyHex, tempPubKeyHex);
        #endif
        if (wrapper->nextNonce == 0) {
            Bits_memcpyConst(wrapper->tempKey, header->handshake.encryptedTempKey, 32);
        }
        #ifdef Log_DEBUG
            Assert_true(!Bits_isZero(header->handshake.encryptedTempKey, 32));
            Assert_true(!Bits_isZero(wrapper->secret, 32));
        #endif
    } else if (wrapper->nextNonce == 3) {
        // Dupe key
        // If nextNonce is 1 then we have our pubkey stored in wrapper->tempKey,
        // If nextNonce is 3 we need to recalculate it each time
        // because tempKey the final secret.
        crypto_scalarmult_curve25519_base(header->handshake.encryptedTempKey,
                                          wrapper->secret);
    } else {
        // Dupe hello
        // wrapper->nextNonce == 1
        // Our public key is cached in wrapper->tempKey so lets copy it out.
        Bits_memcpyConst(header->handshake.encryptedTempKey, wrapper->tempKey, 32);
    }
    #ifdef Log_KEYS
        uint8_t tempKeyHex[65];
        Hex_encode(tempKeyHex, 65, header->handshake.encryptedTempKey, 32);
        Log_keys(wrapper->context->logger,
                  "Wrapping temp public key:\n"
                  "    %s\n",
                  tempKeyHex);
    #endif

    uint8_t sharedSecret[32];
    if (wrapper->nextNonce < 2) {
        if (wrapper->nextNonce == 0) {
            cryptoAuthDebug0(wrapper, "Sending hello packet");
        } else {
            cryptoAuthDebug0(wrapper, "Sending repeat hello packet");
        }
        getSharedSecret(sharedSecret,
                        wrapper->context->privateKey,
                        wrapper->herPerminentPubKey,
                        passwordHash,
                        wrapper->context->logger);

        wrapper->isInitiator = true;
        wrapper->nextNonce = 1;
    } else {
        if (wrapper->nextNonce == 2) {
            cryptoAuthDebug0(wrapper, "Sending key packet");
        } else {
            cryptoAuthDebug0(wrapper, "Sending repeat key packet");
        }
        // Handshake2 wrapper->tempKey holds her public temp key.
        // it was put there by receiveMessage()
        getSharedSecret(sharedSecret,
                        wrapper->context->privateKey,
                        wrapper->tempKey,
                        passwordHash,
                        wrapper->context->logger);
        wrapper->nextNonce = 3;

        #ifdef Log_KEYS
            uint8_t tempKeyHex[65];
            Hex_encode(tempKeyHex, 65, wrapper->tempKey, 32);
            Log_keys(wrapper->context->logger,
                      "Using their temp public key:\n"
                      "    %s\n",
                      tempKeyHex);
        #endif
    }

    // Shift message over the encryptedTempKey field.
    Message_shift(message, 32 - Headers_CryptoAuth_SIZE);

    encryptRndNonce(header->handshake.nonce, message, sharedSecret);

    #ifdef Log_KEYS
        uint8_t sharedSecretHex[65];
        printHexKey(sharedSecretHex, sharedSecret);
        uint8_t nonceHex[49];
        Hex_encode(nonceHex, 49, header->handshake.nonce, 24);
        uint8_t cipherHex[65];
        printHexKey(cipherHex, message->bytes);
        Log_keys(wrapper->context->logger,
                  "Encrypting message with:\n"
                  "    nonce: %s\n"
                  "   secret: %s\n"
                  "   cipher: %s\n",
                  nonceHex, sharedSecretHex, cipherHex);
    #endif
    #ifdef Log_DEBUG
        Assert_true(!Bits_isZero(header->handshake.encryptedTempKey, 32));
    #endif

    // Shift it back -- encryptRndNonce adds 16 bytes of authenticator.
    Message_shift(message, Headers_CryptoAuth_SIZE - 32 - 16);

    return wrapper->wrappedInterface->sendMessage(message, wrapper->wrappedInterface);
}
Ejemplo n.º 29
0
static uint8_t encryptHandshake(struct Message* message,
                                struct CryptoAuth_Wrapper* wrapper,
                                int setupMessage)
{
    Message_shift(message, sizeof(union Headers_CryptoAuth), NULL);

    union Headers_CryptoAuth* header = (union Headers_CryptoAuth*) message->bytes;

    // garbage the auth challenge and set the nonce which follows it
    Random_bytes(wrapper->context->rand, (uint8_t*) &header->handshake.auth,
                 sizeof(union Headers_AuthChallenge) + 24);

    // set the permanent key
    Bits_memcpyConst(&header->handshake.publicKey, wrapper->context->pub.publicKey, 32);

    if (!knowHerKey(wrapper)) {
        return genReverseHandshake(message, wrapper, header);
    } else if (!Bits_isZero(wrapper->herIp6, 16)) {
        // If someone starts a CA session and then discovers the key later and memcpy's it into the
        // result of getHerPublicKey() then we want to make sure they didn't memcpy in an invalid
        // key.
        uint8_t calculatedIp6[16];
        AddressCalc_addressForPublicKey(calculatedIp6, wrapper->herPerminentPubKey);
        Assert_true(!Bits_memcmp(wrapper->herIp6, calculatedIp6, 16));
    }

    if (wrapper->bufferedMessage) {
        // We wanted to send a message but we didn't know the peer's key so we buffered it
        // and sent a connectToMe.
        // Now we just discovered their key and we're sending a hello packet.
        // Lets send 2 hello packets instead and on one will attach our buffered message.

        // This can never happen when the machine is beyond the first hello packet because
        // it should have been sent either by this or in the recipet of a hello packet from
        // the other node.
        Assert_true(wrapper->nextNonce == 0);

        struct Message* bm = wrapper->bufferedMessage;
        wrapper->bufferedMessage = NULL;
        cryptoAuthDebug0(wrapper, "Sending buffered message");
        sendMessage(bm, &wrapper->externalInterface);
        Allocator_free(bm->alloc);
    }

    // Password auth
    uint8_t* passwordHash = NULL;
    struct CryptoAuth_Auth auth;
    if (wrapper->password != NULL) {
        passwordHash = hashPassword(&auth, wrapper->password, wrapper->authType);
        Bits_memcpyConst(header->handshake.auth.bytes,
                         &auth.challenge,
                         sizeof(union Headers_AuthChallenge));
    }
    header->handshake.auth.challenge.type = wrapper->authType;

    // Packet authentication option is deprecated, it must always be enabled.
    Headers_setPacketAuthRequired(&header->handshake.auth, 1);

    // This is a special packet which the user should never see.
    Headers_setSetupPacket(&header->handshake.auth, setupMessage);

    // Set the session state
    uint32_t sessionState_be = Endian_hostToBigEndian32(wrapper->nextNonce);
    header->nonce = sessionState_be;

    if (wrapper->nextNonce == 0 || wrapper->nextNonce == 2) {
        // If we're sending a hello or a key
        // Here we make up a temp keypair
        Random_bytes(wrapper->context->rand, wrapper->ourTempPrivKey, 32);
        crypto_scalarmult_curve25519_base(wrapper->ourTempPubKey, wrapper->ourTempPrivKey);

        #ifdef Log_KEYS
            uint8_t tempPrivateKeyHex[65];
            Hex_encode(tempPrivateKeyHex, 65, wrapper->ourTempPrivKey, 32);
            uint8_t tempPubKeyHex[65];
            Hex_encode(tempPubKeyHex, 65, header->handshake.encryptedTempKey, 32);
            Log_keys(wrapper->context->logger, "Generating temporary keypair\n"
                                                "    myTempPrivateKey=%s\n"
                                                "     myTempPublicKey=%s\n",
                      tempPrivateKeyHex, tempPubKeyHex);
        #endif
    }

    Bits_memcpyConst(header->handshake.encryptedTempKey, wrapper->ourTempPubKey, 32);

    #ifdef Log_KEYS
        uint8_t tempKeyHex[65];
        Hex_encode(tempKeyHex, 65, header->handshake.encryptedTempKey, 32);
        Log_keys(wrapper->context->logger,
                  "Wrapping temp public key:\n"
                  "    %s\n",
                  tempKeyHex);
    #endif

    cryptoAuthDebug(wrapper, "Sending %s%s packet",
                    ((wrapper->nextNonce & 1) ? "repeat " : ""),
                    ((wrapper->nextNonce < 2) ? "hello" : "key"));

    uint8_t sharedSecret[32];
    if (wrapper->nextNonce < 2) {
        getSharedSecret(sharedSecret,
                        wrapper->context->privateKey,
                        wrapper->herPerminentPubKey,
                        passwordHash,
                        wrapper->context->logger);

        wrapper->isInitiator = true;

        Assert_true(wrapper->nextNonce <= 1);
        wrapper->nextNonce = 1;
    } else {
        // Handshake2
        // herTempPubKey was set by receiveMessage()
        Assert_ifParanoid(!Bits_isZero(wrapper->herTempPubKey, 32));
        getSharedSecret(sharedSecret,
                        wrapper->context->privateKey,
                        wrapper->herTempPubKey,
                        passwordHash,
                        wrapper->context->logger);

        Assert_true(wrapper->nextNonce <= 3);
        wrapper->nextNonce = 3;

        #ifdef Log_KEYS
            uint8_t tempKeyHex[65];
            Hex_encode(tempKeyHex, 65, wrapper->herTempPubKey, 32);
            Log_keys(wrapper->context->logger,
                      "Using their temp public key:\n"
                      "    %s\n",
                      tempKeyHex);
        #endif
    }

    // Shift message over the encryptedTempKey field.
    Message_shift(message, 32 - Headers_CryptoAuth_SIZE, NULL);

    encryptRndNonce(header->handshake.nonce, message, sharedSecret);

    #ifdef Log_KEYS
        uint8_t sharedSecretHex[65];
        printHexKey(sharedSecretHex, sharedSecret);
        uint8_t nonceHex[49];
        Hex_encode(nonceHex, 49, header->handshake.nonce, 24);
        uint8_t cipherHex[65];
        printHexKey(cipherHex, message->bytes);
        Log_keys(wrapper->context->logger,
                  "Encrypting message with:\n"
                  "    nonce: %s\n"
                  "   secret: %s\n"
                  "   cipher: %s\n",
                  nonceHex, sharedSecretHex, cipherHex);
    #endif

    // Shift it back -- encryptRndNonce adds 16 bytes of authenticator.
    Message_shift(message, Headers_CryptoAuth_SIZE - 32 - 16, NULL);

    return wrapper->wrappedInterface->sendMessage(message, wrapper->wrappedInterface);
}
Ejemplo n.º 30
0
int main()
{
    struct Allocator* mainAlloc = MallocAllocator_new(1<<20);
    struct Log* log = FileWriterLog_new(stdout, mainAlloc);
    struct Random* rand = Random_new(mainAlloc, log, NULL);
    struct Context* ctx = Allocator_malloc(mainAlloc, sizeof(struct Context));
    Identity_set(ctx);

    struct Interface iface = { .sendMessage = NULL };
    struct Interface* fi = FramingInterface_new(4096, &iface, mainAlloc);
    fi->receiveMessage = messageOut;
    fi->receiverContext = ctx;

    for (int i = 0; i < CYCLES; i++) {
        struct Allocator* alloc = Allocator_child(mainAlloc);
        // max frame size must be at least 5 so that at least 1 byte of data is sent.
        int maxFrameSize = ( Random_uint32(rand) % (MAX_FRAME_SZ - 1) ) + 1;
        int maxMessageSize = ( Random_uint32(rand) % (MAX_MSG_SZ - MIN_MSG_SZ) ) + MIN_MSG_SZ;
        Log_debug(log, "maxFrameSize[%d] maxMessageSize[%d]", maxFrameSize, maxMessageSize);
        ctx->alloc = alloc;
        ctx->messages = NULL;
        ctx->messageCount = 0;
        ctx->currentMessage = 0;

        // Create one huge message, then create lots of little frames inside of it
        // then split it up in random places and send the sections to the framing
        // interface.
        struct Message* msg = Message_new(WORK_BUFF_SZ, 0, alloc);

        Assert_true(WORK_BUFF_SZ == msg->length);
        Random_bytes(rand, msg->bytes, msg->length);
        Message_shift(msg, -WORK_BUFF_SZ, NULL);

        for (;;) {
            int len = Random_uint32(rand) % maxFrameSize;
            if (!len) {
                len++;
            }
            if (msg->padding < len + 4) {
                break;
            }
            Message_shift(msg, len, NULL);

            ctx->messageCount++;
            ctx->messages =
                Allocator_realloc(alloc, ctx->messages, ctx->messageCount * sizeof(char*));
            struct Message* om = ctx->messages[ctx->messageCount-1] = Message_new(len, 0, alloc);
            Bits_memcpy(om->bytes, msg->bytes, len);

            Message_push32(msg, len, NULL);
        }

        do {
            int nextMessageSize = Random_uint32(rand) % maxMessageSize;
            if (!nextMessageSize) {
                nextMessageSize++;
            }
            if (nextMessageSize > msg->length) {
                nextMessageSize = msg->length;
            }
            struct Allocator* msgAlloc = Allocator_child(alloc);
            struct Message* m = Message_new(nextMessageSize, 0, msgAlloc);
            Message_pop(msg, m->bytes, nextMessageSize, NULL);
            Interface_receiveMessage(&iface, m);
            Allocator_free(msgAlloc);
        } while (msg->length);

        Assert_true(ctx->messageCount == ctx->currentMessage);

        Allocator_free(alloc);
    }

    return 0;
}