mirror of
https://github.com/libtom/libtomcrypt
synced 2026-08-25 20:26:07 -04:00
ltc boxes (libsodium compatible)
This commit is contained in:
parent
57826bd484
commit
0563715fc8
8 changed files with 573 additions and 0 deletions
96
src/boxes/ltc_cryptobox_create.c
Normal file
96
src/boxes/ltc_cryptobox_create.c
Normal file
|
|
@ -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
|
||||
96
src/boxes/ltc_cryptobox_open.c
Normal file
96
src/boxes/ltc_cryptobox_open.c
Normal file
|
|
@ -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
|
||||
97
src/boxes/ltc_sealedbox_create.c
Normal file
97
src/boxes/ltc_sealedbox_create.c
Normal file
|
|
@ -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
|
||||
79
src/boxes/ltc_sealedbox_open.c
Normal file
79
src/boxes/ltc_sealedbox_open.c
Normal file
|
|
@ -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
|
||||
67
src/boxes/ltc_secretbox_create.c
Normal file
67
src/boxes/ltc_secretbox_create.c
Normal file
|
|
@ -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
|
||||
72
src/boxes/ltc_secretbox_open.c
Normal file
72
src/boxes/ltc_secretbox_open.c
Normal file
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue