hmac-def.el 2.91 KB
Newer Older
Glenn Morris's avatar
Glenn Morris committed
1 2
;;; hmac-def.el --- A macro for defining HMAC functions.

Glenn Morris's avatar
Glenn Morris committed
3
;; Copyright (C) 1999, 2001, 2007, 2008, 2009, 2010  Free Software Foundation, Inc.
Glenn Morris's avatar
Glenn Morris committed
4 5

;; Author: Shuhei KOBAYASHI <shuhei@aqua.ocn.ne.jp>
Juri Linkov's avatar
Juri Linkov committed
6
;; Keywords: HMAC, RFC2104
Glenn Morris's avatar
Glenn Morris committed
7 8 9

;; This file is part of GNU Emacs.

10
;; GNU Emacs is free software: you can redistribute it and/or modify
Glenn Morris's avatar
Glenn Morris committed
11
;; it under the terms of the GNU General Public License as published by
12 13
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
Glenn Morris's avatar
Glenn Morris committed
14 15 16 17 18 19 20

;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
21
;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
Glenn Morris's avatar
Glenn Morris committed
22 23 24

;;; Commentary:

Juri Linkov's avatar
Juri Linkov committed
25
;; This program is implemented from RFC2104,
Glenn Morris's avatar
Glenn Morris committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
;; "HMAC: Keyed-Hashing for Message Authentication".

;;; Code:

(defmacro define-hmac-function (name H B L &optional bit)
  "Define a function NAME(TEXT KEY) which computes HMAC with function H.

HMAC function is H(KEY XOR opad, H(KEY XOR ipad, TEXT)):

H is a cryptographic hash function, such as SHA1 and MD5, which takes
a string and return a digest of it (in binary form).
B is a byte-length of a block size of H. (B=64 for both SHA1 and MD5.)
L is a byte-length of hash outputs. (L=16 for MD5, L=20 for SHA1.)
If BIT is non-nil, truncate output to specified bits."
  `(defun ,name (text key)
     ,(concat "Compute "
	      (upcase (symbol-name name))
	      " over TEXT with KEY.")
     (let ((key-xor-ipad (make-string ,B ?\x36))
	   (key-xor-opad (make-string ,B ?\x5C))
	   (len (length key))
	   (pos 0))
       (unwind-protect
	   (progn
	     ;; if `key' is longer than the block size, apply hash function
	     ;; to `key' and use the result as a real `key'.
	     (if (> len ,B)
		 (setq key (,H key)
		       len ,L))
	     (while (< pos len)
	       (aset key-xor-ipad pos (logxor (aref key pos) ?\x36))
	       (aset key-xor-opad pos (logxor (aref key pos) ?\x5C))
	       (setq pos (1+ pos)))
	     (setq key-xor-ipad (unwind-protect
				    (concat key-xor-ipad text)
				  (fillarray key-xor-ipad 0))
		   key-xor-ipad (unwind-protect
				    (,H key-xor-ipad)
				  (fillarray key-xor-ipad 0))
		   key-xor-opad (unwind-protect
				    (concat key-xor-opad key-xor-ipad)
				  (fillarray key-xor-opad 0))
		   key-xor-opad (unwind-protect
				    (,H key-xor-opad)
				  (fillarray key-xor-opad 0)))
	     ;; now `key-xor-opad' contains
	     ;; H(KEY XOR opad, H(KEY XOR ipad, TEXT)).
	     ,(if (and bit (< (/ bit 8) L))
		  `(substring key-xor-opad 0 ,(/ bit 8))
		;; return a copy of `key-xor-opad'.
		`(concat key-xor-opad)))
	 ;; cleanup.
	 (fillarray key-xor-ipad 0)
	 (fillarray key-xor-opad 0)))))

(provide 'hmac-def)

83
;; arch-tag: 645adcef-b835-4900-a10a-11f636c982b9
Glenn Morris's avatar
Glenn Morris committed
84
;;; hmac-def.el ends here