diff --git a/src/boxes/ltc_cryptobox_create.c b/src/boxes/ltc_cryptobox_create.c new file mode 100644 index 00000000..401a501a --- /dev/null +++ b/src/boxes/ltc_cryptobox_create.c @@ -0,0 +1,96 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#include "tomcrypt_private.h" + +/** + @file ltc_cryptobox_create.c + libsodium-compatible crypto_box encryption helpers +*/ + +#if defined(LTC_XSALSA20) && defined(LTC_POLY1305) && defined(LTC_CURVE25519) && defined(LTC_BLAKE2B) + +/** + Encrypt a message with crypto_box using imported X25519 keys + @param msg The plaintext message to authenticate and encrypt + @param msglen The length of the plaintext message in octets + @param nonce The nonce to use for XSalsa20-Poly1305, must be 24 octets + @param noncelen The length of the nonce, must be LTC_SECRETBOX_NONCELEN + @param pk The recipient public X25519 key as an initialized key object + @param sk The sender private X25519 key as an initialized key object + @param out [out] The destination for the 16-octet tag followed by ciphertext + @param outlen [in/out] Available out size on entry, bytes written or required on return + @return CRYPT_OK if successful +*/ +int ltc_cryptobox_create_ck(const unsigned char *msg, unsigned long msglen, + const unsigned char *nonce, unsigned long noncelen, + const curve25519_key *pk, + const curve25519_key *sk, + unsigned char *out, unsigned long *outlen) +{ + unsigned char shared[LTC_BOX_KEYLEN], symkey[LTC_BOX_KEYLEN]; + const unsigned char zero16[16] = {0}; + unsigned long shared_len = sizeof(shared); + int err; + + LTC_ARGCHK(msg != NULL); + LTC_ARGCHK(nonce != NULL); + LTC_ARGCHK(pk != NULL); + LTC_ARGCHK(sk != NULL); + LTC_ARGCHK(noncelen == LTC_SECRETBOX_NONCELEN); + if (pk->pka != LTC_PKA_X25519) return CRYPT_PK_INVALID_TYPE; + if (sk->pka != LTC_PKA_X25519) return CRYPT_PK_INVALID_TYPE; + if (sk->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE; + + if ((err = x25519_shared_secret(sk, pk, shared, &shared_len)) != CRYPT_OK) goto cleanup; + if ((err = xsalsa20_hsalsa20(symkey, sizeof(symkey), shared, shared_len, zero16, sizeof(zero16), 20)) != CRYPT_OK) goto cleanup; + err = ltc_secretbox_create(msg, msglen, nonce, noncelen, symkey, sizeof(symkey), out, outlen); + +cleanup: + zeromem(shared, sizeof(shared)); + zeromem(symkey, sizeof(symkey)); + return err; +} + +/** + Encrypt a message with crypto_box using raw 32-byte X25519 keys + @param msg The plaintext message to authenticate and encrypt + @param msglen The length of the plaintext message in octets + @param nonce The nonce to use for XSalsa20-Poly1305, must be 24 octets + @param noncelen The length of the nonce, must be LTC_SECRETBOX_NONCELEN + @param pk The recipient raw public X25519 key, must be 32 octets + @param pklen The length of the recipient public key, must be LTC_BOX_KEYLEN + @param sk The sender raw private X25519 key, must be 32 octets + @param sklen The length of the sender private key, must be LTC_BOX_KEYLEN + @param out [out] The destination for the 16-octet tag followed by ciphertext + @param outlen [in/out] Available out size on entry, bytes written or required on return + @return CRYPT_OK if successful +*/ +int ltc_cryptobox_create(const unsigned char *msg, unsigned long msglen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *pk, unsigned long pklen, + const unsigned char *sk, unsigned long sklen, + unsigned char *out, unsigned long *outlen) +{ + curve25519_key sender_sk, recipient_pk; + int err; + + LTC_ARGCHK(msg != NULL); + LTC_ARGCHK(nonce != NULL); + LTC_ARGCHK(pk != NULL); + LTC_ARGCHK(sk != NULL); + LTC_ARGCHK(noncelen == LTC_SECRETBOX_NONCELEN); + LTC_ARGCHK(pklen == LTC_BOX_KEYLEN); + LTC_ARGCHK(sklen == LTC_BOX_KEYLEN); + + if ((err = x25519_import_raw(sk, sklen, PK_PRIVATE, &sender_sk)) != CRYPT_OK) return err; + if ((err = x25519_import_raw(pk, pklen, PK_PUBLIC, &recipient_pk)) != CRYPT_OK) goto cleanup; + err = ltc_cryptobox_create_ck(msg, msglen, nonce, noncelen, &recipient_pk, &sender_sk, out, outlen); + +cleanup: + zeromem(&sender_sk, sizeof(sender_sk)); + zeromem(&recipient_pk, sizeof(recipient_pk)); + return err; +} + +#endif diff --git a/src/boxes/ltc_cryptobox_open.c b/src/boxes/ltc_cryptobox_open.c new file mode 100644 index 00000000..27c1a6aa --- /dev/null +++ b/src/boxes/ltc_cryptobox_open.c @@ -0,0 +1,96 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#include "tomcrypt_private.h" + +/** + @file ltc_cryptobox_open.c + libsodium-compatible crypto_box decryption helpers +*/ + +#if defined(LTC_XSALSA20) && defined(LTC_POLY1305) && defined(LTC_CURVE25519) && defined(LTC_BLAKE2B) + +/** + Decrypt a crypto_box message using imported X25519 keys + @param enc The encrypted input, a 16-octet tag followed by ciphertext + @param enclen The length of the encrypted input in octets + @param nonce The nonce used for encryption, must be 24 octets + @param noncelen The length of the nonce, must be LTC_SECRETBOX_NONCELEN + @param pk The sender public X25519 key as an initialized key object + @param sk The recipient private X25519 key as an initialized key object + @param out [out] The destination for the decrypted plaintext + @param outlen [in/out] Available out size on entry, bytes written or required on return + @return CRYPT_OK if successful +*/ +int ltc_cryptobox_open_ck(const unsigned char *enc, unsigned long enclen, + const unsigned char *nonce, unsigned long noncelen, + const curve25519_key *pk, + const curve25519_key *sk, + unsigned char *out, unsigned long *outlen) +{ + unsigned char shared[LTC_BOX_KEYLEN], symkey[LTC_BOX_KEYLEN]; + const unsigned char zero16[16] = {0}; + unsigned long shared_len = sizeof(shared); + int err; + + LTC_ARGCHK(enc != NULL); + LTC_ARGCHK(nonce != NULL); + LTC_ARGCHK(pk != NULL); + LTC_ARGCHK(sk != NULL); + LTC_ARGCHK(noncelen == LTC_SECRETBOX_NONCELEN); + if (pk->pka != LTC_PKA_X25519) return CRYPT_PK_INVALID_TYPE; + if (sk->pka != LTC_PKA_X25519) return CRYPT_PK_INVALID_TYPE; + if (sk->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE; + + if ((err = x25519_shared_secret(sk, pk, shared, &shared_len)) != CRYPT_OK) goto cleanup; + if ((err = xsalsa20_hsalsa20(symkey, sizeof(symkey), shared, shared_len, zero16, sizeof(zero16), 20)) != CRYPT_OK) goto cleanup; + err = ltc_secretbox_open(enc, enclen, nonce, noncelen, symkey, sizeof(symkey), out, outlen); + +cleanup: + zeromem(shared, sizeof(shared)); + zeromem(symkey, sizeof(symkey)); + return err; +} + +/** + Decrypt a crypto_box message using raw 32-byte X25519 keys + @param enc The encrypted input, a 16-octet tag followed by ciphertext + @param enclen The length of the encrypted input in octets + @param nonce The nonce used for encryption, must be 24 octets + @param noncelen The length of the nonce, must be LTC_SECRETBOX_NONCELEN + @param pk The sender raw public X25519 key, must be 32 octets + @param pklen The length of the sender public key, must be LTC_BOX_KEYLEN + @param sk The recipient raw private X25519 key, must be 32 octets + @param sklen The length of the recipient private key, must be LTC_BOX_KEYLEN + @param out [out] The destination for the decrypted plaintext + @param outlen [in/out] Available out size on entry, bytes written or required on return + @return CRYPT_OK if successful +*/ +int ltc_cryptobox_open(const unsigned char *enc, unsigned long enclen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *pk, unsigned long pklen, + const unsigned char *sk, unsigned long sklen, + unsigned char *out, unsigned long *outlen) +{ + curve25519_key recipient_sk, sender_pk; + int err; + + LTC_ARGCHK(enc != NULL); + LTC_ARGCHK(nonce != NULL); + LTC_ARGCHK(pk != NULL); + LTC_ARGCHK(sk != NULL); + LTC_ARGCHK(noncelen == LTC_SECRETBOX_NONCELEN); + LTC_ARGCHK(pklen == LTC_BOX_KEYLEN); + LTC_ARGCHK(sklen == LTC_BOX_KEYLEN); + + if ((err = x25519_import_raw(sk, sklen, PK_PRIVATE, &recipient_sk)) != CRYPT_OK) return err; + if ((err = x25519_import_raw(pk, pklen, PK_PUBLIC, &sender_pk)) != CRYPT_OK) goto cleanup; + err = ltc_cryptobox_open_ck(enc, enclen, nonce, noncelen, &sender_pk, &recipient_sk, out, outlen); + +cleanup: + zeromem(&recipient_sk, sizeof(recipient_sk)); + zeromem(&sender_pk, sizeof(sender_pk)); + return err; +} + +#endif diff --git a/src/boxes/ltc_sealedbox_create.c b/src/boxes/ltc_sealedbox_create.c new file mode 100644 index 00000000..84c9cffb --- /dev/null +++ b/src/boxes/ltc_sealedbox_create.c @@ -0,0 +1,97 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#include "tomcrypt_private.h" + +/** + @file ltc_sealedbox_create.c + libsodium-compatible sealed box encryption helper +*/ + +#if defined(LTC_XSALSA20) && defined(LTC_POLY1305) && defined(LTC_CURVE25519) && defined(LTC_BLAKE2B) + +/** + Encrypt a message with a crypto_box sealed box using an imported recipient key + @param msg The plaintext message to encrypt for the recipient public key + @param msglen The length of the plaintext message in octets + @param pk The recipient public X25519 key as an initialized key object + @param prng An active PRNG state used to generate the ephemeral X25519 key + @param wprng The registered PRNG descriptor index matching prng + @param out [out] The destination for ephemeral public key || tag || ciphertext + @param outlen [in/out] Available out size on entry, bytes written or required on return + @return CRYPT_OK if successful +*/ +int ltc_sealedbox_create_ck(const unsigned char *msg, unsigned long msglen, + const curve25519_key *pk, + prng_state *prng, int wprng, + unsigned char *out, unsigned long *outlen) +{ + curve25519_key eph; + hash_state md; + unsigned char nonce[LTC_SECRETBOX_NONCELEN]; + unsigned long need; + unsigned long inner_outlen; + int err; + + LTC_ARGCHK(msg != NULL); + LTC_ARGCHK(pk != NULL); + LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(outlen != NULL); + if (pk->pka != LTC_PKA_X25519) return CRYPT_PK_INVALID_TYPE; + if (msglen > ULONG_MAX - LTC_SEALBOX_OVERHEAD) return CRYPT_OVERFLOW; + need = msglen + LTC_SEALBOX_OVERHEAD; + if (*outlen < need) { + *outlen = need; + return CRYPT_BUFFER_OVERFLOW; + } + LTC_ARGCHK(out != NULL); + *outlen = need; + + if ((err = x25519_make_key(prng, wprng, &eph)) != CRYPT_OK) return err; + + XMEMCPY(out, eph.pub, LTC_SEALBOX_PREAMBLE); + if ((err = blake2b_init(&md, sizeof(nonce), NULL, 0)) != CRYPT_OK) goto cleanup; + if ((err = blake2b_process(&md, eph.pub, LTC_SEALBOX_PREAMBLE)) != CRYPT_OK) goto cleanup; + if ((err = blake2b_process(&md, pk->pub, LTC_SEALBOX_PREAMBLE)) != CRYPT_OK) goto cleanup; + if ((err = blake2b_done(&md, nonce)) != CRYPT_OK) goto cleanup; + inner_outlen = *outlen - LTC_SEALBOX_PREAMBLE; + err = ltc_cryptobox_create_ck(msg, msglen, nonce, sizeof(nonce), pk, &eph, out + LTC_SEALBOX_PREAMBLE, &inner_outlen); + if (err == CRYPT_OK) *outlen = LTC_SEALBOX_PREAMBLE + inner_outlen; + +cleanup: + zeromem(&md, sizeof(md)); + zeromem(nonce, sizeof(nonce)); + zeromem(&eph, sizeof(eph)); + return err; +} + +/** + Encrypt a message with a crypto_box sealed box using a raw recipient key + @param msg The plaintext message to encrypt for the recipient public key + @param msglen The length of the plaintext message in octets + @param pk The recipient raw public X25519 key, must be 32 octets + @param pklen The length of the recipient public key, must be LTC_BOX_KEYLEN + @param prng An active PRNG state used to generate the ephemeral X25519 key + @param wprng The registered PRNG descriptor index matching prng + @param out [out] The destination for ephemeral public key || tag || ciphertext + @param outlen [in/out] Available out size on entry, bytes written or required on return + @return CRYPT_OK if successful +*/ +int ltc_sealedbox_create(const unsigned char *msg, unsigned long msglen, + const unsigned char *pk, unsigned long pklen, + prng_state *prng, int wprng, + unsigned char *out, unsigned long *outlen) +{ + curve25519_key recipient_pk; + int err; + + LTC_ARGCHK(pk != NULL); + LTC_ARGCHK(pklen == LTC_BOX_KEYLEN); + + if ((err = x25519_import_raw(pk, pklen, PK_PUBLIC, &recipient_pk)) != CRYPT_OK) return err; + err = ltc_sealedbox_create_ck(msg, msglen, &recipient_pk, prng, wprng, out, outlen); + zeromem(&recipient_pk, sizeof(recipient_pk)); + return err; +} + +#endif diff --git a/src/boxes/ltc_sealedbox_open.c b/src/boxes/ltc_sealedbox_open.c new file mode 100644 index 00000000..55ec1ca7 --- /dev/null +++ b/src/boxes/ltc_sealedbox_open.c @@ -0,0 +1,79 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#include "tomcrypt_private.h" + +/** + @file ltc_sealedbox_open.c + libsodium-compatible sealed box decryption helper +*/ + +#if defined(LTC_XSALSA20) && defined(LTC_POLY1305) && defined(LTC_CURVE25519) && defined(LTC_BLAKE2B) + +/** + Decrypt a crypto_box sealed box message using an imported recipient key + @param enc The encrypted sealed box: ephemeral public key || tag || ciphertext + @param enclen The length of the encrypted sealed box in octets + @param sk The recipient private X25519 key as an initialized key object + @param out [out] The destination for the decrypted plaintext + @param outlen [in/out] Available out size on entry, bytes written or required on return + @return CRYPT_OK if successful +*/ +int ltc_sealedbox_open_ck(const unsigned char *enc, unsigned long enclen, + const curve25519_key *sk, + unsigned char *out, unsigned long *outlen) +{ + curve25519_key eph_pk; + hash_state md; + unsigned char nonce[LTC_SECRETBOX_NONCELEN]; + int err; + + LTC_ARGCHK(enc != NULL); + LTC_ARGCHK(sk != NULL); + LTC_ARGCHK(enclen >= LTC_SEALBOX_OVERHEAD); + if (sk->pka != LTC_PKA_X25519) return CRYPT_PK_INVALID_TYPE; + if (sk->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE; + + if ((err = x25519_import_raw(enc, LTC_SEALBOX_PREAMBLE, PK_PUBLIC, &eph_pk)) != CRYPT_OK) return err; + if ((err = blake2b_init(&md, sizeof(nonce), NULL, 0)) != CRYPT_OK) goto cleanup; + if ((err = blake2b_process(&md, enc, LTC_SEALBOX_PREAMBLE)) != CRYPT_OK) goto cleanup; + if ((err = blake2b_process(&md, sk->pub, LTC_SEALBOX_PREAMBLE)) != CRYPT_OK) goto cleanup; + if ((err = blake2b_done(&md, nonce)) != CRYPT_OK) goto cleanup; + err = ltc_cryptobox_open_ck(enc + LTC_SEALBOX_PREAMBLE, enclen - LTC_SEALBOX_PREAMBLE, nonce, sizeof(nonce), &eph_pk, sk, out, outlen); + +cleanup: + zeromem(&md, sizeof(md)); + zeromem(&eph_pk, sizeof(eph_pk)); + zeromem(nonce, sizeof(nonce)); + return err; +} + +/** + Decrypt a crypto_box sealed box message using a raw recipient private key + @param enc The encrypted sealed box: ephemeral public key || tag || ciphertext + @param enclen The length of the encrypted sealed box in octets + @param sk The recipient raw private X25519 key, must be 32 octets + @param sklen The length of the recipient private key, must be LTC_BOX_KEYLEN + @param out [out] The destination for the decrypted plaintext + @param outlen [in/out] Available out size on entry, bytes written or required on return + @return CRYPT_OK if successful +*/ +int ltc_sealedbox_open(const unsigned char *enc, unsigned long enclen, + const unsigned char *sk, unsigned long sklen, + unsigned char *out, unsigned long *outlen) +{ + curve25519_key recipient_sk; + int err; + + LTC_ARGCHK(enc != NULL); + LTC_ARGCHK(sk != NULL); + LTC_ARGCHK(sklen == LTC_BOX_KEYLEN); + LTC_ARGCHK(enclen >= LTC_SEALBOX_OVERHEAD); + + if ((err = x25519_import_raw(sk, sklen, PK_PRIVATE, &recipient_sk)) != CRYPT_OK) return err; + err = ltc_sealedbox_open_ck(enc, enclen, &recipient_sk, out, outlen); + zeromem(&recipient_sk, sizeof(recipient_sk)); + return err; +} + +#endif diff --git a/src/boxes/ltc_secretbox_create.c b/src/boxes/ltc_secretbox_create.c new file mode 100644 index 00000000..aec56f88 --- /dev/null +++ b/src/boxes/ltc_secretbox_create.c @@ -0,0 +1,67 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#include "tomcrypt_private.h" + +/** + @file ltc_secretbox_create.c + libsodium-compatible secretbox encryption helper +*/ + +#if defined(LTC_XSALSA20) && defined(LTC_POLY1305) + +/** + Encrypt a message with XSalsa20-Poly1305 secretbox + @param msg The plaintext message to authenticate and encrypt + @param msglen The length of the plaintext message in octets + @param nonce The nonce to use for XSalsa20-Poly1305, must be 24 octets + @param noncelen The length of the nonce, must be LTC_SECRETBOX_NONCELEN + @param key The symmetric secretbox key, must be 32 octets + @param keylen The length of the symmetric key, must be LTC_SECRETBOX_KEYLEN + @param out [out] The destination for the 16-octet tag followed by ciphertext + @param outlen [in/out] Available out size on entry, bytes written or required on return + @return CRYPT_OK if successful +*/ +int ltc_secretbox_create(const unsigned char *msg, unsigned long msglen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen) +{ + salsa20_state st; + poly1305_state poly; + unsigned char polykey[LTC_SECRETBOX_KEYLEN]; + unsigned long need; + unsigned long taglen = LTC_SECRETBOX_TAGLEN; + int err; + + LTC_ARGCHK(msg != NULL); + LTC_ARGCHK(nonce != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(noncelen == LTC_SECRETBOX_NONCELEN); + LTC_ARGCHK(keylen == LTC_SECRETBOX_KEYLEN); + LTC_ARGCHK(outlen != NULL); + if (msglen > ULONG_MAX - LTC_SECRETBOX_TAGLEN) return CRYPT_OVERFLOW; + need = msglen + LTC_SECRETBOX_TAGLEN; + if (*outlen < need) { + *outlen = need; + return CRYPT_BUFFER_OVERFLOW; + } + LTC_ARGCHK(out != NULL); + *outlen = need; + + if ((err = xsalsa20_setup(&st, key, keylen, nonce, noncelen, 20)) != CRYPT_OK) goto cleanup; + if ((err = salsa20_keystream(&st, polykey, sizeof(polykey))) != CRYPT_OK) goto cleanup; + if ((err = salsa20_crypt(&st, msg, msglen, out + LTC_SECRETBOX_TAGLEN)) != CRYPT_OK) goto cleanup; + + if ((err = poly1305_init(&poly, polykey, sizeof(polykey))) != CRYPT_OK) goto cleanup; + if ((err = poly1305_process(&poly, out + LTC_SECRETBOX_TAGLEN, msglen)) != CRYPT_OK) goto cleanup; + err = poly1305_done(&poly, out, &taglen); + +cleanup: + salsa20_done(&st); + zeromem(&poly, sizeof(poly)); + zeromem(polykey, sizeof(polykey)); + return err; +} + +#endif diff --git a/src/boxes/ltc_secretbox_open.c b/src/boxes/ltc_secretbox_open.c new file mode 100644 index 00000000..9a569a07 --- /dev/null +++ b/src/boxes/ltc_secretbox_open.c @@ -0,0 +1,72 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ +/* SPDX-License-Identifier: Unlicense */ + +#include "tomcrypt_private.h" + +/** + @file ltc_secretbox_open.c + libsodium-compatible secretbox decryption helper +*/ + +#if defined(LTC_XSALSA20) && defined(LTC_POLY1305) + +/** + Decrypt a XSalsa20-Poly1305 secretbox message + @param enc The encrypted input, a 16-octet tag followed by ciphertext + @param enclen The length of the encrypted input in octets + @param nonce The nonce used for encryption, must be 24 octets + @param noncelen The length of the nonce, must be LTC_SECRETBOX_NONCELEN + @param key The symmetric secretbox key, must be 32 octets + @param keylen The length of the symmetric key, must be LTC_SECRETBOX_KEYLEN + @param out [out] The destination for the decrypted plaintext + @param outlen [in/out] Available out size on entry, bytes written or required on return + @return CRYPT_OK if successful +*/ +int ltc_secretbox_open(const unsigned char *enc, unsigned long enclen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen) +{ + salsa20_state st; + poly1305_state poly; + unsigned char polykey[LTC_SECRETBOX_KEYLEN], tag[LTC_SECRETBOX_TAGLEN]; + unsigned long taglen = LTC_SECRETBOX_TAGLEN; + unsigned long msglen; + int err; + + LTC_ARGCHK(enc != NULL); + LTC_ARGCHK(nonce != NULL); + LTC_ARGCHK(key != NULL); + LTC_ARGCHK(noncelen == LTC_SECRETBOX_NONCELEN); + LTC_ARGCHK(keylen == LTC_SECRETBOX_KEYLEN); + LTC_ARGCHK(enclen >= LTC_SECRETBOX_TAGLEN); + + msglen = enclen - LTC_SECRETBOX_TAGLEN; + LTC_ARGCHK(outlen != NULL); + if (*outlen < msglen) { + *outlen = msglen; + return CRYPT_BUFFER_OVERFLOW; + } + LTC_ARGCHK(out != NULL); + *outlen = msglen; + + if ((err = xsalsa20_setup(&st, key, keylen, nonce, noncelen, 20)) != CRYPT_OK) return err; + if ((err = salsa20_keystream(&st, polykey, sizeof(polykey))) != CRYPT_OK) goto done; + if ((err = poly1305_init(&poly, polykey, sizeof(polykey))) != CRYPT_OK) goto done; + if ((err = poly1305_process(&poly, enc + LTC_SECRETBOX_TAGLEN, msglen)) != CRYPT_OK) goto done; + if ((err = poly1305_done(&poly, tag, &taglen)) != CRYPT_OK) goto done; + if (mem_neq(tag, enc, LTC_SECRETBOX_TAGLEN) != 0) { + err = CRYPT_ERROR; + goto done; + } + err = salsa20_crypt(&st, enc + LTC_SECRETBOX_TAGLEN, msglen, out); + +done: + salsa20_done(&st); + zeromem(&poly, sizeof(poly)); + zeromem(tag, sizeof(tag)); + zeromem(polykey, sizeof(polykey)); + return err; +} + +#endif diff --git a/src/headers/tomcrypt_misc.h b/src/headers/tomcrypt_misc.h index be63f550..122eab1a 100644 --- a/src/headers/tomcrypt_misc.h +++ b/src/headers/tomcrypt_misc.h @@ -109,6 +109,63 @@ int hkdf(int hash_idx, #endif /* LTC_HKDF */ +/* ---- libsodium box-compatible helpers ---- */ +#if defined(LTC_XSALSA20) && defined(LTC_POLY1305) +int ltc_secretbox_create(const unsigned char *msg, unsigned long msglen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen); + +int ltc_secretbox_open(const unsigned char *enc, unsigned long enclen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *key, unsigned long keylen, + unsigned char *out, unsigned long *outlen); +#endif + +#if defined(LTC_XSALSA20) && defined(LTC_POLY1305) && defined(LTC_CURVE25519) && defined(LTC_BLAKE2B) +int ltc_cryptobox_create(const unsigned char *msg, unsigned long msglen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *pk, unsigned long pklen, + const unsigned char *sk, unsigned long sklen, + unsigned char *out, unsigned long *outlen); + +int ltc_cryptobox_create_ck(const unsigned char *msg, unsigned long msglen, + const unsigned char *nonce, unsigned long noncelen, + const curve25519_key *pk, + const curve25519_key *sk, + unsigned char *out, unsigned long *outlen); + +int ltc_cryptobox_open(const unsigned char *enc, unsigned long enclen, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *pk, unsigned long pklen, + const unsigned char *sk, unsigned long sklen, + unsigned char *out, unsigned long *outlen); + +int ltc_cryptobox_open_ck(const unsigned char *enc, unsigned long enclen, + const unsigned char *nonce, unsigned long noncelen, + const curve25519_key *pk, + const curve25519_key *sk, + unsigned char *out, unsigned long *outlen); + +int ltc_sealedbox_create(const unsigned char *msg, unsigned long msglen, + const unsigned char *pk, unsigned long pklen, + prng_state *prng, int wprng, + unsigned char *out, unsigned long *outlen); + +int ltc_sealedbox_create_ck(const unsigned char *msg, unsigned long msglen, + const curve25519_key *pk, + prng_state *prng, int wprng, + unsigned char *out, unsigned long *outlen); + +int ltc_sealedbox_open(const unsigned char *enc, unsigned long enclen, + const unsigned char *sk, unsigned long sklen, + unsigned char *out, unsigned long *outlen); + +int ltc_sealedbox_open_ck(const unsigned char *enc, unsigned long enclen, + const curve25519_key *sk, + unsigned char *out, unsigned long *outlen); +#endif + /* ---- MEM routines ---- */ int mem_neq(const void *a, const void *b, size_t len); void zeromem(volatile void *out, size_t outlen); diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h index 3a30526c..e0556173 100644 --- a/src/headers/tomcrypt_private.h +++ b/src/headers/tomcrypt_private.h @@ -37,6 +37,15 @@ LTC_STATIC_ASSERT(correct_ltc_uintptr_size, sizeof(ltc_uintptr) == sizeof(void*) #define LTC_OID_MAX_STRLEN 256 +#if defined(LTC_XSALSA20) && defined(LTC_POLY1305) && defined(LTC_CURVE25519) && defined(LTC_BLAKE2B) +#define LTC_SECRETBOX_NONCELEN 24uL +#define LTC_SECRETBOX_KEYLEN 32uL +#define LTC_BOX_KEYLEN 32uL +#define LTC_SECRETBOX_TAGLEN 16uL +#define LTC_SEALBOX_PREAMBLE 32uL +#define LTC_SEALBOX_OVERHEAD (LTC_SEALBOX_PREAMBLE + LTC_SECRETBOX_TAGLEN) +#endif + /* `NULL` as defined by the standard is not guaranteed to be of a pointer * type. In order to make sure that in vararg API's a pointer type is used, * define our own version and use that one internally.