From a8ccce5a5fb60c896a24585292602d7edb92874e Mon Sep 17 00:00:00 2001 From: Vineet Kumar Date: Fri, 22 May 2026 14:56:20 -0400 Subject: import hmac code from sean mcafee to remove gnutls dependency --- kasi-totp.el | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/kasi-totp.el b/kasi-totp.el index d14e00a..b8fe078 100644 --- 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 -- cgit v1.2.3