mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-26 07:55:01 +00:00
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
This commit is contained in:
parent
0fd98b8a76
commit
f7781d030c
@ -1,4 +1,4 @@
|
||||
|
||||
SUBDIR= libjail
|
||||
SUBDIR+= libhash
|
||||
SUBDIR+= libjail
|
||||
|
||||
.include <bsd.subdir.mk>
|
||||
|
14
lib/flua/libhash/Makefile
Normal file
14
lib/flua/libhash/Makefile
Normal file
@ -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 <bsd.lib.mk>
|
54
lib/flua/libhash/hash.3lua
Normal file
54
lib/flua/libhash/hash.3lua
Normal file
@ -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 .
|
177
lib/flua/libhash/lhash.c
Normal file
177
lib/flua/libhash/lhash.c
Normal file
@ -0,0 +1,177 @@
|
||||
/*-
|
||||
* Copyright (c) 2024 Netflix, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <lua.h>
|
||||
#include "lauxlib.h"
|
||||
#include "lhash.h"
|
||||
|
||||
#include <sha256.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
11
lib/flua/libhash/lhash.h
Normal file
11
lib/flua/libhash/lhash.h
Normal file
@ -0,0 +1,11 @@
|
||||
/*-
|
||||
* Copyright (c) 2024 Netflix, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <lua.h>
|
||||
|
||||
int luaopen_hash(lua_State *L);
|
Loading…
Reference in New Issue
Block a user