Changeset View
Changeset View
Standalone View
Standalone View
sys/opencrypto/xform_chacha20_poly1305.c
Show All 22 Lines | |||||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||||||
*/ | */ | ||||||||
#include <opencrypto/xform_auth.h> | #include <opencrypto/xform_auth.h> | ||||||||
#include <opencrypto/xform_enc.h> | #include <opencrypto/xform_enc.h> | ||||||||
#include <sodium/crypto_core_hchacha20.h> | |||||||||
#include <sodium/crypto_onetimeauth_poly1305.h> | #include <sodium/crypto_onetimeauth_poly1305.h> | ||||||||
#include <sodium/crypto_stream_chacha20.h> | #include <sodium/crypto_stream_chacha20.h> | ||||||||
struct chacha20_poly1305_ctx { | struct chacha20_poly1305_ctx { | ||||||||
struct crypto_onetimeauth_poly1305_state auth; | struct crypto_onetimeauth_poly1305_state auth; | ||||||||
const void *key; | const void *key; | ||||||||
uint32_t ic; | uint32_t ic; | ||||||||
bool ietf; | bool ietf; | ||||||||
char nonce[CHACHA20_POLY1305_IV_LEN]; | char nonce[CHACHA20_POLY1305_IV_LEN]; | ||||||||
}; | }; | ||||||||
struct xchacha20_poly1305_ctx { | |||||||||
struct chacha20_poly1305_ctx base_ctx; /* must be first */ | |||||||||
markjUnsubmitted Done Inline Actions
markj: | |||||||||
const void *key; | |||||||||
char derived_key[CHACHA20_POLY1305_KEY]; | |||||||||
}; | |||||||||
static int | static int | ||||||||
chacha20_poly1305_setkey(void *vctx, const uint8_t *key, int len) | chacha20_poly1305_setkey(void *vctx, const uint8_t *key, int len) | ||||||||
{ | { | ||||||||
struct chacha20_poly1305_ctx *ctx = vctx; | struct chacha20_poly1305_ctx *ctx = vctx; | ||||||||
if (len != CHACHA20_POLY1305_KEY) | if (len != CHACHA20_POLY1305_KEY) | ||||||||
return (EINVAL); | return (EINVAL); | ||||||||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | const struct enc_xform enc_xform_chacha20_poly1305 = { | ||||||||
.ivsize = CHACHA20_POLY1305_IV_LEN, | .ivsize = CHACHA20_POLY1305_IV_LEN, | ||||||||
.minkey = CHACHA20_POLY1305_KEY, | .minkey = CHACHA20_POLY1305_KEY, | ||||||||
.maxkey = CHACHA20_POLY1305_KEY, | .maxkey = CHACHA20_POLY1305_KEY, | ||||||||
.macsize = POLY1305_HASH_LEN, | .macsize = POLY1305_HASH_LEN, | ||||||||
.encrypt = chacha20_poly1305_crypt, | .encrypt = chacha20_poly1305_crypt, | ||||||||
.decrypt = chacha20_poly1305_crypt, | .decrypt = chacha20_poly1305_crypt, | ||||||||
.setkey = chacha20_poly1305_setkey, | .setkey = chacha20_poly1305_setkey, | ||||||||
.reinit = chacha20_poly1305_reinit, | .reinit = chacha20_poly1305_reinit, | ||||||||
.encrypt_last = chacha20_poly1305_crypt_last, | |||||||||
.decrypt_last = chacha20_poly1305_crypt_last, | |||||||||
.update = chacha20_poly1305_update, | |||||||||
.final = chacha20_poly1305_final, | |||||||||
}; | |||||||||
static int | |||||||||
xchacha20_poly1305_setkey(void *vctx, const uint8_t *key, int len) | |||||||||
{ | |||||||||
struct xchacha20_poly1305_ctx *ctx = vctx; | |||||||||
if (len != XCHACHA20_POLY1305_KEY) | |||||||||
return (EINVAL); | |||||||||
ctx->key = key; | |||||||||
ctx->base_ctx.key = ctx->derived_key; | |||||||||
return (0); | |||||||||
} | |||||||||
static void | |||||||||
xchacha20_poly1305_reinit(void *vctx, const uint8_t *iv, size_t ivlen) | |||||||||
{ | |||||||||
struct xchacha20_poly1305_ctx *ctx = vctx; | |||||||||
char nonce[CHACHA20_POLY1305_IV_LEN]; | |||||||||
KASSERT(ivlen == XCHACHA20_POLY1305_IV_LEN, | |||||||||
("%s: invalid nonce length", __func__)); | |||||||||
/* | |||||||||
* Use HChaCha20 to derive the internal key used for | |||||||||
* ChaCha20-Poly1305. | |||||||||
*/ | |||||||||
crypto_core_hchacha20(ctx->derived_key, iv, ctx->key, NULL); | |||||||||
memset(nonce, 0, 4); | |||||||||
memcpy(nonce + 4, iv + crypto_core_hchacha20_INPUTBYTES, | |||||||||
sizeof(nonce) - 4); | |||||||||
chacha20_poly1305_reinit(&ctx->base_ctx, nonce, sizeof(nonce)); | |||||||||
Done Inline ActionsShould we zero the nonce buffer? markj: Should we zero the `nonce` buffer? | |||||||||
explicit_bzero(nonce, sizeof(nonce)); | |||||||||
} | |||||||||
const struct enc_xform enc_xform_xchacha20_poly1305 = { | |||||||||
.type = CRYPTO_XCHACHA20_POLY1305, | |||||||||
.name = "XChaCha20-Poly1305", | |||||||||
.ctxsize = sizeof(struct xchacha20_poly1305_ctx), | |||||||||
.blocksize = 1, | |||||||||
.native_blocksize = CHACHA20_NATIVE_BLOCK_LEN, | |||||||||
.ivsize = XCHACHA20_POLY1305_IV_LEN, | |||||||||
.minkey = XCHACHA20_POLY1305_KEY, | |||||||||
.maxkey = XCHACHA20_POLY1305_KEY, | |||||||||
.macsize = POLY1305_HASH_LEN, | |||||||||
.encrypt = chacha20_poly1305_crypt, | |||||||||
.decrypt = chacha20_poly1305_crypt, | |||||||||
.setkey = xchacha20_poly1305_setkey, | |||||||||
.reinit = xchacha20_poly1305_reinit, | |||||||||
.encrypt_last = chacha20_poly1305_crypt_last, | .encrypt_last = chacha20_poly1305_crypt_last, | ||||||||
.decrypt_last = chacha20_poly1305_crypt_last, | .decrypt_last = chacha20_poly1305_crypt_last, | ||||||||
.update = chacha20_poly1305_update, | .update = chacha20_poly1305_update, | ||||||||
.final = chacha20_poly1305_final, | .final = chacha20_poly1305_final, | ||||||||
}; | }; |