示例#1
0
文件: dfcrypt.c 项目: defuse/dfcrypt
int dfcrypt_decrypt(
    const dfcrypt_state_t *state,
    const unsigned char *ctxt,
    size_t ctxt_len_bytes,
    const unsigned char *message_number,
    unsigned char *ptxt_out
)
{
    const unsigned char *salt = ctxt;
    const unsigned char *nonce = ctxt + DFCRYPT_INTERNAL_SALT_BYTES;
    const unsigned char *encrypted = nonce + crypto_stream_chacha20_NONCEBYTES;
    const unsigned char *ciphertext_mac = ctxt + ctxt_len_bytes - DFCRYPT_INTERNAL_MAC_BYTES;

    unsigned char keys[DFCRYPT_INTERNAL_AKEY_BYTES + DFCRYPT_INTERNAL_EKEY_BYTES];
    const unsigned char *akey = keys;
    const unsigned char *ekey = keys + DFCRYPT_INTERNAL_AKEY_BYTES;

    unsigned char computed_mac[DFCRYPT_INTERNAL_MAC_BYTES];

    /* Derive the authentication and encryption keys. */
    assert(sizeof(keys) == 64);
    crypto_generichash_blake2b_salt_personal(
        keys,                   /* output */
        sizeof(keys),           /* output length */
        state->appseed,         /* input */
        state->appseed_length,  /* input length */
        state->key,             /* key */
        DFCRYPT_KEY_BYTES,      /* key length */
        salt,                   /* salt */
        message_number          /* personalization (can be NULL) */
    );

    /* Re-compute the MAC. */
    crypto_generichash_blake2b(
        computed_mac,                                   /* output */
        DFCRYPT_INTERNAL_MAC_BYTES,                     /* output length */
        ctxt,                                           /* input */
        ctxt_len_bytes - DFCRYPT_INTERNAL_MAC_BYTES,    /* input length */
        akey,                                           /* key */
        DFCRYPT_INTERNAL_AKEY_BYTES                     /* key length */
    );

    /* Check the MAC. */
    if (sodium_memcmp(computed_mac, ciphertext_mac, DFCRYPT_INTERNAL_MAC_BYTES) != 0) {
        return -1;
    }

    /* Decrypt the plaintext. */
    crypto_stream_chacha20_xor(
        ptxt_out,                                   /* output */
        encrypted,                                  /* input */
        ctxt_len_bytes - DFCRYPT_CIPHERTEXT_GROWTH, /* input length */
        nonce,                                      /* nonce */
        ekey                                        /* key */
    );

    return 0;
}
示例#2
0
文件: dfcrypt.c 项目: defuse/dfcrypt
void dfcrypt_encrypt(
    const dfcrypt_state_t *state,
    const unsigned char *ptxt,
    size_t ptxt_len_bytes,
    const unsigned char *message_number,
    unsigned char *ctxt_out
)
{
    unsigned char *salt = ctxt_out;
    unsigned char *nonce = ctxt_out + DFCRYPT_INTERNAL_SALT_BYTES;
    unsigned char *encrypted = nonce + crypto_stream_chacha20_NONCEBYTES;
    unsigned char *mac = encrypted + ptxt_len_bytes;

    unsigned char keys[DFCRYPT_INTERNAL_AKEY_BYTES + DFCRYPT_INTERNAL_EKEY_BYTES];
    const unsigned char *akey = keys;
    const unsigned char *ekey = keys + DFCRYPT_INTERNAL_AKEY_BYTES;

    /* Sample a random salt and nonce. */
    randombytes_buf(salt, DFCRYPT_INTERNAL_SALT_BYTES);
    randombytes_buf(nonce, crypto_stream_chacha20_NONCEBYTES);

    /* Derive the authentication and encryption keys. */
    assert(sizeof(keys) == 64);
    crypto_generichash_blake2b_salt_personal(
        keys,                   /* output */
        sizeof(keys),           /* output length */
        state->appseed,         /* input */
        state->appseed_length,  /* input length */
        state->key,             /* key */
        DFCRYPT_KEY_BYTES,      /* key length */
        salt,                   /* salt */
        message_number          /* personalization (can be NULL) */
    );

    /* Encrypt the ciphertext. */
    crypto_stream_chacha20_xor(
        encrypted,      /* output */
        ptxt,           /* input */
        ptxt_len_bytes, /* input length */
        nonce,          /* nonce */
        ekey            /* key */
    );

    /* Append the MAC. */
    crypto_generichash_blake2b(
        mac,                            /* output */
        DFCRYPT_INTERNAL_MAC_BYTES,     /* output length */
        ctxt_out,                       /* input */
        DFCRYPT_INTERNAL_SALT_BYTES +
        crypto_stream_chacha20_NONCEBYTES + ptxt_len_bytes, /* input length */
        akey,                           /* key */
        DFCRYPT_INTERNAL_AKEY_BYTES     /* key length */
    );
}
示例#3
0
int main(void)
{
#define MAXLEN 64
    crypto_generichash_blake2b_state st;
    unsigned char salt[crypto_generichash_blake2b_SALTBYTES]
        = { '5', 'b', '6', 'b', '4', '1', 'e', 'd',
            '9', 'b', '3', '4', '3', 'f', 'e', '0' };
    unsigned char personal[crypto_generichash_blake2b_PERSONALBYTES]
        = { '5', '1', '2', '6', 'f', 'b', '2', 'a',
            '3', '7', '4', '0', '0', 'd', '2', 'a' };
    unsigned char in[MAXLEN], out[crypto_generichash_blake2b_BYTES_MAX],
        k[crypto_generichash_blake2b_KEYBYTES_MAX];
    size_t h, i, j;

    for (h = 0; h < crypto_generichash_blake2b_KEYBYTES_MAX; ++h)
        k[h] = h;

    for (i = 0; i < MAXLEN; ++i) {
        in[i] = i;
        crypto_generichash_blake2b_init_salt_personal(
            &st, k, 1 + i % crypto_generichash_blake2b_KEYBYTES_MAX,
            1 + i % crypto_generichash_blake2b_BYTES_MAX, salt, personal);
        crypto_generichash_blake2b_update(&st, in, i);
        crypto_generichash_blake2b_final(
            &st, out, 1 + i % crypto_generichash_blake2b_BYTES_MAX);
        for (j = 0; j < 1 + i % crypto_generichash_blake2b_BYTES_MAX; ++j) {
            printf("%02x", (unsigned int)out[j]);
        }
        printf("\n");
    }

    memset(out, 0, sizeof out);
    crypto_generichash_blake2b_init_salt_personal(
        &st, k, 0U, crypto_generichash_blake2b_BYTES_MAX, salt, personal);
    crypto_generichash_blake2b_update(&st, in, MAXLEN);
    crypto_generichash_blake2b_final(&st, out,
                                     crypto_generichash_blake2b_BYTES_MAX);
    for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) {
        printf("%02x", (unsigned int)out[j]);
    }
    printf("\n");

    memset(out, 0, sizeof out);
    crypto_generichash_blake2b_init_salt_personal(
        &st, NULL, 1U, crypto_generichash_blake2b_BYTES_MAX, salt, personal);
    crypto_generichash_blake2b_update(&st, in, MAXLEN);
    crypto_generichash_blake2b_final(&st, out,
                                     crypto_generichash_blake2b_BYTES_MAX);
    for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) {
        printf("%02x", (unsigned int)out[j]);
    }
    printf("\n");

    memset(out, 0, sizeof out);
    crypto_generichash_blake2b_init_salt_personal(
        &st, k, crypto_generichash_blake2b_KEYBYTES_MAX,
    crypto_generichash_blake2b_BYTES_MAX, NULL, personal);
    crypto_generichash_blake2b_update(&st, in, MAXLEN);
    crypto_generichash_blake2b_final(&st, out,
                                     crypto_generichash_blake2b_BYTES_MAX);
    for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) {
        printf("%02x", (unsigned int)out[j]);
    }
    printf("\n");

    memset(out, 0, sizeof out);
    crypto_generichash_blake2b_init_salt_personal(
        &st, k, crypto_generichash_blake2b_KEYBYTES_MAX,
        crypto_generichash_blake2b_BYTES_MAX, salt, NULL);
    crypto_generichash_blake2b_update(&st, in, MAXLEN);
    assert(crypto_generichash_blake2b_final(
        &st, out, crypto_generichash_blake2b_BYTES_MAX + 1U) == -1);
    crypto_generichash_blake2b_final(
        &st, out, crypto_generichash_blake2b_BYTES_MAX);
    for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) {
        printf("%02x", (unsigned int)out[j]);
    }
    printf("\n");

    memset(out, 0, sizeof out);
    crypto_generichash_blake2b_salt_personal(
        out, crypto_generichash_blake2b_BYTES_MAX, in, MAXLEN,
        k, 0U, salt, personal);
    for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) {
        printf("%02x", (unsigned int)out[j]);
    }
    printf("\n");

    memset(out, 0, sizeof out);
    crypto_generichash_blake2b_salt_personal(
        out, crypto_generichash_blake2b_BYTES_MAX, in, MAXLEN,
        NULL, crypto_generichash_blake2b_KEYBYTES_MAX, salt, personal);
    for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) {
        printf("%02x", (unsigned int)out[j]);
    }
    printf("\n");

    memset(out, 0, sizeof out);
    crypto_generichash_blake2b_salt_personal(
        out, crypto_generichash_blake2b_BYTES_MAX, in, MAXLEN,
        k, crypto_generichash_blake2b_KEYBYTES_MAX, salt, personal);
    for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) {
        printf("%02x", (unsigned int)out[j]);
    }
    printf("\n");

    memset(out, 0, sizeof out);
    crypto_generichash_blake2b_salt_personal(
        out, crypto_generichash_blake2b_BYTES_MAX, in, MAXLEN,
        k, crypto_generichash_blake2b_KEYBYTES_MAX, NULL, personal);
    for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) {
        printf("%02x", (unsigned int)out[j]);
    }
    printf("\n");

    memset(out, 0, sizeof out);
    crypto_generichash_blake2b_salt_personal(
        out, crypto_generichash_blake2b_BYTES_MAX, in, MAXLEN,
        k, crypto_generichash_blake2b_KEYBYTES_MAX, salt, NULL);
    for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) {
        printf("%02x", (unsigned int)out[j]);
    }
    printf("\n");

    crypto_generichash_blake2b_init_salt_personal(&st, NULL, 0U, crypto_generichash_BYTES,
                                                  NULL, personal);
    crypto_generichash_blake2b_update(&st, in, MAXLEN);
    crypto_generichash_blake2b_final(&st, out, crypto_generichash_blake2b_BYTES_MAX);
    for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) {
        printf("%02x", (unsigned int)out[j]);
    }
    printf("\n");

    crypto_generichash_blake2b_init_salt_personal(&st, NULL, 0U, crypto_generichash_BYTES,
                                                  salt, NULL);
    crypto_generichash_blake2b_update(&st, in, MAXLEN);
    crypto_generichash_blake2b_final(&st, out, crypto_generichash_blake2b_BYTES_MAX);
    for (j = 0; j < crypto_generichash_blake2b_BYTES_MAX; ++j) {
        printf("%02x", (unsigned int)out[j]);
    }
    printf("\n");

    assert(crypto_generichash_blake2b_init_salt_personal(&st, k, sizeof k, 0U,
                                                         salt, personal) == -1);
    assert(crypto_generichash_blake2b_init_salt_personal(&st, k, sizeof k,
                                                         crypto_generichash_BYTES_MAX + 1U,
                                                         salt, personal) == -1);
    assert(crypto_generichash_blake2b_init_salt_personal(&st, k,
                                                         crypto_generichash_KEYBYTES_MAX + 1U,
                                                         sizeof out, salt, personal) == -1);

    assert(crypto_generichash_blake2b_salt_personal(out, 0U, in, MAXLEN,
                                                    k, sizeof k,
                                                    salt, personal) == -1);
    assert(crypto_generichash_blake2b_salt_personal(out, crypto_generichash_BYTES_MAX + 1U,
                                                    in, MAXLEN, k, sizeof k,
                                                    salt, personal) == -1);
    assert(crypto_generichash_blake2b_salt_personal(out, sizeof out, in, MAXLEN,
                                                    k, crypto_generichash_KEYBYTES_MAX + 1U,
                                                    salt, personal) == -1);
    assert(crypto_generichash_blake2b_init_salt_personal(&st, k, sizeof k, crypto_generichash_BYTES,
                                                         NULL, personal) == 0);
    assert(crypto_generichash_blake2b_init_salt_personal(&st, k, sizeof k, crypto_generichash_BYTES,
                                                         salt, NULL) == 0);
    return 0;
}