From nobody Fri Feb 16 04:00:32 2024 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4TbdWN5sdKz59ZBh; Fri, 16 Feb 2024 04:00:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4TbdWN3PS9z4H9T; Fri, 16 Feb 2024 04:00:32 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1708056032; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=iKAA73VbNlvqAMRKJM4G9LpqJAbowROdjnP5qglgWWg=; b=Zuv2JNvd6WXRbjUOuKWJXUpko+1XZoZKWgZ5dFuFqd0IPXlnVqfKGn6PE2RDxXvjc931ji zr5OKFO2qyTUyxce9FsR2cSDTSmVim8VUYd40gvAFIsDIcvuoTxfhoxW6SyHDS8U/WHvXi eBO+b+FX74pdC1nlQldhoLdqoSbLPwdheWgWbkhNOLbR0iZZ1ti4YmbnQlADn2FnyOu7+c /f7awUitXxoAPwky+SwWYgbmxffxdt2FL5EZvvK9tUUSnbTmPXYvn9KrYgynhFRMDMEe2p 58MnUNhQeYgBLK4nNQD8a7hQZCJRWJDkTTm2/MRzh7jmG0Pg96qmVCCfPPCLXQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1708056032; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=iKAA73VbNlvqAMRKJM4G9LpqJAbowROdjnP5qglgWWg=; b=vQVQ7kVwyFMe1U9M5bcNPin0bLBQbe4XWojTPi6CCZBFZeojwX/a8H7PPHcRJrj/yiyw9J dC7g0IG4C+UsgkDx76qU0gO9BHwKWA3fqE+cpAWhTWvFpweugoDMjJusyCF117sUqMisds +7g0xylv+iTmXyXf1/6hYrQrtpmSsYln0z2jFCmsNMAwqrzQXGpbarIC55KL1cvbG8Fms9 oHO0prB3PS5QWBAWbQqo2W5MAyyMa+IsTUYkP+XuoswSMtIHowdDYDxeKXuvCYQIfAnRyD u7Yh2pgb4yJspKsRW5gMIZYLxe79CrSH9cVl2+LhVlwK06ehq4qqaBu8GDw/qA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1708056032; a=rsa-sha256; cv=none; b=xjmYxGxvKcGFM2azvDzmP+t0aSeTZTryC1mMNekvZaGcuN8p2Kg6X8hq6VA8RcWZCQmwXw 0mqO+QB9Etx15ra3G3qGw9gFSuLatGTnuNQBhB53FA6Fr2EzZO2LvS72bakmbglWTQWifp 6757XRNx/Zgv66BtnLGHoiNpqeHjbk6d2pAMJNxGrIJ5Jq8GidVbTLW/GIosa6wR4O6JyR Rfya6DC7cifijTLgvtvTlNqWN9h8upEgOCDwIIvs+RzXy3CvWF6zRLqhSTDjfrA5yGq0Gy dwqjY72YmKX2UYy1bwrxd3BwUWwpI1VUl/1RNxyP0vLhoFG2rvwhug4p6SovyQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4TbdWN2WM4z18b4; Fri, 16 Feb 2024 04:00:32 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.17.1/8.17.1) with ESMTP id 41G40WxJ019245; Fri, 16 Feb 2024 04:00:32 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.17.1/8.17.1/Submit) id 41G40WVx019242; Fri, 16 Feb 2024 04:00:32 GMT (envelope-from git) Date: Fri, 16 Feb 2024 04:00:32 GMT Message-Id: <202402160400.41G40WVx019242@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Warner Losh Subject: git: f7781d030ccd - main - flua: Add hash module List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: imp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: f7781d030ccd18b1d4c864ecfade122ea19dafb1 Auto-Submitted: auto-generated The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=f7781d030ccd18b1d4c864ecfade122ea19dafb1 commit f7781d030ccd18b1d4c864ecfade122ea19dafb1 Author: Warner Losh AuthorDate: 2024-02-16 03:54:36 +0000 Commit: Warner Losh CommitDate: 2024-02-16 03:59:23 +0000 flua: Add hash module Add lua bindings to hashing functions. sha256 is available. sha256.new craetes a new object. sha256.update updates the digest. sha256.digest returns the digest as a binary string and resets the context. sha256.hexdigest returns the digest as a string of hex digits and then resets the cotnext. Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D43872 --- lib/flua/Makefile | 4 +- lib/flua/libhash/Makefile | 14 ++++ lib/flua/libhash/hash.3lua | 54 ++++++++++++++ lib/flua/libhash/lhash.c | 177 +++++++++++++++++++++++++++++++++++++++++++++ lib/flua/libhash/lhash.h | 11 +++ 5 files changed, 258 insertions(+), 2 deletions(-) diff --git a/lib/flua/Makefile b/lib/flua/Makefile index eb148c2125fd..769736039f7e 100644 --- a/lib/flua/Makefile +++ b/lib/flua/Makefile @@ -1,4 +1,4 @@ - -SUBDIR= libjail +SUBDIR+= libhash +SUBDIR+= libjail .include diff --git a/lib/flua/libhash/Makefile b/lib/flua/libhash/Makefile new file mode 100644 index 000000000000..f166ff90a392 --- /dev/null +++ b/lib/flua/libhash/Makefile @@ -0,0 +1,14 @@ +SHLIB_NAME= hash.so +SHLIBDIR= ${LIBDIR}/flua + +SRCS+= lhash.c + +CFLAGS+= \ + -I${SRCTOP}/contrib/lua/src \ + -I${SRCTOP}/lib/liblua \ + +LIBADD+= md + +MAN= hash.3lua + +.include diff --git a/lib/flua/libhash/hash.3lua b/lib/flua/libhash/hash.3lua new file mode 100644 index 000000000000..1662e87f7c68 --- /dev/null +++ b/lib/flua/libhash/hash.3lua @@ -0,0 +1,54 @@ +.\" +.\" Copyright (c) 2024 Netflix, Inc. +.\" +.\" SPDX-License-Identifier: BSD-2-Clause +.\" +.Dd February 6, 2024 +.Dt HASH 3lua +.Os +.Sh NAME +.Nm new , +.Nm update , +.Nm digest , +.Nm hexdigest +.Nd Lua Cryptographic hash module. +.Sh DESCRIPTION +The built-in cryptographic hashing Lua bindings for the are available via the +.Ic hash +table. +.Ss Supported Hashing Schemes +The following hashing schemes are supported by the hash module. +.Bl -bullet -compact +.It +sha256 +.El +.Ss APIs Supported +.Bl -tag -width asdf -compact +.It Fn new data +Compute a digest based on the +.Va data . +.It Fn update Va data +Using the current digest, process +.Va data +to compute a new digest as if all prior data had been concatenated together. +.It Fn digest +Return the hashed digest as a binary array. +This resets the context. +.It Fn hexdigest +Take +.Fn digest +and convert it to an upper case hex string. +This resets the context. +.It Va digest_size +Return the size of the digest, in bytes. +.It Va block_size +Return the block size used in bytes. +.El +.Sh EXAMPLES +.Sh SEE ALSO +.Xr sha256 3 +.Sh AUTHORS +The +.Nm +man page was written by +.An Warner Losh Aq Mt imp@FreeBSD.org . diff --git a/lib/flua/libhash/lhash.c b/lib/flua/libhash/lhash.c new file mode 100644 index 000000000000..4587961fe8a0 --- /dev/null +++ b/lib/flua/libhash/lhash.c @@ -0,0 +1,177 @@ +/*- + * Copyright (c) 2024 Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include "lauxlib.h" +#include "lhash.h" + +#include +#include + +#define SHA256_META "SHA256 meta table" +#define SHA256_DIGEST_LEN 32 + +/* + * Note C++ comments indicate the before -- after state of the stack, in with a + * similar convention to forth's ( ) comments. Lua indexes are from 1 and can be + * read left to right (leftmost is 1). Negative are relative to the end (-1 is + * rightmost). A '.' indicates a return value left on the stack (all values to + * its right). Trivial functions don't do this. + */ + +/* + * Updates the digest with the new data passed in. Takes 1 argument, which + * is converted to a string. + */ +static int +lua_sha256_update(lua_State *L) +{ + size_t len; + const unsigned char *data; + SHA256_CTX *ctx; + + ctx = luaL_checkudata(L, 1, SHA256_META); + data = luaL_checklstring(L, 2, &len); + SHA256_Update(ctx, data, len); + + lua_settop(L, 1); + + return (1); +} + +/* + * Finalizes the digest value and returns it as a 32-byte binary string. The ctx + * is zeroed. + */ +static int +lua_sha256_digest(lua_State *L) +{ + SHA256_CTX *ctx; + unsigned char digest[SHA256_DIGEST_LEN]; + + ctx = luaL_checkudata(L, 1, SHA256_META); + SHA256_Final(digest, ctx); + lua_pushlstring(L, digest, sizeof(digest)); + + return (1); +} + +/* + * Finalizes the digest value and returns it as a 64-byte ascii string of hex + * numbers. The ctx is zeroed. + */ +static int +lua_sha256_hexdigest(lua_State *L) +{ + SHA256_CTX *ctx; + char buf[SHA256_DIGEST_LEN * 2 + 1]; + unsigned char digest[SHA256_DIGEST_LEN]; + static const char hex[]="0123456789abcdef"; + int i; + + ctx = luaL_checkudata(L, 1, SHA256_META); + SHA256_Final(digest, ctx); + for (i = 0; i < SHA256_DIGEST_LEN; i++) { + buf[i+i] = hex[digest[i] >> 4]; + buf[i+i+1] = hex[digest[i] & 0x0f]; + } + buf[i+i] = '\0'; + + lua_pushstring(L, buf); + + return (1); +} + +/* + * Zeros out the ctx before garbage collection. Normally this is done in + * obj:digest or obj:hexdigest, but if not, it will be wiped here. Lua + * manages freeing the ctx memory. + */ +static int +lua_sha256_done(lua_State *L) +{ + SHA256_CTX *ctx; + + ctx = luaL_checkudata(L, 1, SHA256_META); + memset(ctx, 0, sizeof(*ctx)); + + return (0); +} + +/* + * Create object obj which accumulates the state of the sha256 digest + * for its contents and any subsequent obj:update call. It takes zero + * or 1 arguments. + */ +static int +lua_sha256(lua_State *L) +{ + SHA256_CTX *ctx; + int top; + + /* We take 0 or 1 args */ + top = lua_gettop(L); // data -- data + if (top > 1) { + lua_pushnil(L); + return (1); + } + + ctx = lua_newuserdata(L, sizeof(*ctx)); // data -- data ctx + SHA256_Init(ctx); + if (top == 1) { + size_t len; + const unsigned char *data; + + data = luaL_checklstring(L, 1, &len); + SHA256_Update(ctx, data, len); + } + luaL_setmetatable(L, SHA256_META); // data ctx -- data ctx + + return (1); // data . ctx +} + +/* + * Setup the metatable to manage our userdata that we create in lua_sha256. We + * request a finalization call with __gc so we can zero out the ctx buffer so + * that we don't leak secrets if obj:digest or obj:hexdigest aren't called. + */ +static void +register_metatable_sha256(lua_State *L) +{ + luaL_newmetatable(L, SHA256_META); // -- meta + + lua_newtable(L); // meta -- meta tbl + lua_pushcfunction(L, lua_sha256_update); // meta tbl -- meta tbl fn + lua_setfield(L, -2, "update"); // meta tbl fn -- meta tbl + lua_pushcfunction(L, lua_sha256_digest); // meta tbl -- meta tbl fn + lua_setfield(L, -2, "digest"); // meta tbl fn -- meta tbl + lua_pushcfunction(L, lua_sha256_hexdigest); // meta tbl -- meta tbl fn + lua_setfield(L, -2, "hexdigest"); // meta tbl fn -- meta tbl + + /* Associate tbl with metatable */ + lua_setfield(L, -2, "__index"); // meta tbl -- meta + lua_pushcfunction(L, lua_sha256_done); // meta -- meta fn + lua_setfield(L, -2, "__gc"); // meta fn -- meta + + lua_pop(L, 1); // meta -- +} + +#define REG_SIMPLE(n) { #n, lua_ ## n } +static const struct luaL_Reg hashlib[] = { + REG_SIMPLE(sha256), + { NULL, NULL }, +}; +#undef REG_SIMPLE + +int +luaopen_hash(lua_State *L) +{ + register_metatable_sha256(L); + + luaL_newlib(L, hashlib); + + return 1; +} diff --git a/lib/flua/libhash/lhash.h b/lib/flua/libhash/lhash.h new file mode 100644 index 000000000000..c1e9788a55a3 --- /dev/null +++ b/lib/flua/libhash/lhash.h @@ -0,0 +1,11 @@ +/*- + * Copyright (c) 2024 Netflix, Inc + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +int luaopen_hash(lua_State *L);