1 /* 2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include <errno.h> 12 #include "internal/cryptlib.h" 13 #include <openssl/buffer.h> 14 #include <openssl/evp.h> 15 #include "crypto/evp.h" 16 #include "evp_local.h" 17 #include "internal/bio.h" 18 19 /* 20 * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest 21 */ 22 23 static int md_write(BIO *h, char const *buf, int num); 24 static int md_read(BIO *h, char *buf, int size); 25 static int md_gets(BIO *h, char *str, int size); 26 static long md_ctrl(BIO *h, int cmd, long arg1, void *arg2); 27 static int md_new(BIO *h); 28 static int md_free(BIO *data); 29 static long md_callback_ctrl(BIO *h, int cmd, BIO_info_cb *fp); 30 31 static const BIO_METHOD methods_md = { 32 BIO_TYPE_MD, 33 "message digest", 34 /* TODO: Convert to new style write function */ 35 bwrite_conv, 36 md_write, 37 /* TODO: Convert to new style read function */ 38 bread_conv, 39 md_read, 40 NULL, /* md_puts, */ 41 md_gets, 42 md_ctrl, 43 md_new, 44 md_free, 45 md_callback_ctrl, 46 }; 47 48 const BIO_METHOD *BIO_f_md(void) 49 { 50 return &methods_md; 51 } 52 53 static int md_new(BIO *bi) 54 { 55 EVP_MD_CTX *ctx; 56 57 ctx = EVP_MD_CTX_new(); 58 if (ctx == NULL) 59 return 0; 60 61 BIO_set_init(bi, 1); 62 BIO_set_data(bi, ctx); 63 64 return 1; 65 } 66 67 static int md_free(BIO *a) 68 { 69 if (a == NULL) 70 return 0; 71 EVP_MD_CTX_free(BIO_get_data(a)); 72 BIO_set_data(a, NULL); 73 BIO_set_init(a, 0); 74 75 return 1; 76 } 77 78 static int md_read(BIO *b, char *out, int outl) 79 { 80 int ret = 0; 81 EVP_MD_CTX *ctx; 82 BIO *next; 83 84 if (out == NULL) 85 return 0; 86 87 ctx = BIO_get_data(b); 88 next = BIO_next(b); 89 90 if ((ctx == NULL) || (next == NULL)) 91 return 0; 92 93 ret = BIO_read(next, out, outl); 94 if (BIO_get_init(b)) { 95 if (ret > 0) { 96 if (EVP_DigestUpdate(ctx, (unsigned char *)out, 97 (unsigned int)ret) <= 0) 98 return -1; 99 } 100 } 101 BIO_clear_retry_flags(b); 102 BIO_copy_next_retry(b); 103 return ret; 104 } 105 106 static int md_write(BIO *b, const char *in, int inl) 107 { 108 int ret = 0; 109 EVP_MD_CTX *ctx; 110 BIO *next; 111 112 if ((in == NULL) || (inl <= 0)) 113 return 0; 114 115 ctx = BIO_get_data(b); 116 next = BIO_next(b); 117 if ((ctx != NULL) && (next != NULL)) 118 ret = BIO_write(next, in, inl); 119 120 if (BIO_get_init(b)) { 121 if (ret > 0) { 122 if (!EVP_DigestUpdate(ctx, (const unsigned char *)in, 123 (unsigned int)ret)) { 124 BIO_clear_retry_flags(b); 125 return 0; 126 } 127 } 128 } 129 if (next != NULL) { 130 BIO_clear_retry_flags(b); 131 BIO_copy_next_retry(b); 132 } 133 return ret; 134 } 135 136 static long md_ctrl(BIO *b, int cmd, long num, void *ptr) 137 { 138 EVP_MD_CTX *ctx, *dctx, **pctx; 139 const EVP_MD **ppmd; 140 EVP_MD *md; 141 long ret = 1; 142 BIO *dbio, *next; 143 144 145 ctx = BIO_get_data(b); 146 next = BIO_next(b); 147 148 switch (cmd) { 149 case BIO_CTRL_RESET: 150 if (BIO_get_init(b)) 151 ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL); 152 else 153 ret = 0; 154 if (ret > 0) 155 ret = BIO_ctrl(next, cmd, num, ptr); 156 break; 157 case BIO_C_GET_MD: 158 if (BIO_get_init(b)) { 159 ppmd = ptr; 160 *ppmd = ctx->digest; 161 } else 162 ret = 0; 163 break; 164 case BIO_C_GET_MD_CTX: 165 pctx = ptr; 166 *pctx = ctx; 167 BIO_set_init(b, 1); 168 break; 169 case BIO_C_SET_MD_CTX: 170 if (BIO_get_init(b)) 171 BIO_set_data(b, ptr); 172 else 173 ret = 0; 174 break; 175 case BIO_C_DO_STATE_MACHINE: 176 BIO_clear_retry_flags(b); 177 ret = BIO_ctrl(next, cmd, num, ptr); 178 BIO_copy_next_retry(b); 179 break; 180 181 case BIO_C_SET_MD: 182 md = ptr; 183 ret = EVP_DigestInit_ex(ctx, md, NULL); 184 if (ret > 0) 185 BIO_set_init(b, 1); 186 break; 187 case BIO_CTRL_DUP: 188 dbio = ptr; 189 dctx = BIO_get_data(dbio); 190 if (!EVP_MD_CTX_copy_ex(dctx, ctx)) 191 return 0; 192 BIO_set_init(b, 1); 193 break; 194 default: 195 ret = BIO_ctrl(next, cmd, num, ptr); 196 break; 197 } 198 return ret; 199 } 200 201 static long md_callback_ctrl(BIO *b, int cmd, BIO_info_cb *fp) 202 { 203 long ret = 1; 204 BIO *next; 205 206 next = BIO_next(b); 207 208 if (next == NULL) 209 return 0; 210 211 switch (cmd) { 212 default: 213 ret = BIO_callback_ctrl(next, cmd, fp); 214 break; 215 } 216 return ret; 217 } 218 219 static int md_gets(BIO *bp, char *buf, int size) 220 { 221 EVP_MD_CTX *ctx; 222 unsigned int ret; 223 224 ctx = BIO_get_data(bp); 225 226 if (size < ctx->digest->md_size) 227 return 0; 228 229 if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0) 230 return -1; 231 232 return (int)ret; 233 } 234