ChaCha20¶
Encrypt¶
To test a function that encrypts with ChaCha20 only, its name must conform to the following convention:
CC_ChaCha20_encrypt
Its signature must be:
- int CC_ChaCha20_encrypt(
- uint8_t *ciphertext,
- const uint8_t *plaintext,
- size_t text_size,
- const uint8_t key[32],
- const uint8_t *nonce,
- size_t nonce_size,
- uint32_t init_counter,
- Parameters:
ciphertext – [Out] An allocated buffer to return the resulting ciphertext.
plaintext – [In] The plaintext to encrypt.
text_size – [In] The size of the plaintext and ciphertext buffers.
key – [In] The 32-byte key to use.
nonce – [In] The nonce.
nonce_size – [In] The size of the nonce in bytes.
init_counter – [In] An absolute position within the keystream in bytes to seek before encrypting.
- Returns:
A status value.
- Return values:
1 – OK.
0 – Failed to encrypt.
Example¶
#include <openssl/err.h>
#include <openssl/evp.h>
// TODO: We use EVP_chacha20_poly1305() for both, as the test vector for
// ChaCha20 has counter=1 and it seems that there is no way to set it in EVP.
// This works with the current test vector, but will break with other values of
// counter.
int CC_ChaCha20_encrypt(uint8_t *ciphertext, const uint8_t *plaintext,
size_t text_size, const uint8_t key[32],
const uint8_t *nonce, size_t nonce_size,
uint32_t init_counter) {
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
int len = 0;
if (!ctx)
goto error;
if (1 != EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, key, nonce))
goto error;
if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, text_size))
goto error;
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
goto error;
EVP_CIPHER_CTX_free(ctx);
return 1;
error:
ERR_print_errors_fp(stderr);
EVP_CIPHER_CTX_free(ctx);
return 0;
}
Compile with:
gcc -fPIC -shared -o chacha20_openssl_encrypt.so chacha20_openssl_encrypt.c -lssl -lcrypto
Then test with:
crypto-condor-cli test harness chacha20_openssl_encrypt.so
Decrypt¶
To test a function that decrypts with ChaCha20 only, its name must conform to the following convention:
CC_ChaCha20_decrypt
Its signature must be:
- void CC_ChaCha20_decrypt(
- uint8_t *plaintext,
- const uint8_t *ciphertext,
- size_t text_size,
- const uint8_t key[32],
- const uint8_t *nonce,
- size_t nonce_size,
- uint64_t init_counter,
- Parameters:
plaintext – [out] an allocated buffer to return the resulting plaintext.
ciphertext – [in] the ciphertext to decrypt.
text_size – [in] the size of the plaintext and ciphertext buffers.
key – [In] The 32-byte key to use.
nonce – [In] The nonce.
nonce_size – [In] The size of the nonce in bytes.
init_counter – [In] An absolute position within the keystream in bytes to seek before encrypting.
- Returns:
A status value.
- Return values:
1 – OK.
0 – Failed to decrypt.
Example¶
#include <openssl/err.h>
#include <openssl/evp.h>
// TODO: We use EVP_chacha20_poly1305() for both, as the test vector for
// ChaCha20 has counter=1 and it seems that there is no way to set it in EVP.
// This works with the current test vector, but will break with other values of
// counter.
int CC_ChaCha20_decrypt(uint8_t *plaintext, const uint8_t *ciphertext,
size_t text_size, const uint8_t key[32],
const uint8_t *nonce, size_t nonce_size,
uint64_t init_counter) {
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
int len = 0;
if (!ctx)
goto error;
if (1 != EVP_DecryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, key, nonce))
goto error;
if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, text_size))
goto error;
if (1 != EVP_DecryptFinal_ex(ctx, plaintext + len, &len))
goto error;
EVP_CIPHER_CTX_free(ctx);
return 1;
error:
ERR_print_errors_fp(stderr);
EVP_CIPHER_CTX_free(ctx);
return 0;
}
Compile with:
gcc -fPIC -shared -o chacha20_openssl_decrypt.so chacha20_openssl_decrypt.c -lssl -lcrypto
Then test with:
crypto-condor-cli test harness chacha20_openssl_decrypt.so
Encrypt with Poly1305¶
To test a function that encrypts with ChaCha20-Poly1305, its name must conform to the following convention:
CC_ChaCha20_encrypt_poly
Its signature must be:
- int CC_ChaCha20_encrypt_poly(
- uint8_t *ciphertext,
- uint8_t mac[16],
- const uint8_t *plaintext,
- size_t text_size,
- const uint8_t key[32],
- const uint8_t *nonce,
- size_t nonce_size,
- const uint8_t *aad,
- size_t aad_size,
- Parameters:
ciphertext – [Out] An allocated buffer to return the resulting ciphertext.
mac – [Out] buffer to store the resulting 16-byte MAC tag.
plaintext – [In] The plaintext to encrypt.
text_size – [In] The size of the plaintext and ciphertext buffers.
key – [In] The 32-byte key to use.
nonce – [In] The nonce.
nonce_size – [In] The size of the nonce in bytes.
aad – [In] The optional associated data. NULL if not used.
aad_size – [In] The size of the associated data in bytes. 0 if not used.
- Returns:
A status value.
- Return values:
1 – OK.
0 – Failed to encrypt.
Example¶
#include <openssl/err.h>
#include <openssl/evp.h>
int CC_ChaCha20_encrypt_poly(uint8_t *ciphertext, uint8_t mac[16],
const uint8_t *plaintext, size_t text_size,
const uint8_t key[32], const uint8_t *nonce,
size_t nonce_size, const uint8_t *aad,
size_t aad_size) {
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
int len = 0;
// Adhere to the RFC 7539 version with 12-byte nonces.
if (nonce_size != 12)
goto error;
if (!ctx)
goto error;
if (1 != EVP_EncryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, key, nonce))
goto error;
if (aad_size > 0) {
if (1 != EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_size))
goto error;
}
if (1 != EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, text_size))
goto error;
if (1 != EVP_EncryptFinal_ex(ctx, ciphertext + len, &len))
goto error;
if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, mac))
goto error;
EVP_CIPHER_CTX_free(ctx);
return 1;
error:
ERR_print_errors_fp(stderr);
EVP_CIPHER_CTX_free(ctx);
return 0;
}
Compile with:
gcc -fPIC -shared -o chacha20_poly1305_openssl_encrypt.so chacha20_poly1305_openssl_encrypt.c -lssl -lcrypto
Then test with:
crypto-condor-cli test harness chacha20_poly1305_openssl_encrypt.so
Decrypt with Poly1305¶
To test a function that decrypts with ChaCha20-Poly1305, its name must conform to the following convention:
CC_ChaCha20_poly1305_decrypt
Its signature must be:
- int CC_ChaCha20_decrypt_poly(
- uint8_t *plaintext,
- const uint8_t *ciphertext,
- size_t text_size,
- const uint8_t key[32],
- const uint8_t mac[16],
- const uint8_t *nonce,
- size_t nonce_size,
- const uint8_t *aad,
- size_t aad_size,
- Parameters:
plaintext – [out] an allocated buffer to return the resulting plaintext.
ciphertext – [in] the ciphertext to decrypt.
text_size – [in] the size of the plaintext and ciphertext buffers.
key – [In] The 32-byte symmetric key.
mac – [In] The 16-byte MAC tag to verify.
nonce – [In] The nonce.
nonce_size – [In] The size of the nonce in bytes.
aad – [In] The optional associated data. NULL if not used.
aad_size – [In] The size of the associated data. 0 if not used.
- Returns:
A status value.
- Return values:
1 – OK.
0 – The MAC verification failed.
-1 – Failed to decrypt.
Example¶
#include <openssl/err.h>
#include <openssl/evp.h>
int CC_ChaCha20_decrypt_poly(uint8_t *plaintext, const uint8_t *ciphertext,
size_t text_size, const uint8_t key[32],
const uint8_t mac[16], const uint8_t *nonce,
size_t nonce_size, const uint8_t *aad,
size_t aad_size) {
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
int len = 0, ret = 0;
// Adhere to the RFC 7539 version with 12-byte nonces.
if (nonce_size != 12)
goto error;
if (!ctx)
goto error;
if (1 != EVP_DecryptInit_ex(ctx, EVP_chacha20_poly1305(), NULL, key, nonce))
goto error;
if (aad_size > 0) {
if (1 != EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_size))
goto error;
}
if (1 != EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, text_size))
goto error;
if (1 != EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, 16, (void *)mac))
goto error;
ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
EVP_CIPHER_CTX_free(ctx);
return ret;
error:
ERR_print_errors_fp(stderr);
EVP_CIPHER_CTX_free(ctx);
return -1;
}
Compile with:
gcc -fPIC -shared -o chacha20_poly1305_openssl_decrypt.so chacha20_poly1305_openssl_decrypt.c -lssl -lcrypto
Then test with:
crypto-condor-cli test harness chacha20_poly1305_openssl_decrypt.so