Overview
Comment: | Optimized calc digest for data blob to use same functions as other cases. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | crypto |
Files: | files | file ages | folders |
SHA3-256: |
d5db8e7da54e8b676fc9a6c64c992657 |
User & Date: | bohagan on 2023-11-17 21:46:18 |
Other Links: | branch diff | manifest | tags |
Context
2023-11-18
| ||
05:59 | Optimized DigestInputProc to use common digest functions. Fixed write to channel digest transform. Updated comments check-in: 3120c0a647 user: bohagan tags: crypto | |
2023-11-17
| ||
21:46 | Optimized calc digest for data blob to use same functions as other cases. check-in: d5db8e7da5 user: bohagan tags: crypto | |
18:31 | Changed digest command to make digest into a variable argument check-in: 6f3bac05a8 user: bohagan tags: crypto | |
Changes
Modified generic/tlsDigest.c from [5957db2945] to [075035113a].
1 | /* | | | > | | > | | | | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /* * Message Digests (MD) and Message Authentication Code (MAC) Module * * Provides commands to calculate a message digest (MD) or message * authentication code (MAC) using a specified hash function and/or cipher. * * Copyright (C) 2023 Brian O'Hagan * */ #include "tlsInt.h" #include "tclOpts.h" #include <tcl.h> #include <stdio.h> #include <string.h> #include <openssl/evp.h> #include <openssl/cmac.h> #include <openssl/hmac.h> /* Constants */ const char *hex = "0123456789abcdef"; /* Macros */ #define BUFFER_SIZE 65536 #define CHAN_EOF 0x10 #define READ_DELAY 5 /* Digest format and operation */ #define BIN_FORMAT 0x01 #define HEX_FORMAT 0x02 #define TYPE_MD 0x10 #define TYPE_HMAC 0x20 #define TYPE_CMAC 0x40 /* * This structure defines the per-instance state of a digest operation. */ typedef struct DigestState { Tcl_Channel self; /* This socket channel */ Tcl_TimerToken timer; /* Timer for read events */ |
︙ | ︙ | |||
184 185 186 187 188 189 190 | * 1 if successful or 0 for failure * * Side effects: * Adds buf to hash function * *------------------------------------------------------------------- */ | | | | 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | * 1 if successful or 0 for failure * * Side effects: * Adds buf to hash function * *------------------------------------------------------------------- */ int Tls_DigestUpdate(DigestState *statePtr, char *buf, size_t read, int do_result) { int res = 0; if (statePtr->format & TYPE_MD) { res = EVP_DigestUpdate(statePtr->ctx, buf, read); } else if (statePtr->format & TYPE_HMAC) { res = HMAC_Update(statePtr->hctx, buf, read); } else if (statePtr->format & TYPE_CMAC) { res = CMAC_Update(statePtr->cctx, buf, read); } if (!res && do_result) { Tcl_AppendResult(statePtr->interp, "Update failed: ", REASON(), NULL); return TCL_ERROR; } return res; } /* |
︙ | ︙ | |||
576 577 578 579 580 581 582 | * Nothing (can't return error messages) * * Side effects: * Configure notifier so future events on the channel will be seen by Tcl. * *---------------------------------------------------------------------- */ | < | 578 579 580 581 582 583 584 585 586 587 588 589 590 591 | * Nothing (can't return error messages) * * Side effects: * Configure notifier so future events on the channel will be seen by Tcl. * *---------------------------------------------------------------------- */ void DigestWatchProc(ClientData clientData, int mask) { DigestState *statePtr = (DigestState *) clientData; Tcl_Channel parent; Tcl_DriverWatchProc *watchProc; /* Abort if no channel */ if (statePtr->self == (Tcl_Channel) NULL) { |
︙ | ︙ | |||
948 949 950 951 952 953 954 | * * Side effects: * Sets result to message digest or error message * *------------------------------------------------------------------- */ int | | | | < < | < < < < | < | < < < | < < < < < < < < < < < < | | | | > > | | | | | | | < < < < < < < < < < < < < < < < < < < < < < < | 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 | * * Side effects: * Sets result to message digest or error message * *------------------------------------------------------------------- */ int Tls_DigestData(Tcl_Interp *interp, Tcl_Obj *dataObj, const EVP_MD *md, const EVP_CIPHER *cipher, int format, Tcl_Obj *keyObj) { char *data; int data_len; DigestState *statePtr; /* Get data */ data = Tcl_GetByteArrayFromObj(dataObj, &data_len); if (data == NULL || data_len == 0) { Tcl_SetResult(interp, "No data", NULL); return TCL_ERROR; } /* Create state struct */ if ((statePtr = Tls_DigestNew(interp, format)) == NULL) { Tcl_AppendResult(interp, "Memory allocation error", (char *) NULL); return TCL_ERROR; } /* Calc Digest */ if (Tls_DigestInit(interp, statePtr, md, cipher, keyObj) != TCL_OK || Tls_DigestUpdate(statePtr, data, (size_t) len, 1) == 0 || Tls_DigestFinialize(interp, statePtr) != TCL_OK) { Tls_DigestFree(statePtr); return TCL_ERROR; } Tls_DigestFree(statePtr); return TCL_OK; } /*******************************************************************/ /* *------------------------------------------------------------------- |
︙ | ︙ | |||
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 | */ int Tls_DigestFile(Tcl_Interp *interp, Tcl_Obj *filename, const EVP_MD *md, const EVP_CIPHER *cipher, int format, Tcl_Obj *keyObj) { DigestState *statePtr; Tcl_Channel chan = NULL; unsigned char buf[BUFFER_SIZE]; int res = TCL_OK, len; /* Open file channel */ chan = Tcl_FSOpenFileChannel(interp, filename, "rb", 0444); if (chan == (Tcl_Channel) NULL) { return TCL_ERROR; } /* Configure channel */ if ((res = Tcl_SetChannelOption(interp, chan, "-translation", "binary")) == TCL_ERROR) { goto done; } Tcl_SetChannelBufferSize(chan, BUFFER_SIZE); | > > > > > > > < < < < < < < | 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 | */ int Tls_DigestFile(Tcl_Interp *interp, Tcl_Obj *filename, const EVP_MD *md, const EVP_CIPHER *cipher, int format, Tcl_Obj *keyObj) { DigestState *statePtr; Tcl_Channel chan = NULL; unsigned char buf[BUFFER_SIZE]; int res = TCL_OK, len; /* Create state data struct */ if ((statePtr = Tls_DigestNew(interp, format)) == NULL) { Tcl_AppendResult(interp, "Memory allocation error", (char *) NULL); return TCL_ERROR; } /* Open file channel */ chan = Tcl_FSOpenFileChannel(interp, filename, "rb", 0444); if (chan == (Tcl_Channel) NULL) { Tls_DigestFree(statePtr); return TCL_ERROR; } /* Configure channel */ if ((res = Tcl_SetChannelOption(interp, chan, "-translation", "binary")) == TCL_ERROR) { goto done; } Tcl_SetChannelBufferSize(chan, BUFFER_SIZE); /* Initialize hash function */ if ((res = Tls_DigestInit(interp, statePtr, md, cipher, keyObj)) != TCL_OK) { goto done; } /* Read file data and update hash function */ while (!Tcl_Eof(chan)) { |
︙ | ︙ | |||
1099 1100 1101 1102 1103 1104 1105 | } /*******************************************************************/ /* *------------------------------------------------------------------- * | | > | | 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 | } /*******************************************************************/ /* *------------------------------------------------------------------- * * DigestMain -- * * Return message digest or Message Authentication Code (MAC) of * data using user specified hash function. * * Returns: * TCL_OK or TCL_ERROR * * Side effects: * Sets result to message digest or error message * |
︙ | ︙ | |||
1132 1133 1134 1135 1136 1137 1138 | return TCL_ERROR; } /* Optimal case for a digest and blob of data */ if (objc == 3 && type == TYPE_MD) { digestName = Tcl_GetStringFromObj(objv[1],NULL); if ((md = EVP_get_digestbyname(digestName)) != NULL) { | | | 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 | return TCL_ERROR; } /* Optimal case for a digest and blob of data */ if (objc == 3 && type == TYPE_MD) { digestName = Tcl_GetStringFromObj(objv[1],NULL); if ((md = EVP_get_digestbyname(digestName)) != NULL) { return Tls_DigestData(interp, objv[2], md, NULL, HEX_FORMAT | TYPE_MD, NULL); } else { Tcl_AppendResult(interp, "Invalid digest \"", digestName, "\"", NULL); return TCL_ERROR; } } /* Get options */ |
︙ | ︙ | |||
1214 1215 1216 1217 1218 1219 1220 | if (fileObj != NULL) { res = Tls_DigestFile(interp, fileObj, md, cipher, format | type, keyObj); } else if (channel != NULL) { res = Tls_DigestChannel(interp, channel, md, cipher, format | type, keyObj); } else if (cmdObj != NULL) { res = Tls_DigestInstance(interp, cmdObj, md, cipher, format | type, keyObj); } else if (dataObj != NULL) { | < < < | | 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 | if (fileObj != NULL) { res = Tls_DigestFile(interp, fileObj, md, cipher, format | type, keyObj); } else if (channel != NULL) { res = Tls_DigestChannel(interp, channel, md, cipher, format | type, keyObj); } else if (cmdObj != NULL) { res = Tls_DigestInstance(interp, cmdObj, md, cipher, format | type, keyObj); } else if (dataObj != NULL) { res = Tls_DigestData(interp, dataObj, md, cipher, format | type, keyObj); } return res; } /* *------------------------------------------------------------------- * |
︙ | ︙ | |||
1265 1266 1267 1268 1269 1270 1271 | * * Side effects: * Sets result to message digest or error message * *------------------------------------------------------------------- */ int DigestMD4Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { | > > > > | > > > > | > > > > | > > > > | > > > > | | 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 | * * Side effects: * Sets result to message digest or error message * *------------------------------------------------------------------- */ int DigestMD4Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "data"); return TCL_ERROR; } return Tls_DigestData(interp, objv[1], EVP_md4(), NULL, HEX_FORMAT | TYPE_MD, NULL); } int DigestMD5Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "data"); return TCL_ERROR; } return Tls_DigestData(interp, objv[1], EVP_md5(), NULL, HEX_FORMAT | TYPE_MD, NULL); } int DigestSHA1Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "data"); return TCL_ERROR; } return Tls_DigestData(interp, objv[1], EVP_sha1(), NULL, HEX_FORMAT | TYPE_MD, NULL); } int DigestSHA256Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "data"); return TCL_ERROR; } return Tls_DigestData(interp, objv[1], EVP_sha256(), NULL, HEX_FORMAT | TYPE_MD, NULL); } int DigestSHA512Cmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "data"); return TCL_ERROR; } return Tls_DigestData(interp, objv[1], EVP_sha512(), NULL, HEX_FORMAT | TYPE_MD, NULL); } /* *------------------------------------------------------------------- * * Tls_DigestCommands -- * |
︙ | ︙ |