diff --git a/Makefile.am b/Makefile.am index 13a06ab..2731703 100644 --- a/Makefile.am +++ b/Makefile.am @@ -72,6 +72,12 @@ else libkcapi_la_SOURCES += endif +if ENABLE_LIB_ECC +libkcapi_la_SOURCES += lib/kcapi-ecc.c +else +libkcapi_la_SOURCES += +endif + libkcapi_la_CPPFLAGS = $(COMMON_CPPFLAGS) libkcapi_la_LDFLAGS = $(COMMON_LDFLAGS) -Wl,--version-script,$(top_srcdir)/lib/version.lds -version-number `echo $(VERSION) | sed 's/\./:/g'` diff --git a/configure.ac b/configure.ac index fbae4f9..02d1942 100644 --- a/configure.ac +++ b/configure.ac @@ -126,6 +126,12 @@ if test "$with_lib_kpp" = "yes"; then AC_DEFINE([WITH_LIB_KPP], 1, [KPP support enabled]) fi +AC_ARG_ENABLE([lib-ecc], [AS_HELP_STRING([--enable-lib-ecc], [Enable ECC support in library])], [with_lib_ecc=$enableval]) +AM_CONDITIONAL([ENABLE_LIB_ECC], [test "x$with_lib_ecc" = "xyes"]) +if test "$with_lib_ecc" = "yes"; then + AC_DEFINE([WITH_LIB_ECC], 1, [ECC support enabled]) +fi + AC_ARG_ENABLE([sum-prefix], AS_HELP_STRING([--enable-sum-prefix=PRE],[prefix to add to filenames when deriving the binary's checksum file's name (default ".")]), if test x$enableval != xno ; then diff --git a/lib/kcapi-ecc.c b/lib/kcapi-ecc.c new file mode 100644 index 0000000..6139632 --- /dev/null +++ b/lib/kcapi-ecc.c @@ -0,0 +1,76 @@ +/* Kernel crypto API AF_ALG ECC Primitives API + * + * Copyright (C) 2022, VMware Inc. + * Author: Alexey Makhalov + * + * License: see COPYING file in root directory + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +#include "internal.h" +#include "kcapi.h" + +DSO_PUBLIC +int kcapi_ecc_init(struct kcapi_handle **handle) +{ + int ret = _kcapi_handle_init(handle, "ecc", "ecdh", 0); + kcapi_set_verbosity(KCAPI_LOG_DEBUG); + + if (ret) + return ret; + + return 0; +} + +DSO_PUBLIC +void kcapi_ecc_destroy(struct kcapi_handle *handle) +{ + _kcapi_handle_destroy(handle); +} + + +DSO_PUBLIC +int32_t kcapi_ecc_verify(struct kcapi_handle *handle, + const uint8_t *x, uint32_t xlen, + const uint8_t *y, uint32_t ylen) +{ + struct iovec iov[2]; + + iov[0].iov_base = (void*)(uintptr_t)x; + iov[0].iov_len = xlen; + iov[1].iov_base = (void*)(uintptr_t)y; + iov[1].iov_len = ylen; + + return _kcapi_common_send_data(handle, iov, 2, 0); +} + +DSO_PUBLIC +int32_t kcapi_ecc_keygen(struct kcapi_handle *handle, + uint8_t *privkey, uint32_t privkeylen, + uint8_t *x, uint32_t xlen, + uint8_t *y, uint32_t ylen) +{ + struct iovec iov[3]; + + iov[0].iov_base = (void*)(uintptr_t)privkey; + iov[0].iov_len = privkeylen; + iov[1].iov_base = (void*)(uintptr_t)x; + iov[1].iov_len = xlen; + iov[2].iov_base = (void*)(uintptr_t)y; + iov[2].iov_len = ylen; + + return _kcapi_common_recv_data(handle, iov, 3); +} + diff --git a/lib/kcapi.h b/lib/kcapi.h index 9f1db2c..433268f 100644 --- a/lib/kcapi.h +++ b/lib/kcapi.h @@ -2493,6 +2493,74 @@ ssize_t kcapi_akcipher_stream_init_vfy(struct kcapi_handle *handle, ssize_t kcapi_akcipher_stream_update(struct kcapi_handle *handle, struct iovec *iov, size_t iovlen); +/** + * DOC: ECC Primitives + * + * API function calls used to invoke ECC operations. + */ + +/** + * kcapi_ecc_init() - initialize cipher handle + * + * @handle: [out] cipher handle filled during the call + * + * This function provides the initialization of a ECC handle and + * establishes the connection to the kernel. + * + * On success, a pointer to kcapi_handle object is returned in *handle. + * Function kcapi_ecc_destroy should be called afterwards to free + * resources. + * + * @return 0 upon success; + * -ENOENT - algorithm not available; + * -EOPNOTSUPP - AF_ALG family not available; + * -EINVAL - accept syscall failed + * -ENOMEM - cipher handle cannot be allocated + */ +int kcapi_ecc_init(struct kcapi_handle **handle); + +/** + * kcapi_ecc_destroy() - close the cipher handle and release resources + * + * @handle: [in] cipher handle to release + */ +void kcapi_ecc_destroy(struct kcapi_handle *handle); + +/** + * kcapi_ecc_verify - verify curve point of public key + * + * @handle: [in] cipher handle + * @x: [in] public key curve point x + * @xlen: [in] length of x buffer + * @y: [in] public key curve point y + * @ylen: [in] length of y buffer + * + * @return number of bytes accepted by the key verification operation upon + * success; a negative errno-style error code if an error occurred + */ +int32_t kcapi_ecc_verify(struct kcapi_handle *handle, + const uint8_t *x, uint32_t xlen, + const uint8_t *y, uint32_t ylen); + +/** + * kcapi_ecc_keygen - generate a private/public key pair + * + * @handle: [in] cipher handle + * @privkey: [out] generated private key + * @privkeylen: [in] length of key buffer + * @x: [out] generated public key curve point x + * @xlen: [in] length of x buffer + * @y: [out] generated public key curve point y + * @ylen: [in] length of y buffer + * + * @return number of bytes returned by the key generation operation upon + * success; a negative errno-style error code if an error occurred + */ +int32_t kcapi_ecc_keygen(struct kcapi_handle *handle, + uint8_t *privkey, uint32_t privkeylen, + uint8_t *x, uint32_t xlen, + uint8_t *y, uint32_t ylen); + /** * kcapi_akcipher_stream_update_last() - send last data for processing (stream) * diff --git a/lib/version.lds b/lib/version.lds index 2f25882..561ab3e 100644 --- a/lib/version.lds +++ b/lib/version.lds @@ -248,4 +248,8 @@ LIBKCAPI_1.5.0 { kcapi_md_sha3_256; kcapi_md_sha3_384; kcapi_md_sha3_512; + kcapi_ecc_init; + kcapi_ecc_destroy; + kcapi_ecc_verify; + kcapi_ecc_keygen; } LIBKCAPI_1.4.0;