summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2025-04-16 06:29:30 -0700
committerKaz Kylheku <kaz@kylheku.com>2025-04-16 06:29:30 -0700
commit00c8f50d4e3bc6b7883f022ef3649d0a6167f4c7 (patch)
treee0716d250646878c2bf69884a87a08eb47cc0e6e
parentf440625e1421cca677a33d232d92d7bd35e83515 (diff)
downloadtxr-00c8f50d4e3bc6b7883f022ef3649d0a6167f4c7.tar.gz
txr-00c8f50d4e3bc6b7883f022ef3649d0a6167f4c7.tar.bz2
txr-00c8f50d4e3bc6b7883f022ef3649d0a6167f4c7.zip
New: HMAC functions.
* autoload.c (hmac_set_entries, hmac_instantiate): New static functions. (autoload_init): Register autoload of hmac module. * stdlib/hmac.tl: New file. * tests/013/chksum.tl: New tests. * txr.1: Documented.
-rw-r--r--autoload.c17
-rw-r--r--stdlib/hmac.tl61
-rw-r--r--tests/013/chksum.tl8
-rw-r--r--txr.151
4 files changed, 137 insertions, 0 deletions
diff --git a/autoload.c b/autoload.c
index b9dfca0d..11d2beac 100644
--- a/autoload.c
+++ b/autoload.c
@@ -1026,6 +1026,22 @@ static val infix_instantiate(void)
return nil;
}
+static val hmac_set_entries(val fun)
+{
+ val name[] = {
+ lit("hmac-sha1"), lit("hmac-sha256"), lit("hmac-md5"),
+ nil
+ };
+ autoload_set(al_fun, name, fun);
+ return nil;
+}
+
+static val hmac_instantiate(void)
+{
+ load(scat2(stdlib_path, lit("hmac")));
+ return nil;
+}
+
val autoload_reg(val (*instantiate)(void),
val (*set_entries)(val))
{
@@ -1098,6 +1114,7 @@ void autoload_init(void)
autoload_reg(glob_instantiate, glob_set_entries);
autoload_reg(enum_instantiate, enum_set_entries);
autoload_reg(infix_instantiate, infix_set_entries);
+ autoload_reg(hmac_instantiate, hmac_set_entries);
reg_fun(intern(lit("autoload-try-fun"), system_package), func_n1(autoload_try_fun));
}
diff --git a/stdlib/hmac.tl b/stdlib/hmac.tl
new file mode 100644
index 00000000..fc487cbe
--- /dev/null
+++ b/stdlib/hmac.tl
@@ -0,0 +1,61 @@
+;; Copyright 2025
+;; Kaz Kylheku <kaz@kylheku.com>
+;; Vancouver, Canada
+;; All rights reserved.
+;;
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright notice,
+;; this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright notice,
+;; this list of conditions and the following disclaimer in the documentation
+;; and/or other materials provided with the distribution.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+;; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+;; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+;; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 ADVISED OF THE
+;; POSSIBILITY OF SUCH DAMAGE.
+
+(defun hmac-impl (key message
+ digest-fn begin-fn update-fn end-fn
+ block-size)
+ (if (stringp key)
+ (upd key buf-str))
+
+ (if (stringp message)
+ (upd message buf-str))
+
+ (if (> (len key) block-size)
+ (upd key digest-fn))
+
+ (buf-set-length key block-size)
+
+ (for ((i 0) (okey (copy-buf key)) (ikey (copy-buf key))
+ (ctx0 [begin-fn]) (ctx1 [begin-fn]))
+ ((< i block-size)
+ [update-fn ctx0 ikey]
+ [update-fn ctx0 message]
+ [update-fn ctx1 okey]
+ [update-fn ctx1 [end-fn ctx0]]
+ [end-fn ctx1])
+ ((inc i))
+ (upd [okey i] (logxor #x5c))
+ (upd [ikey i] (logxor #x36))))
+
+(defun hmac-sha1 (key message)
+ [hmac-impl key message sha1 sha1-begin sha1-hash sha1-end 64])
+
+(defun hmac-sha256 (key message)
+ [hmac-impl key message sha256 sha256-begin sha256-hash sha256-end 64])
+
+(defun hmac-md5 (key message)
+ [hmac-impl key message md5 md5-begin md5-hash md5-end 64])
diff --git a/tests/013/chksum.tl b/tests/013/chksum.tl
index 7b4be59e..8fcdc87e 100644
--- a/tests/013/chksum.tl
+++ b/tests/013/chksum.tl
@@ -43,3 +43,11 @@
(equal h0 h2) t
(equal h0 h3) t
(equal h0 h4) t)))
+
+(mtest
+ (hmac-sha256 "key" "The quick brown fox jumps over the lazy dog")
+ #b'f7bc83f430538424 b13298e6aa6fb143 ef4d59a149461759 97479dbc2d1a3cd8'
+ (hmac-md5 "key" "The quick brown fox jumps over the lazy dog")
+ #b'80070713463e7749 b90c2dc24911e275'
+ (hmac-sha1 "key" "The quick brown fox jumps over the lazy dog")
+ #b'de7c9b85b8b78aa6 bc8a7a36f70a9070 1c9db4d9')
diff --git a/txr.1 b/txr.1
index 84718ebf..bee4e7e2 100644
--- a/txr.1
+++ b/txr.1
@@ -72544,6 +72544,57 @@ function additionally resets the
object into the initial state of a newly created context object, so
that it may be used for another digest session.
+.coNP Functions @, hmac-sha1 @ hmac-sha256 and @ hmac-md5
+.synb
+.mets (hmac-sha1 < key < object )
+.mets (hmac-sha256 < key < object )
+.mets (hmac-md5 < key < object )
+.syne
+.desc
+The functions
+.codn hmac-sha1 ,
+.code hmac-sha256
+and
+.code hmac-md5
+calculate and return the HMAC of
+.metn object ,
+using the specified
+.meta key
+and the respective message digest algorithm: SHA-1, SHA-256 or MD5.
+
+The HMAC calculation is described in RFC 2104, titled
+.IR "HMAC: Keyed-Hashing for Message Authentication" .
+
+The argument to the
+.meta key
+parameter may be a buffer object or string.
+For security reasons, the key should be no shorter than the length
+of the selected message digest type.
+
+If
+.meta key
+is a string, it is converted to a binary key using UTF-8 encoding.
+
+The
+.meta object
+hashed may be a character, string, buffer or stream.
+
+.TP* Examples:
+
+.verb
+ (hmac-sha256 "key" "The quick brown fox jumps over the lazy dog")
+ --> #b'f7bc83f430538424 b13298e6aa6fb143
+ ef4d59a149461759 97479dbc2d1a3cd8'
+
+ (hmac-md5 "key" "The quick brown fox jumps over the lazy dog")
+ --> #b'80070713463e7749 b90c2dc24911e275'
+
+ (hmac-sha1 "key" "The quick brown fox jumps over the lazy dog")
+ --> #b'de7c9b85b8b78aa6 bc8a7a36f70a9070 1c9db4d9')
+.brev
+
+Note: the small key used in these examples is not recommended practice.
+
.SS* The Awk Utility
The \*(TL library provides a macro called