int main(void) { size_t clen; for (clen = 0; clen < 1000; ++clen) { crypto_auth_keygen(key); randombytes_buf(c, clen); crypto_auth(a, c, clen, key); if (crypto_auth_verify(a, c, clen, key) != 0) { printf("fail %u\n", (unsigned int) clen); return 100; } if (clen > 0) { c[rand() % clen] += 1 + (rand() % 255); if (crypto_auth_verify(a, c, clen, key) == 0) { printf("forgery %u\n", (unsigned int) clen); return 100; } a[rand() % sizeof a] += 1 + (rand() % 255); if (crypto_auth_verify(a, c, clen, key) == 0) { printf("forgery %u\n", (unsigned int) clen); return 100; } } } crypto_auth_keygen(key); crypto_auth(a, guard_page, 0U, key); assert(crypto_auth_verify(a, guard_page, 0U, key) == 0); return 0; }
void measure(void) { int i; int loop; int mlen; for (loop = 0;loop < LOOPS;++loop) { for (mlen = 0;mlen <= MAXTEST_BYTES;mlen += 1 + mlen / MGAP) { randombytes(k,crypto_auth_KEYBYTES); randombytes(m,mlen); randombytes(h,crypto_auth_BYTES); for (i = 0;i <= TIMINGS;++i) { cycles[i] = cpucycles(); crypto_auth(h,m,mlen,k); } for (i = 0;i < TIMINGS;++i) cycles[i] = cycles[i + 1] - cycles[i]; printentry(mlen,"cycles",cycles,TIMINGS); for (i = 0;i <= TIMINGS;++i) { cycles[i] = cpucycles(); crypto_auth_verify(h,m,mlen,k); } for (i = 0;i < TIMINGS;++i) cycles[i] = cycles[i + 1] - cycles[i]; printentry(mlen,"verify_cycles",cycles,TIMINGS); } } }
static nif_term_t salt_auth(nif_heap_t *hp, int argc, const nif_term_t argv[]) { /* salt_auth(Message, Secret_key) -> Authenticator. */ nif_bin_t ms; nif_bin_t sk; nif_bin_t au; if (argc != 2) return (BADARG); /* Unpack arguments ensuring they're suitably typed. */ if (! enif_inspect_iolist_as_binary(hp, argv[0], &ms)) return (BADARG); if (! enif_inspect_binary(hp, argv[1], &sk)) return (BADARG); /* Check constraints on size. */ if (ms.size < 1 || ms.size > SALT_MAX_MESSAGE_SIZE) return (BADARG); if (sk.size != crypto_auth_KEYBYTES) return (BADARG); /* Allocate space for authenticator. NB: Passing ENOMEM as BADARG. */ if (! enif_alloc_binary(crypto_auth_BYTES, &au)) return (BADARG); (void)crypto_auth(au.data, ms.data, ms.size, sk.data); return (enif_make_binary(hp, &au)); }
int crypto_auth_verify(const unsigned char *h, const unsigned char *in, unsigned long long inlen, const unsigned char *k) { unsigned char correct[32]; crypto_auth(correct,in,inlen,k); return crypto_verify_32(h,correct); }
int crypto_auth_verify(const unsigned char *h, const unsigned char *in, unsigned long long inlen, const unsigned char *k) { unsigned char correct[32]; crypto_auth(correct,in,inlen,k); return crypto_verify_32(h,correct) | (-(h == correct)) | sodium_memcmp(correct,h,32); }
i64 packet_sign(u8 *signed_data, u8 *key, u8 *data, i64 size) { if (!signed_data || !key || !data || size < IPV4_AND_UDP_HEADER_SIZE) { return -1; } crypto_auth(signed_data + IPV4_AND_UDP_HEADER_SIZE, data, size, key); //copy original packet into new packet memcpy(signed_data, data, IPV4_AND_UDP_HEADER_SIZE); memcpy(signed_data + IPV4_AND_UDP_HEADER_SIZE + SIGN_BYTES, data + IPV4_AND_UDP_HEADER_SIZE, size - IPV4_AND_UDP_HEADER_SIZE); return size + SIGN_BYTES; // Return new size }
/* * Derive a message key from a chain key. * * The chain and message keys have to be crypto_auth_BYTES long. * * MK = HMAC-Hash(CK, 0x00) * (chain_key as key, 0x00 as message) */ int derive_message_key( buffer_t * const message_key, const buffer_t * const chain_key) { //make sure assumptions about length are correct assert(crypto_auth_BYTES == crypto_auth_KEYBYTES); if ((chain_key->content_length != crypto_auth_BYTES) || (message_key->buffer_length < crypto_auth_BYTES)) { return -6; } message_key->content_length = crypto_auth_BYTES; const unsigned char input_message = 0x00; //message_key = HMAC-Hash(chain_key, 0x00) //and return status return crypto_auth(message_key->content, &input_message, 1, chain_key->content); }
/* * Derive the next chain key in a message chain. * * The chain keys have to be crypto_auth_BYTES long. * * CK_new = HMAC-Hash(CK_prev, 0x01) * (previous chain key as key, 0x01 as message) */ int derive_chain_key( buffer_t * const new_chain_key, const buffer_t * const previous_chain_key) { //make sure assumptions about length are correct assert(crypto_auth_BYTES == crypto_auth_KEYBYTES); if ((previous_chain_key->content_length != crypto_auth_BYTES) || (new_chain_key->buffer_length < crypto_auth_BYTES)) { return -6; } new_chain_key->content_length = crypto_auth_BYTES; const unsigned char input_message = 0x01; //new_chain_key = HMAC-Hash(previous_chain_key, 0x01) //and return status return crypto_auth(new_chain_key->content, &input_message, 1, previous_chain_key->content); }
int test_vectors() { #define MAXLEN 64 u8 in[MAXLEN], out[8], k[16]; int i; int ok = 1; for( i = 0; i < 16; ++i ) k[i] = i; for( i = 0; i < MAXLEN; ++i ) { in[i] = i; crypto_auth( out, in, i, k ); if ( memcmp( out, vectors[i], 8 ) ) { printf( "test vector failed for %d bytes\n", i ); ok = 0; } } return ok; }
const char *checksum_compute(void) { long long i; long long j; for (i = 0; i < CHECKSUM_BYTES; ++i) { long long mlen = i; long long klen = crypto_auth_KEYBYTES; long long hlen = crypto_auth_BYTES; for (j = -16; j < 0; ++j) h[j] = rand(); for (j = -16; j < 0; ++j) k[j] = rand(); for (j = -16; j < 0; ++j) m[j] = rand(); for (j = hlen; j < hlen + 16; ++j) h[j] = rand(); for (j = klen; j < klen + 16; ++j) k[j] = rand(); for (j = mlen; j < mlen + 16; ++j) m[j] = rand(); for (j = -16; j < hlen + 16; ++j) h2[j] = h[j]; for (j = -16; j < klen + 16; ++j) k2[j] = k[j]; for (j = -16; j < mlen + 16; ++j) m2[j] = m[j]; if (crypto_auth(h,m,mlen,k) != 0) return "crypto_auth returns nonzero"; for (j = -16; j < klen + 16; ++j) if (k[j] != k2[j]) return "crypto_auth overwrites k"; for (j = -16; j < mlen + 16; ++j) if (m[j] != m2[j]) return "crypto_auth overwrites m"; for (j = -16; j < 0; ++j) if (h[j] != h2[j]) return "crypto_auth writes before output"; for (j = hlen; j < hlen + 16; ++j) if (h[j] != h2[j]) return "crypto_auth writes after output"; for (j = -16; j < 0; ++j) h[j] = rand(); for (j = -16; j < 0; ++j) k[j] = rand(); for (j = -16; j < 0; ++j) m[j] = rand(); for (j = hlen; j < hlen + 16; ++j) h[j] = rand(); for (j = klen; j < klen + 16; ++j) k[j] = rand(); for (j = mlen; j < mlen + 16; ++j) m[j] = rand(); for (j = -16; j < hlen + 16; ++j) h2[j] = h[j]; for (j = -16; j < klen + 16; ++j) k2[j] = k[j]; for (j = -16; j < mlen + 16; ++j) m2[j] = m[j]; if (crypto_auth(m2,m2,mlen,k) != 0) return "crypto_auth returns nonzero"; for (j = 0; j < hlen; ++j) if (m2[j] != h[j]) return "crypto_auth does not handle m overlap"; for (j = 0; j < hlen; ++j) m2[j] = m[j]; if (crypto_auth(k2,m2,mlen,k2) != 0) return "crypto_auth returns nonzero"; for (j = 0; j < hlen; ++j) if (k2[j] != h[j]) return "crypto_auth does not handle k overlap"; for (j = 0; j < hlen; ++j) k2[j] = k[j]; if (crypto_auth_verify(h,m,mlen,k) != 0) return "crypto_auth_verify returns nonzero"; for (j = -16; j < hlen + 16; ++j) if (h[j] != h2[j]) return "crypto_auth overwrites h"; for (j = -16; j < klen + 16; ++j) if (k[j] != k2[j]) return "crypto_auth overwrites k"; for (j = -16; j < mlen + 16; ++j) if (m[j] != m2[j]) return "crypto_auth overwrites m"; crypto_hash_sha256(h2,h,hlen); for (j = 0; j < klen; ++j) k[j] ^= h2[j % 32]; if (crypto_auth(h,m,mlen,k) != 0) return "crypto_auth returns nonzero"; if (crypto_auth_verify(h,m,mlen,k) != 0) return "crypto_auth_verify returns nonzero"; crypto_hash_sha256(h2,h,hlen); for (j = 0; j < mlen; ++j) m[j] ^= h2[j % 32]; m[mlen] = h2[0]; } if (crypto_auth(h,m,CHECKSUM_BYTES,k) != 0) return "crypto_auth returns nonzero"; if (crypto_auth_verify(h,m,CHECKSUM_BYTES,k) != 0) return "crypto_auth_verify returns nonzero"; sodium_bin2hex(checksum, sizeof checksum, h, crypto_auth_BYTES); return 0; }
void doit(void) { crypto_auth(h,m,TUNE_BYTES,k); crypto_auth_verify(h,m,TUNE_BYTES,k); }