1/* $NetBSD: h_md5hmac.c,v 1.3 2014/01/17 22:31:25 pgoyette Exp $ */ 2 3/*- 4 * Copyright (c) 2014 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include <err.h> 30#include <fcntl.h> 31#include <stdio.h> 32#include <string.h> 33 34#include <sys/ioctl.h> 35#include <sys/time.h> 36 37#include <crypto/cryptodev.h> 38 39#define MD5_HMAC_KEYLEN 16 /* Fixed key length supported */ 40 41/* Test data from RFC2202 */ 42const struct { 43 int num; 44 size_t key_len; 45 size_t len; 46 unsigned char key[80]; 47 unsigned char data[80]; 48 unsigned char mac[16]; 49} tests[] = { 50 /* Test #1 */ 51 { 1, 16, 8, 52 { 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 53 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b }, 54 "Hi There", 55 { 0x92, 0x94, 0x72, 0x7a, 0x36, 0x38, 0xbb, 0x1c, 56 0x13, 0xf4, 0x8e, 0xf8, 0x15, 0x8b, 0xfc, 0x9d } 57 }, 58 /* Test #2 */ 59 { 2, 4, 28, 60 "Jefe", 61 "what do ya want for nothing?", 62 { 0x75, 0x0c, 0x78, 0x3e, 0x6a, 0xb0, 0xb5, 0x03, 63 0xea, 0xa8, 0x6e, 0x31, 0x0a, 0x5d, 0xb7, 0x38 } 64 }, 65 /* Test #3 */ 66 { 3, 16, 50, 67 { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 68 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, 69 { 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 70 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 71 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 72 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 73 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 74 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 75 0xdd, 0xdd }, 76 { 0x56, 0xbe, 0x34, 0x52, 0x1d, 0x14, 0x4c, 0x88, 77 0xdb, 0xb8, 0xc7, 0x33, 0xf0, 0xe8, 0xb3, 0xf6 } 78 }, 79 /* Test #4 */ 80 { 4, 25, 50, 81 { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 82 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 83 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 84 0x19 }, 85 { 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 86 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 87 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 88 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 89 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 90 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 91 0xcd, 0xcd }, 92 { 0x69, 0x7e, 0xaf, 0x0a, 0xca, 0x3a, 0x3a, 0xea, 93 0x3a, 0x75, 0x16, 0x47, 0x46, 0xff, 0xaa, 0x79 } 94 }, 95 /* Test #5 */ 96 { 5, 16, 20, 97 { 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 98 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c }, 99 "Test With Truncation", 100 { 0x56, 0x46, 0x1e, 0xf2, 0x34, 0x2e, 0xdc, 0x00, 101 0xf9, 0xba, 0xb9, 0x95, 0x69, 0x0e, 0xfd, 0x4c } 102 }, 103 /* Test #6 */ 104 { 6, 80, 54, 105 { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 106 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 107 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 108 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 109 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 110 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 111 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 112 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 113 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 114 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, 115 "Test Using Larger Than Block-Size Key - Hash Key First", 116 { 0x6b, 0x1a, 0xb7, 0xfe, 0x4b, 0xd7, 0xbf, 0x8f, 117 0x0b, 0x62, 0xe6, 0xce, 0x61, 0xb9, 0xd0, 0xcd } 118 }, 119 /* Test #7 */ 120 { 7, 80, 73, 121 { 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 122 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 123 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 124 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 125 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 126 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 127 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 128 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 129 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 130 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa }, 131 "Test Using Larger Than Block-Size Key and Larger " 132 "Than One Block-Size Data", 133 { 0x6f, 0x63, 0x0f, 0xad, 0x67, 0xcd, 0xa0, 0xee, 134 0x1f, 0xb1, 0xf5, 0x62, 0xdb, 0x3a, 0xa5, 0x3e } 135 }, 136}; 137 138int 139main(void) 140{ 141 size_t i; 142 int fd, res; 143 struct session_op cs; 144 struct crypt_op co; 145 unsigned char buf[16]; 146 147 fd = open("/dev/crypto", O_RDWR, 0); 148 if (fd < 0) 149 err(1, "open"); 150 for (i = 0; i < __arraycount(tests); i++) { 151 if (tests[i].key_len != MD5_HMAC_KEYLEN) 152 continue; 153 154 memset(&cs, 0, sizeof(cs)); 155 cs.mac = CRYPTO_MD5_HMAC; 156 cs.mackeylen = tests[i].key_len; 157 cs.mackey = __UNCONST(&tests[i].key); 158 res = ioctl(fd, CIOCGSESSION, &cs); 159 if (res < 0) 160 err(1, "CIOCGSESSION test %d", tests[i].num); 161 162 memset(&co, 0, sizeof(co)); 163 memset(buf, 0, sizeof(buf)); 164 co.ses = cs.ses; 165 co.op = COP_ENCRYPT; 166 co.len = tests[i].len; 167 co.src = __UNCONST(&tests[i].data); 168 co.mac = buf; 169 res = ioctl(fd, CIOCCRYPT, &co); 170 if (res < 0) 171 err(1, "CIOCCRYPT test %d", tests[i].num); 172 173 if (memcmp(co.mac, tests[i].mac, sizeof(tests[i].mac))) 174 errx(1, "verification failed test %d", tests[i].num); 175 176 res = ioctl(fd, CIOCFSESSION, &cs.ses); 177 if (res < 0) 178 err(1, "CIOCFSESSION test %d", tests[i].num); 179 } 180 return 0; 181} 182