static void _test_salsa20(salsa20_func *crypt, const struct tstring *key, const struct tstring *iv, const struct tstring *cleartext, const struct tstring *ciphertext) { struct salsa20_ctx ctx; uint8_t *data; unsigned length; ASSERT (cleartext->length == ciphertext->length); length = cleartext->length; ASSERT (iv->length == SALSA20_IV_SIZE); data = xalloc(length + 1); salsa20_set_key(&ctx, key->length, key->data); salsa20_set_iv(&ctx, iv->data); data[length] = 17; crypt(&ctx, length, data, cleartext->data); if (data[length] != 17) { fprintf(stderr, "Encrypt of %u bytes wrote too much!\nInput:", length); tstring_print_hex(cleartext); fprintf(stderr, "\n"); FAIL(); } if (!MEMEQ(length, data, ciphertext->data)) { fprintf(stderr, "Encrypt failed:\nInput:"); tstring_print_hex(cleartext); fprintf(stderr, "\nOutput: "); print_hex(length, data); fprintf(stderr, "\nExpected:"); tstring_print_hex(ciphertext); fprintf(stderr, "\n"); FAIL(); } salsa20_set_key(&ctx, key->length, key->data); salsa20_set_iv(&ctx, iv->data); crypt(&ctx, length, data, data); if (!MEMEQ(length, data, cleartext->data)) { fprintf(stderr, "Decrypt failed:\nInput:"); tstring_print_hex(ciphertext); fprintf(stderr, "\nOutput: "); print_hex(length, data); fprintf(stderr, "\nExpected:"); tstring_print_hex(cleartext); fprintf(stderr, "\n"); FAIL(); } free(data); }
static void test_salsa20(unsigned key_length, const uint8_t *key, const uint8_t *iv, unsigned length, const uint8_t *cleartext, const uint8_t *ciphertext) { struct salsa20_ctx ctx; uint8_t *data = xalloc(length + 1); salsa20_set_key(&ctx, key_length, key); salsa20_set_iv(&ctx, iv); data[length] = 17; salsa20_crypt(&ctx, length, data, cleartext); if (data[length] != 17) { fprintf(stderr, "Encrypt of %u bytes wrote too much!\nInput:", length); print_hex(length, cleartext); fprintf(stderr, "\n"); FAIL(); } if (!MEMEQ(length, data, ciphertext)) { fprintf(stderr, "Encrypt failed:\nInput:"); print_hex(length, cleartext); fprintf(stderr, "\nOutput: "); print_hex(length, data); fprintf(stderr, "\nExpected:"); print_hex(length, ciphertext); fprintf(stderr, "\n"); FAIL(); } salsa20_set_key(&ctx, key_length, key); salsa20_set_iv(&ctx, iv); salsa20_crypt(&ctx, length, data, data); if (!MEMEQ(length, data, cleartext)) { fprintf(stderr, "Decrypt failed:\nInput:"); print_hex(length, ciphertext); fprintf(stderr, "\nOutput: "); print_hex(length, data); fprintf(stderr, "\nExpected:"); print_hex(length, cleartext); fprintf(stderr, "\n"); FAIL(); } free(data); }
/* Initializes the nonce level random generator. * * the @nonce_key must be provided. * * @init must be non zero on first initialization, and * zero on any subsequent reinitializations. */ static int nonce_rng_init(struct nonce_ctx_st *ctx, uint8_t nonce_key[NONCE_KEY_SIZE], unsigned nonce_key_size, unsigned init) { uint8_t iv[8]; int ret; if (init == 0) { /* use the previous key to generate IV as well */ memset(iv, 0, sizeof(iv)); /* to prevent valgrind from whinning */ salsa20r12_crypt(&ctx->ctx, sizeof(iv), iv, iv); /* Add key continuity by XORing the new key with data generated * from the old key */ salsa20r12_crypt(&ctx->ctx, nonce_key_size, nonce_key, nonce_key); } else { ctx->forkid = _gnutls_get_forkid(); /* when initializing read the IV from the system randomness source */ ret = _rnd_get_system_entropy(iv, sizeof(iv)); if (ret < 0) return gnutls_assert_val(ret); } salsa20_set_key(&ctx->ctx, nonce_key_size, nonce_key); salsa20_set_iv(&ctx->ctx, iv); zeroize_key(nonce_key, nonce_key_size); ctx->counter = 0; return 0; }
static void test_salsa20_stream(const struct tstring *key, const struct tstring *iv, const struct tstring *ciphertext, const struct tstring *xor_ref) { struct salsa20_ctx ctx; uint8_t data[STREAM_LENGTH + 1]; uint8_t stream[STREAM_LENGTH + 1]; uint8_t xor[SALSA20_BLOCK_SIZE]; unsigned j; ASSERT (iv->length == SALSA20_IV_SIZE); ASSERT (ciphertext->length == 4*SALSA20_BLOCK_SIZE); ASSERT (xor_ref->length == SALSA20_BLOCK_SIZE); salsa20_set_key(&ctx, key->length, key->data); salsa20_set_iv(&ctx, iv->data); memset(stream, 0, STREAM_LENGTH + 1); salsa20_crypt(&ctx, STREAM_LENGTH, stream, stream); if (stream[STREAM_LENGTH]) { fprintf(stderr, "Stream of %d bytes wrote too much!\n", STREAM_LENGTH); FAIL(); } if (!MEMEQ (64, stream, ciphertext->data)) { fprintf(stderr, "Error failed, offset 0:\n"); fprintf(stderr, "\nOutput: "); print_hex(64, stream); fprintf(stderr, "\nExpected:"); print_hex(64, ciphertext->data); fprintf(stderr, "\n"); FAIL(); } if (!MEMEQ (128, stream + 192, ciphertext->data + 64)) { fprintf(stderr, "Error failed, offset 192:\n"); fprintf(stderr, "\nOutput: "); print_hex(128, stream + 192); fprintf(stderr, "\nExpected:"); print_hex(64, ciphertext->data + 64); fprintf(stderr, "\n"); FAIL(); } if (!MEMEQ (64, stream + 448, ciphertext->data + 192)) { fprintf(stderr, "Error failed, offset 448:\n"); fprintf(stderr, "\nOutput: "); print_hex(64, stream + 448); fprintf(stderr, "\nExpected:"); print_hex(64, ciphertext->data + 192); fprintf(stderr, "\n"); FAIL(); } memxor3 (xor, stream, stream + SALSA20_BLOCK_SIZE, SALSA20_BLOCK_SIZE); for (j = 2*SALSA20_BLOCK_SIZE; j < STREAM_LENGTH; j += SALSA20_BLOCK_SIZE) memxor (xor, stream + j, SALSA20_BLOCK_SIZE); if (!MEMEQ (SALSA20_BLOCK_SIZE, xor, xor_ref->data)) { fprintf(stderr, "Error failed, bad xor 448:\n"); fprintf(stderr, "\nOutput: "); print_hex(SALSA20_BLOCK_SIZE, xor); fprintf(stderr, "\nExpected:"); print_hex(SALSA20_BLOCK_SIZE, xor_ref->data); fprintf(stderr, "\n"); FAIL(); } for (j = 1; j <= STREAM_LENGTH; j++) { memset(data, 0, STREAM_LENGTH + 1); salsa20_set_iv(&ctx, iv->data); salsa20_crypt(&ctx, j, data, data); if (!MEMEQ(j, data, stream)) { fprintf(stderr, "Encrypt failed for length %u:\n", j); fprintf(stderr, "\nOutput: "); print_hex(j, data); fprintf(stderr, "\nExpected:"); print_hex(j, stream); fprintf(stderr, "\n"); FAIL(); } if (!memzero_p (data + j, STREAM_LENGTH + 1 - j)) { fprintf(stderr, "Encrypt failed for length %u, wrote too much:\n", j); fprintf(stderr, "\nOutput: "); print_hex(STREAM_LENGTH + 1 - j, data + j); fprintf(stderr, "\n"); FAIL(); } } }
static int wrap_nettle_cipher_setkey(void *_ctx, const void *key, size_t keysize) { struct nettle_cipher_ctx *ctx = _ctx; uint8_t des_key[DES3_KEY_SIZE]; switch (ctx->algo) { case GNUTLS_CIPHER_AES_128_GCM: case GNUTLS_CIPHER_AES_256_GCM: gcm_aes_set_key(&ctx->ctx.aes_gcm, keysize, key); break; case GNUTLS_CIPHER_CAMELLIA_128_GCM: case GNUTLS_CIPHER_CAMELLIA_256_GCM: _gcm_camellia_set_key(&ctx->ctx.camellia_gcm, keysize, key); break; case GNUTLS_CIPHER_AES_128_CBC: case GNUTLS_CIPHER_AES_192_CBC: case GNUTLS_CIPHER_AES_256_CBC: if (ctx->enc) aes_set_encrypt_key(ctx->ctx_ptr, keysize, key); else aes_set_decrypt_key(ctx->ctx_ptr, keysize, key); break; case GNUTLS_CIPHER_CAMELLIA_128_CBC: case GNUTLS_CIPHER_CAMELLIA_192_CBC: case GNUTLS_CIPHER_CAMELLIA_256_CBC: if (ctx->enc) camellia_set_encrypt_key(ctx->ctx_ptr, keysize, key); else camellia_set_decrypt_key(ctx->ctx_ptr, keysize, key); break; case GNUTLS_CIPHER_3DES_CBC: if (keysize != DES3_KEY_SIZE) { gnutls_assert(); return GNUTLS_E_INTERNAL_ERROR; } des_fix_parity(keysize, des_key, key); /* this fails on weak keys */ if (des3_set_key(ctx->ctx_ptr, des_key) != 1) { gnutls_assert(); return GNUTLS_E_INTERNAL_ERROR; } break; case GNUTLS_CIPHER_DES_CBC: if (keysize != DES_KEY_SIZE) { gnutls_assert(); return GNUTLS_E_INTERNAL_ERROR; } des_fix_parity(keysize, des_key, key); if (des_set_key(ctx->ctx_ptr, des_key) != 1) { gnutls_assert(); return GNUTLS_E_INTERNAL_ERROR; } break; case GNUTLS_CIPHER_ARCFOUR_128: case GNUTLS_CIPHER_ARCFOUR_40: arcfour_set_key(ctx->ctx_ptr, keysize, key); break; case GNUTLS_CIPHER_SALSA20_256: case GNUTLS_CIPHER_ESTREAM_SALSA20_256: salsa20_set_key(ctx->ctx_ptr, keysize, key); break; case GNUTLS_CIPHER_RC2_40_CBC: arctwo_set_key(ctx->ctx_ptr, keysize, key); break; default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } return 0; }