1 /* mdXhl.c 2 * ---------------------------------------------------------------------------- 3 * "THE BEER-WARE LICENSE" (Revision 42): 4 * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you 5 * can do whatever you want with this stuff. If we meet some day, and you think 6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp 7 * ---------------------------------------------------------------------------- 8 */ 9 10 #include <sys/cdefs.h> 11 __FBSDID("$FreeBSD$"); 12 13 #include <sys/types.h> 14 #include <sys/stat.h> 15 #include <fcntl.h> 16 #include <unistd.h> 17 18 #include <errno.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 22 #include "mdX.h" 23 24 char * 25 MDXEnd(MDX_CTX *ctx, char *buf) 26 { 27 int i; 28 unsigned char digest[LENGTH]; 29 static const char hex[]="0123456789abcdef"; 30 31 if (!buf) 32 buf = malloc(2*LENGTH + 1); 33 if (!buf) 34 return 0; 35 MDXFinal(digest, ctx); 36 for (i = 0; i < LENGTH; i++) { 37 buf[i+i] = hex[digest[i] >> 4]; 38 buf[i+i+1] = hex[digest[i] & 0x0f]; 39 } 40 buf[i+i] = '\0'; 41 return buf; 42 } 43 44 char * 45 MDXFd(int fd, char *buf) 46 { 47 return MDXFdChunk(fd, buf, 0, 0); 48 } 49 50 char * 51 MDXFdChunk(int fd, char *buf, off_t ofs, off_t len) 52 { 53 unsigned char buffer[16*1024]; 54 MDX_CTX ctx; 55 struct stat stbuf; 56 int readrv, e; 57 off_t remain; 58 59 if (len < 0) { 60 errno = EINVAL; 61 return NULL; 62 } 63 64 MDXInit(&ctx); 65 if (ofs != 0) { 66 errno = 0; 67 if (lseek(fd, ofs, SEEK_SET) != ofs || 68 (ofs == -1 && errno != 0)) { 69 readrv = -1; 70 goto error; 71 } 72 } 73 remain = len; 74 readrv = 0; 75 while (len == 0 || remain > 0) { 76 if (len == 0 || remain > sizeof(buffer)) 77 readrv = read(fd, buffer, sizeof(buffer)); 78 else 79 readrv = read(fd, buffer, remain); 80 if (readrv <= 0) 81 break; 82 MDXUpdate(&ctx, buffer, readrv); 83 remain -= readrv; 84 } 85 error: 86 if (readrv < 0) 87 return NULL; 88 return (MDXEnd(&ctx, buf)); 89 } 90 91 char * 92 MDXFile(const char *filename, char *buf) 93 { 94 return (MDXFileChunk(filename, buf, 0, 0)); 95 } 96 97 char * 98 MDXFileChunk(const char *filename, char *buf, off_t ofs, off_t len) 99 { 100 char *ret; 101 int e, fd; 102 103 fd = open(filename, O_RDONLY); 104 if (fd < 0) 105 return NULL; 106 ret = MDXFdChunk(fd, buf, ofs, len); 107 e = errno; 108 close (fd); 109 errno = e; 110 return ret; 111 } 112 113 char * 114 MDXData (const void *data, unsigned int len, char *buf) 115 { 116 MDX_CTX ctx; 117 118 MDXInit(&ctx); 119 MDXUpdate(&ctx,data,len); 120 return (MDXEnd(&ctx, buf)); 121 } 122 123 #ifdef WEAK_REFS 124 /* When building libmd, provide weak references. Note: this is not 125 activated in the context of compiling these sources for internal 126 use in libcrypt. 127 */ 128 #undef MDXEnd 129 __weak_reference(_libmd_MDXEnd, MDXEnd); 130 #undef MDXFile 131 __weak_reference(_libmd_MDXFile, MDXFile); 132 #undef MDXFileChunk 133 __weak_reference(_libmd_MDXFileChunk, MDXFileChunk); 134 #undef MDXData 135 __weak_reference(_libmd_MDXData, MDXData); 136 #endif 137