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