diff options
Diffstat (limited to '')
-rw-r--r-- | siv_nettle.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/siv_nettle.c b/siv_nettle.c new file mode 100644 index 0000000..d8f8b23 --- /dev/null +++ b/siv_nettle.c @@ -0,0 +1,156 @@ +/* + chronyd/chronyc - Programs for keeping computer clocks accurate. + + ********************************************************************** + * Copyright (C) Miroslav Lichvar 2019 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + ********************************************************************** + + ======================================================================= + + SIV ciphers using the Nettle library + */ + +#include "config.h" + +#include "sysincl.h" + +#ifdef HAVE_NETTLE_SIV_CMAC +#include <nettle/siv-cmac.h> +#else +#include "siv_nettle_int.c" +#endif + +#include "memory.h" +#include "siv.h" + +struct SIV_Instance_Record { + struct siv_cmac_aes128_ctx siv; + int key_set; +}; + +/* ================================================== */ + +SIV_Instance +SIV_CreateInstance(SIV_Algorithm algorithm) +{ + SIV_Instance instance; + + if (algorithm != AEAD_AES_SIV_CMAC_256) + return NULL; + + instance = MallocNew(struct SIV_Instance_Record); + instance->key_set = 0; + + return instance; +} + +/* ================================================== */ + +void +SIV_DestroyInstance(SIV_Instance instance) +{ + Free(instance); +} + +/* ================================================== */ + +int +SIV_GetKeyLength(SIV_Algorithm algorithm) +{ + assert(32 <= SIV_MAX_KEY_LENGTH); + + if (algorithm == AEAD_AES_SIV_CMAC_256) + return 32; + return 0; +} + +/* ================================================== */ + +int +SIV_SetKey(SIV_Instance instance, const unsigned char *key, int length) +{ + if (length != 32) + return 0; + + siv_cmac_aes128_set_key(&instance->siv, key); + + instance->key_set = 1; + + return 1; +} + +/* ================================================== */ + +int +SIV_GetTagLength(SIV_Instance instance) +{ + assert(SIV_DIGEST_SIZE <= SIV_MAX_TAG_LENGTH); + + return SIV_DIGEST_SIZE; +} + +/* ================================================== */ + +int +SIV_Encrypt(SIV_Instance instance, + const unsigned char *nonce, int nonce_length, + const void *assoc, int assoc_length, + const void *plaintext, int plaintext_length, + unsigned char *ciphertext, int ciphertext_length) +{ + if (!instance->key_set) + return 0; + + if (nonce_length < SIV_MIN_NONCE_SIZE || assoc_length < 0 || + plaintext_length < 0 || plaintext_length > ciphertext_length || + plaintext_length + SIV_DIGEST_SIZE != ciphertext_length) + return 0; + + assert(assoc && plaintext); + + siv_cmac_aes128_encrypt_message(&instance->siv, nonce_length, nonce, + assoc_length, assoc, + ciphertext_length, ciphertext, plaintext); + return 1; +} + +/* ================================================== */ + +int +SIV_Decrypt(SIV_Instance instance, + const unsigned char *nonce, int nonce_length, + const void *assoc, int assoc_length, + const unsigned char *ciphertext, int ciphertext_length, + void *plaintext, int plaintext_length) +{ + if (!instance->key_set) + return 0; + + if (nonce_length < SIV_MIN_NONCE_SIZE || assoc_length < 0 || + plaintext_length < 0 || plaintext_length > ciphertext_length || + plaintext_length + SIV_DIGEST_SIZE != ciphertext_length) + return 0; + + assert(assoc && plaintext); + + if (!siv_cmac_aes128_decrypt_message(&instance->siv, nonce_length, nonce, + assoc_length, assoc, + plaintext_length, plaintext, ciphertext)) + return 0; + + return 1; +} |