diff options
-rw-r--r-- | autoload.c | 17 | ||||
-rw-r--r-- | stdlib/hmac.tl | 61 | ||||
-rw-r--r-- | tests/013/chksum.tl | 8 | ||||
-rw-r--r-- | txr.1 | 51 |
4 files changed, 137 insertions, 0 deletions
@@ -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') @@ -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 |