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: stable/11/lib/libmd/mdXhl.c 310372 2016-12-21 18:42:04Z emaste $"); 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 24char * 25MDXEnd(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 44char * 45MDXFd(int fd, char *buf) 46{ 47 return MDXFdChunk(fd, buf, 0, 0); 48} 49 50char * 51MDXFdChunk(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 } 85error: 86 if (readrv < 0) 87 return NULL; 88 return (MDXEnd(&ctx, buf)); 89} 90 91char * 92MDXFile(const char *filename, char *buf) 93{ 94 return (MDXFileChunk(filename, buf, 0, 0)); 95} 96 97char * 98MDXFileChunk(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 113char * 114MDXData (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