commit a8ccce5a5fb60c896a24585292602d7edb92874e
parent f503c45b7156ef47afed0ab6bf98dc1067e79aa7
Author: Vineet Kumar <git@vineetk.net>
Date: Fri, 22 May 2026 14:56:20 -0400
import hmac code from sean mcafee to remove gnutls dependency
Diffstat:
1 file changed, 33 insertions(+), 2 deletions(-)
diff --git a/kasi-totp.el b/kasi-totp.el
@@ -1,10 +1,41 @@
;; TOTP code taken from Mastering Emacs which took from Jürgen Hötzel's `totp.el'.
;; Base32 code taken from same Mastering Emacs article.
+;; HMAC code taken from Sean McAfee.
;; https://www.masteringemacs.org/article/securely-generating-totp-tokens-emacs
;; https://github.com/juergenhoetzel/emacs-totp
+;; https://github.com/grimnebulin/emacs-hmac
(require 'bindat)
-(require 'gnutls)
(require 'hexl)
+(require 'cl-lib)
+(require 'subr-x)
+
+(defconst hmac-algorithm-blocksizes
+ '((md5 . 64)
+ (sha1 . 64)
+ (sha224 . 64)
+ (sha256 . 64)
+ (sha384 . 128)
+ (sha512 . 128))
+ "Mapping from HMAC algorithm to the algorithm's blocksize.")
+
+(defun hmac (algorithm key message &optional binary)
+ "Compute the HMAC for a given message, private key and algorithm.
+
+ALGORITHM is a symbol naming one of the algorithms recognized by
+`secure-hash'. KEY is a the private key to use. MESSAGE, a
+string, is the message to hash. If BINARY is non-nil, the hmac
+will be returned as a binary string, otherwise as a hexadecimal
+string."
+ (if-let (blocksize (alist-get algorithm hmac-algorithm-blocksizes))
+ (progn
+ (when (> (length key) blocksize)
+ (setq key (secure-hash algorithm key)))
+ (when (< (length key) blocksize)
+ (setq key (concat key (make-string (- blocksize (length key)) 0))))
+ (let ((o-key-pad (cl-map 'string #'logxor key (make-string blocksize #x5c)))
+ (i-key-pad (cl-map 'string #'logxor key (make-string blocksize #x36))))
+ (secure-hash algorithm (concat o-key-pad (secure-hash algorithm (concat i-key-pad message) nil nil t)) nil nil binary)))
+ (error "Unsupported hash algorithm %s" algorithm)))
(defconst base32-alphabet
(let ((tbl (make-char-table nil)))
@@ -50,7 +81,7 @@ required for HMAC-TOTP."
;; we have to manually split the 64 bit number (u64 not supported in Emacs 27.2)
(counter-bytes (bindat-pack '((:high u32) (:low u32))
`((:high . ,(ash counter -32)) (:low . ,(logand counter #xffffffff)))))
- (mac (gnutls-hash-mac 'SHA1 key-bytes counter-bytes))
+ (mac (hmac 'sha1 key-bytes counter-bytes))
(offset (logand (bindat-get-field (bindat-unpack '((:offset u8)) mac 19) :offset) #xf)))
(format "%06d"
(mod