From patchwork Mon Oct 7 16:45:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 175377 Delivered-To: patch@linaro.org Received: by 2002:a92:7e96:0:0:0:0:0 with SMTP id q22csp4529380ill; Mon, 7 Oct 2019 09:46:42 -0700 (PDT) X-Google-Smtp-Source: APXvYqwmEE734jLcZYJq3RMDw2gkBs+qAAYu/mMuD4Pz/O+3kug5MRYm9zP4nTycCb5tya1zMOF3 X-Received: by 2002:a17:906:7245:: with SMTP id n5mr24357812ejk.173.1570466802576; Mon, 07 Oct 2019 09:46:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1570466802; cv=none; d=google.com; s=arc-20160816; b=u5O6buHU5uRtfVWhsha6Gc+ZgV6tsUfTo9Bof4lOYR4kFpKSSR9SsH07gRnF5T3+RT 7JeQ/3i1swXgbHh0Y3B42uk16BVoRRCIyn//uz+tTPFfxkWI66HLO2kRw6AQMZXD2OYD OL8727RjuRLTwaxAidTcfavwA1IOYXZwc7O4B6N5hujpNgtFE4YKHPVWH4fOeR5lUEYj itcpGoDLlAffWXpYnf/L1h471Q+Vm8WMFphH4YWk+z3J2pT3RnovwJOcGSNbjLhgs6nz OxkFABSPzC5RjfvsdJGrQ/5DOKpz8VGu8P7DexpPXiEMk+YCXHlvEz9b72iDrz0fdL+t wxbg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=3KYzyJG0KPQg/NKCrKbyZmAb/K1Eaht43wf2/3hmTm4=; b=GyQcT9t0S82r7nCqpSNlmqA7MKBj+92TfDUeJKIc8BYGwIB9cueQ4HHy+gkJpgSHu8 shwIGJMdW3e0FfWqLGUs86gwk1cOm7AWYGCps6g4Vh763cZ3RItLfxDAFV4T7bn9ar6S ekpjFJ0nh968X334myeMrV0/BeL0vp0tPSI69QQ89sbK2DwxWg6dr7iMY9nDJVRxtze6 j7a8QwVRfB0KZJ8EKelyuvEfChPNoP06uquRILq+u5xBiguk4ODPDsULQhDrueeMd/XY WopalVS5tNtNDQ13Iz1DywHHRcvODJi/hPfrzvNNpE9LUV2Ah5DIfqoPPerAeWv+xFVl 3qUA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=yIU2dZEo; spf=pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f17si11357081edf.328.2019.10.07.09.46.42; Mon, 07 Oct 2019 09:46:42 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=yIU2dZEo; spf=pass (google.com: best guess record for domain of linux-crypto-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-crypto-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729003AbfJGQql (ORCPT + 3 others); Mon, 7 Oct 2019 12:46:41 -0400 Received: from mail-wm1-f67.google.com ([209.85.128.67]:50443 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728955AbfJGQqk (ORCPT ); Mon, 7 Oct 2019 12:46:40 -0400 Received: by mail-wm1-f67.google.com with SMTP id 5so230871wmg.0 for ; Mon, 07 Oct 2019 09:46:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=3KYzyJG0KPQg/NKCrKbyZmAb/K1Eaht43wf2/3hmTm4=; b=yIU2dZEo0XsjshtytMGuhBZhGR09qyYHKCr21brIQCK3Unw+v3wLqkxCMNfzyTf0lH ZQfxsF1op4/ze56BGKtoqToKX5+ykX+b8GW6TNHS+CJPc597zfnZvNVDaSGnlpG+Yfhg aBf+jwVdlfSr0bp9jzYH0PnPmt5FpszKzejvd1Gz4A+wASN00QRA/6QY4/X9Xvay4+QH 2i7gIh6stpKLRo5tlxCXFqvBWWSZX0VaHRb8wyTP/2eFWShjKNk4wV+sjd9awHqIKqDa CivtiQ95LI0aBtZamk50ZwERSpDIb/6lINEYJhz/be/io804UGgNeRzTlXzlgiW1tsEx ntmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3KYzyJG0KPQg/NKCrKbyZmAb/K1Eaht43wf2/3hmTm4=; b=XeaoFtzALm3YTKXhH91ToMmIN6b31URM6SLa2f5A395+GEKD6oULCTzmb2tWL2z6TT S6axd2HHBxP+UwWVRAeHczexY2mKk5HKITXSOHU0UO4df5xc/4d39JyuX5DIOyhcjbBR mzCwsAUsyWr0wI4UyBhrSEj0snPxtzgoF7arhv4X4kwXXW3SsYFFx4kd7W60HAfo+nz2 DidiykOd4e4r+xtrXLKrQ2t2tywYfLERb9mV7ai5ZjpIWh3HD5jvOLilcJn0tvrHYvME 8iKyaXoksiCT7nBwbc4ODzcU4ck24COWhWNtyRAbf3uGK+Y0g+JcVDA4IOhL5Nx8VmlC yWzQ== X-Gm-Message-State: APjAAAVxqBxBjCwJe8FvWeF0CbEtsxd83cM23fHvR9ziROG1mbf/oy+B Jidlf/eDZkiYO82jviZND9ksDCeUYIn7JQ== X-Received: by 2002:a7b:c049:: with SMTP id u9mr193700wmc.12.1570466798096; Mon, 07 Oct 2019 09:46:38 -0700 (PDT) Received: from localhost.localdomain (laubervilliers-657-1-83-120.w92-154.abo.wanadoo.fr. [92.154.90.120]) by smtp.gmail.com with ESMTPSA id b22sm68507wmj.36.2019.10.07.09.46.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 07 Oct 2019 09:46:37 -0700 (PDT) From: Ard Biesheuvel To: linux-crypto@vger.kernel.org Cc: Ard Biesheuvel , Herbert Xu , David Miller , "Jason A . Donenfeld" , Samuel Neves , Arnd Bergmann , Eric Biggers , Andy Lutomirski , Martin Willi , Rene van Dorst Subject: [PATCH v3 14/29] crypto: poly1305 - expose init/update/final library interface Date: Mon, 7 Oct 2019 18:45:55 +0200 Message-Id: <20191007164610.6881-15-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20191007164610.6881-1-ard.biesheuvel@linaro.org> References: <20191007164610.6881-1-ard.biesheuvel@linaro.org> MIME-Version: 1.0 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org Expose the existing generic Poly1305 code via a init/update/final library interface so that callers are not required to go through the crypto API's shash abstraction to access it. At the same time, make some preparations so that the library implementation can be superseded by an accelerated arch-specific version in the future. Signed-off-by: Ard Biesheuvel --- crypto/Kconfig | 11 +++ crypto/poly1305_generic.c | 22 +---- include/crypto/internal/poly1305.h | 7 ++ include/crypto/poly1305.h | 8 +- lib/crypto/poly1305.c | 90 ++++++++++++++++++++ 5 files changed, 116 insertions(+), 22 deletions(-) -- 2.20.1 diff --git a/crypto/Kconfig b/crypto/Kconfig index e510caf587df..ead0c3d15823 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -682,8 +682,19 @@ config CRYPTO_GHASH GHASH is the hash function used in GCM (Galois/Counter Mode). It is not a general-purpose cryptographic hash function. +config CRYPTO_ARCH_HAVE_LIB_POLY1305 + tristate + +config CRYPTO_LIB_POLY1305_RSIZE + int + default 1 + +config CRYPTO_LIB_POLY1305 + tristate + config CRYPTO_LIB_POLY1305_GENERIC tristate + default CRYPTO_LIB_POLY1305 if !CRYPTO_ARCH_HAVE_LIB_POLY1305 config CRYPTO_POLY1305 tristate "Poly1305 authenticator algorithm" diff --git a/crypto/poly1305_generic.c b/crypto/poly1305_generic.c index f3fcd9578a47..afe9a9e576dd 100644 --- a/crypto/poly1305_generic.c +++ b/crypto/poly1305_generic.c @@ -85,31 +85,11 @@ EXPORT_SYMBOL_GPL(crypto_poly1305_update); int crypto_poly1305_final(struct shash_desc *desc, u8 *dst) { struct poly1305_desc_ctx *dctx = shash_desc_ctx(desc); - __le32 digest[4]; - u64 f = 0; if (unlikely(!dctx->sset)) return -ENOKEY; - if (unlikely(dctx->buflen)) { - dctx->buf[dctx->buflen++] = 1; - memset(dctx->buf + dctx->buflen, 0, - POLY1305_BLOCK_SIZE - dctx->buflen); - poly1305_core_blocks(&dctx->h, dctx->r, dctx->buf, 1, 0); - } - - poly1305_core_emit(&dctx->h, digest); - - /* mac = (h + s) % (2^128) */ - f = (f >> 32) + le32_to_cpu(digest[0]) + dctx->s[0]; - put_unaligned_le32(f, dst + 0); - f = (f >> 32) + le32_to_cpu(digest[1]) + dctx->s[1]; - put_unaligned_le32(f, dst + 4); - f = (f >> 32) + le32_to_cpu(digest[2]) + dctx->s[2]; - put_unaligned_le32(f, dst + 8); - f = (f >> 32) + le32_to_cpu(digest[3]) + dctx->s[3]; - put_unaligned_le32(f, dst + 12); - + poly1305_final_generic(dctx, dst); return 0; } EXPORT_SYMBOL_GPL(crypto_poly1305_final); diff --git a/include/crypto/internal/poly1305.h b/include/crypto/internal/poly1305.h index 04fa269e5534..68269f0d0062 100644 --- a/include/crypto/internal/poly1305.h +++ b/include/crypto/internal/poly1305.h @@ -28,6 +28,13 @@ void poly1305_core_blocks(struct poly1305_state *state, unsigned int nblocks, u32 hibit); void poly1305_core_emit(const struct poly1305_state *state, void *dst); +void poly1305_init_generic(struct poly1305_desc_ctx *desc, const u8 *key); + +void poly1305_update_generic(struct poly1305_desc_ctx *desc, const u8 *src, + unsigned int nbytes); + +void poly1305_final_generic(struct poly1305_desc_ctx *desc, u8 *digest); + /* Crypto API helper functions for the Poly1305 MAC */ int crypto_poly1305_init(struct shash_desc *desc); diff --git a/include/crypto/poly1305.h b/include/crypto/poly1305.h index 36b5886cb50c..39afea016ac3 100644 --- a/include/crypto/poly1305.h +++ b/include/crypto/poly1305.h @@ -35,7 +35,13 @@ struct poly1305_desc_ctx { /* accumulator */ struct poly1305_state h; /* key */ - struct poly1305_key r[1]; + struct poly1305_key r[CONFIG_CRYPTO_LIB_POLY1305_RSIZE]; }; +void poly1305_init(struct poly1305_desc_ctx *desc, const u8 *key); + +void poly1305_update(struct poly1305_desc_ctx *desc, const u8 *src, + unsigned int nbytes); +void poly1305_final(struct poly1305_desc_ctx *desc, u8 *digest); + #endif diff --git a/lib/crypto/poly1305.c b/lib/crypto/poly1305.c index f019a57dbc1b..88367139b125 100644 --- a/lib/crypto/poly1305.c +++ b/lib/crypto/poly1305.c @@ -154,5 +154,95 @@ void poly1305_core_emit(const struct poly1305_state *state, void *dst) } EXPORT_SYMBOL_GPL(poly1305_core_emit); +void poly1305_init_generic(struct poly1305_desc_ctx *desc, const u8 *key) +{ + poly1305_core_setkey(desc->r, key); + desc->s[0] = get_unaligned_le32(key + 16); + desc->s[1] = get_unaligned_le32(key + 20); + desc->s[2] = get_unaligned_le32(key + 24); + desc->s[3] = get_unaligned_le32(key + 28); + poly1305_core_init(&desc->h); + desc->buflen = 0; + desc->sset = true; + desc->rset = 1; +} +EXPORT_SYMBOL_GPL(poly1305_init_generic); + +void poly1305_update_generic(struct poly1305_desc_ctx *desc, const u8 *src, + unsigned int nbytes) +{ + unsigned int bytes; + + if (unlikely(desc->buflen)) { + bytes = min(nbytes, POLY1305_BLOCK_SIZE - desc->buflen); + memcpy(desc->buf + desc->buflen, src, bytes); + src += bytes; + nbytes -= bytes; + desc->buflen += bytes; + + if (desc->buflen == POLY1305_BLOCK_SIZE) { + poly1305_core_blocks(&desc->h, desc->r, desc->buf, 1, 1); + desc->buflen = 0; + } + } + + if (likely(nbytes >= POLY1305_BLOCK_SIZE)) { + poly1305_core_blocks(&desc->h, desc->r, src, + nbytes / POLY1305_BLOCK_SIZE, 1); + src += nbytes - (nbytes % POLY1305_BLOCK_SIZE); + nbytes %= POLY1305_BLOCK_SIZE; + } + + if (unlikely(nbytes)) { + desc->buflen = nbytes; + memcpy(desc->buf, src, nbytes); + } +} +EXPORT_SYMBOL_GPL(poly1305_update_generic); + +void poly1305_final_generic(struct poly1305_desc_ctx *desc, u8 *dst) +{ + __le32 digest[4]; + u64 f = 0; + + if (unlikely(desc->buflen)) { + desc->buf[desc->buflen++] = 1; + memset(desc->buf + desc->buflen, 0, + POLY1305_BLOCK_SIZE - desc->buflen); + poly1305_core_blocks(&desc->h, desc->r, desc->buf, 1, 0); + } + + poly1305_core_emit(&desc->h, digest); + + /* mac = (h + s) % (2^128) */ + f = (f >> 32) + le32_to_cpu(digest[0]) + desc->s[0]; + put_unaligned_le32(f, dst + 0); + f = (f >> 32) + le32_to_cpu(digest[1]) + desc->s[1]; + put_unaligned_le32(f, dst + 4); + f = (f >> 32) + le32_to_cpu(digest[2]) + desc->s[2]; + put_unaligned_le32(f, dst + 8); + f = (f >> 32) + le32_to_cpu(digest[3]) + desc->s[3]; + put_unaligned_le32(f, dst + 12); + + *desc = (struct poly1305_desc_ctx){}; +} +EXPORT_SYMBOL_GPL(poly1305_final_generic); + MODULE_LICENSE("GPL"); MODULE_AUTHOR("Martin Willi "); + +extern void poly1305_init(struct poly1305_desc_ctx *desc, const u8 *key) + __weak __alias(poly1305_init_generic); + +extern void poly1305_update(struct poly1305_desc_ctx *desc, const u8 *src, + unsigned int nbytes) + __weak __alias(poly1305_update_generic); + +extern void poly1305_final(struct poly1305_desc_ctx *desc, u8 *dst) + __weak __alias(poly1305_final_generic); + +#if !IS_ENABLED(CONFIG_CRYPTO_ARCH_HAVE_LIB_POLY1305) +EXPORT_SYMBOL_GPL(poly1305_init); +EXPORT_SYMBOL_GPL(poly1305_update); +EXPORT_SYMBOL_GPL(poly1305_final); +#endif