889 return key; |
889 return key; |
890 } |
890 } |
891 |
891 |
892 #endif |
892 #endif |
893 |
893 |
|
894 /* -------------------- Windows Crypto Functions -------------------- */ |
|
895 #ifdef DAV_CRYPTO_CNG |
|
896 |
|
897 static void cng_cleanup(BCRYPT_ALG_HANDLE hAesAlg, BCRYPT_KEY_HANDLE hKey, BCRYPT_HASH_HANDLE hHash, void *pbObject) { |
|
898 if(hAesAlg) { |
|
899 BCryptCloseAlgorithmProvider(hAesAlg,0); |
|
900 } |
|
901 if(hKey) { |
|
902 BCryptDestroyKey(hKey); |
|
903 } |
|
904 if(hHash) { |
|
905 BCryptDestroyHash(hHash); |
|
906 } |
|
907 if(pbObject) { |
|
908 free(pbObject); |
|
909 } |
|
910 } |
|
911 |
|
912 static int cng_init_key(BCRYPT_ALG_HANDLE *alg, BCRYPT_KEY_HANDLE *key, void **keyobj, DavKey *aesKey) { |
|
913 BCRYPT_ALG_HANDLE hAesAlg = NULL; |
|
914 BCRYPT_KEY_HANDLE hKey = NULL; |
|
915 |
|
916 void *pbKeyObject = NULL; |
|
917 ULONG keyObjectLength = 0; |
|
918 |
|
919 ULONG result = 0; |
|
920 |
|
921 // check DavKey and get AES key length |
|
922 if(!aesKey) { |
|
923 return 1; |
|
924 } |
|
925 |
|
926 ULONG aesKeyLength = 0; |
|
927 if(aesKey->type == DAV_KEY_AES128) { |
|
928 aesKeyLength = 16; |
|
929 } else if(aesKey->type == DAV_KEY_AES256) { |
|
930 aesKeyLength = 32; |
|
931 } |
|
932 if(aesKeyLength > aesKey->length || !aesKey->data) { |
|
933 // invalid DavKey |
|
934 return 1; |
|
935 } |
|
936 |
|
937 // initialize BCrypt stuff |
|
938 if(BCryptOpenAlgorithmProvider(&hAesAlg, BCRYPT_AES_ALGORITHM, NULL, 0)) { |
|
939 fprintf(stderr, "Error: BCryptOpenAlgorithmProvider failed\n"); |
|
940 return 1; |
|
941 } |
|
942 |
|
943 if(BCryptGetProperty(hAesAlg, BCRYPT_OBJECT_LENGTH, (PUCHAR)&keyObjectLength, sizeof(DWORD), &result, 0)) { |
|
944 fprintf(stderr, "Error: BCrypt: Cannot get BCRYPT_OBJECT_LENGTH\n"); |
|
945 cng_cleanup(hAesAlg, hKey, NULL, pbKeyObject); |
|
946 return 1; |
|
947 } |
|
948 |
|
949 if(BCryptSetProperty(hAesAlg, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0)) { |
|
950 fprintf(stderr, "Error: BCrypt: Cannot set CBC mode\n"); |
|
951 cng_cleanup(hAesAlg, hKey, NULL, pbKeyObject); |
|
952 return 1; |
|
953 } |
|
954 |
|
955 pbKeyObject = calloc(1, keyObjectLength); |
|
956 if(!pbKeyObject) { |
|
957 cng_cleanup(hAesAlg, hKey, NULL, pbKeyObject); |
|
958 return 1; |
|
959 } |
|
960 |
|
961 // init key |
|
962 if(BCryptGenerateSymmetricKey(hAesAlg, &hKey, pbKeyObject, keyObjectLength, aesKey->data, aesKeyLength, 0)) { |
|
963 fprintf(stderr, "Error: BCrypt: Cannot set key\n"); |
|
964 cng_cleanup(hAesAlg, hKey, NULL, pbKeyObject); |
|
965 return 1; |
|
966 } |
|
967 |
|
968 *alg = hAesAlg; |
|
969 *key = hKey; |
|
970 *keyobj = pbKeyObject; |
|
971 |
|
972 return 0; |
|
973 } |
|
974 |
|
975 static int cng_hash_init(WinBCryptSHACTX *ctx) { |
|
976 if(BCryptOpenAlgorithmProvider(&ctx->hAlg, BCRYPT_SHA256_ALGORITHM, NULL, 0)) { |
|
977 fprintf(stderr, "Error: BCryptOpenAlgorithmProvider failed\n"); |
|
978 return 1; |
|
979 } |
|
980 |
|
981 ULONG hashObjectLen; |
|
982 ULONG result; |
|
983 if(BCryptGetProperty(ctx->hAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&hashObjectLen, sizeof(DWORD), &result, 0)) { |
|
984 cng_cleanup(ctx->hAlg, NULL, NULL, NULL); |
|
985 return 1; |
|
986 } |
|
987 |
|
988 ctx->pbHashObject = calloc(1, hashObjectLen); |
|
989 |
|
990 if(BCryptCreateHash(ctx->hAlg, &ctx->hHash, ctx->pbHashObject, hashObjectLen, NULL, 0, 0)) { |
|
991 cng_cleanup(ctx->hAlg, NULL, ctx->hHash, ctx->pbHashObject); |
|
992 return 1; |
|
993 } |
|
994 |
|
995 return 0; |
|
996 } |
|
997 |
|
998 |
|
999 int dav_rand_bytes(unsigned char *buf, size_t len) { |
|
1000 if(BCryptGenRandom(NULL, (unsigned char*)buf, (ULONG)len, BCRYPT_USE_SYSTEM_PREFERRED_RNG)) { |
|
1001 return 1; |
|
1002 } |
|
1003 return 0; |
|
1004 } |
|
1005 |
|
1006 AESDecrypter* aes_decrypter_new(DavKey *key, void *stream, dav_write_func write_func) { |
|
1007 AESDecrypter *dec = calloc(1, sizeof(AESDecrypter)); |
|
1008 if(!dec) { |
|
1009 return NULL; |
|
1010 } |
|
1011 if(cng_hash_init(&dec->sha256)) { |
|
1012 free(dec); |
|
1013 return NULL; |
|
1014 } |
|
1015 |
|
1016 dec->stream = stream; |
|
1017 dec->write = write_func; |
|
1018 dec->key = key; |
|
1019 dec->init = 0; |
|
1020 dec->ivpos = 0; |
|
1021 |
|
1022 return dec; |
|
1023 } |
|
1024 |
|
1025 static void aes_decrypter_init(AESDecrypter *dec) { |
|
1026 if(cng_init_key(&dec->ctx.hAlg, &dec->ctx.hKey, &dec->ctx.pbKeyObject, dec->key)) { |
|
1027 fprintf(stderr, "Error: cng_init_key failed\n"); |
|
1028 exit(-1); |
|
1029 } |
|
1030 // copy iv |
|
1031 memcpy(dec->ctx.pbIV, dec->ivtmp, 16); |
|
1032 } |
|
1033 |
|
1034 size_t aes_write(const void *buf, size_t s, size_t n, AESDecrypter *dec) { |
|
1035 int len = s*n; |
|
1036 if(!dec->init) { |
|
1037 size_t n = 16 - dec->ivpos; |
|
1038 size_t cp = n > len ? len : n; |
|
1039 memcpy(dec->ivtmp + dec->ivpos, buf, cp); |
|
1040 dec->ivpos += cp; |
|
1041 if(dec->ivpos >= 16) { |
|
1042 aes_decrypter_init(dec); |
|
1043 } |
|
1044 if(len == cp) { |
|
1045 return len; |
|
1046 } else { |
|
1047 buf = (char*)buf + cp; |
|
1048 len -= cp; |
|
1049 } |
|
1050 } |
|
1051 |
|
1052 // the cipher text must be a multiply of 16 |
|
1053 // remaining bytes are stored in ctx.buf and must be added to cibuf |
|
1054 // the next time |
|
1055 size_t cbufalloc = len + 32; |
|
1056 ULONG clen = 0; |
|
1057 char *cbuf = malloc(cbufalloc); |
|
1058 |
|
1059 // add previous remaining bytes |
|
1060 if(dec->ctx.buflen > 0) { |
|
1061 memcpy(cbuf, dec->ctx.buf, dec->ctx.buflen); |
|
1062 clen = dec->ctx.buflen; |
|
1063 } |
|
1064 // add current bytes |
|
1065 memcpy(cbuf + clen, buf, len); |
|
1066 clen += len; |
|
1067 |
|
1068 // check if the message fits the blocksize |
|
1069 int remaining = clen % 16; |
|
1070 if(remaining > 0) { |
|
1071 // add remaining bytes to ctx.buf for the next aes_write run |
|
1072 clen -= remaining; |
|
1073 memcpy(dec->ctx.buf, cbuf + clen - remaining, remaining); |
|
1074 } |
|
1075 dec->ctx.buflen = remaining; |
|
1076 |
|
1077 // ready to decrypt the message |
|
1078 ULONG outlen = clen + 32; |
|
1079 unsigned char *out = malloc(outlen); |
|
1080 |
|
1081 // decrypt |
|
1082 if(clen > 0) { |
|
1083 if(BCryptDecrypt(dec->ctx.hKey, cbuf, clen, NULL, dec->ctx.pbIV, 16, out, outlen, &outlen, BCRYPT_BLOCK_PADDING)) { |
|
1084 fprintf(stderr, "Error: BCryptDecrypt failed\n"); |
|
1085 free(out); |
|
1086 free(cbuf); |
|
1087 return 0; |
|
1088 } |
|
1089 } |
|
1090 |
|
1091 // write decrypted data to the output stream and update the hash |
|
1092 dec->write(out, 1, outlen, dec->stream); |
|
1093 BCryptHashData(dec->sha256.hHash, out, outlen, 0); |
|
1094 free(out); |
|
1095 free(cbuf); |
|
1096 |
|
1097 return (s*n) / s; |
|
1098 } |
|
1099 |
|
1100 void aes_decrypter_shutdown(AESDecrypter *dec) { |
|
1101 if(dec->init && dec->ctx.buflen > 0) { |
|
1102 ULONG outlen = 64; |
|
1103 char out[64]; |
|
1104 if(BCryptDecrypt(dec->ctx.hKey, dec->ctx.buf, dec->ctx.buflen, NULL, dec->ctx.pbIV, 16, out, outlen, &outlen, BCRYPT_BLOCK_PADDING)) { |
|
1105 fprintf(stderr, "Error: BCryptDecrypt failed\n"); |
|
1106 return; |
|
1107 } |
|
1108 dec->write(out, 1, outlen, dec->stream); |
|
1109 BCryptHashData(dec->sha256.hHash, out, outlen, 0); |
|
1110 } |
|
1111 } |
|
1112 |
|
1113 void aes_decrypter_close(AESDecrypter *dec) { |
|
1114 cng_cleanup(dec->ctx.hAlg, dec->ctx.hKey, NULL, dec->ctx.pbKeyObject); |
|
1115 cng_cleanup(dec->sha256.hAlg, NULL, dec->sha256.hHash, dec->sha256.pbHashObject); |
|
1116 free(dec); |
|
1117 } |
|
1118 |
|
1119 AESEncrypter* aes_encrypter_new(DavKey *key, void *stream, dav_read_func read_func, dav_seek_func seek_func) { |
|
1120 unsigned char *iv = malloc(16); |
|
1121 if(dav_rand_bytes(iv, 16)) { |
|
1122 free(iv); |
|
1123 return NULL; |
|
1124 } |
|
1125 |
|
1126 AESEncrypter *enc = calloc(1, sizeof(AESEncrypter)); |
|
1127 if(cng_hash_init(&enc->sha256)) { |
|
1128 free(iv); |
|
1129 free(enc); |
|
1130 return NULL; |
|
1131 } |
|
1132 |
|
1133 enc->stream = stream; |
|
1134 enc->read = read_func; |
|
1135 enc->seek = seek_func; |
|
1136 enc->tmp = NULL; |
|
1137 enc->tmplen = 0; |
|
1138 enc->tmpoff = 0; |
|
1139 enc->end = 0; |
|
1140 enc->iv = iv; |
|
1141 enc->ivlen = 0; |
|
1142 |
|
1143 if(cng_init_key(&enc->ctx.hAlg, &enc->ctx.hKey, &enc->ctx.pbKeyObject, key)) { |
|
1144 fprintf(stderr, "Error: cng_init_key failed\n"); |
|
1145 exit(-1); |
|
1146 } |
|
1147 |
|
1148 enc->ctx.buflen = 0; |
|
1149 memcpy(enc->ctx.pbIV, iv, 16); |
|
1150 |
|
1151 return enc; |
|
1152 } |
|
1153 |
|
1154 size_t aes_read(void *buf, size_t s, size_t n, AESEncrypter *enc) { |
|
1155 size_t len = s*n; |
|
1156 size_t nread = 0; |
|
1157 |
|
1158 if(enc->tmp) { |
|
1159 // the temp buffer contains bytes that are already encrypted, but |
|
1160 // the last aes_read had not enough read buffer space |
|
1161 |
|
1162 // in case we have a tmp buf, we just return this |
|
1163 size_t tmp_diff = enc->tmplen - enc->tmpoff; |
|
1164 size_t cp_len = tmp_diff > len ? len : tmp_diff; |
|
1165 memcpy(buf, enc->tmp + enc->tmpoff, cp_len); |
|
1166 enc->tmpoff += cp_len; |
|
1167 if(enc->tmpoff >= enc->tmplen) { |
|
1168 free(enc->tmp); |
|
1169 enc->tmp = NULL; |
|
1170 enc->tmplen = 0; |
|
1171 enc->tmpoff = 0; |
|
1172 } |
|
1173 return cp_len / s; |
|
1174 } |
|
1175 |
|
1176 if(enc->ivlen < 16) { |
|
1177 size_t copy_iv_len = 16 - enc->ivlen; |
|
1178 copy_iv_len = len > copy_iv_len ? copy_iv_len : len; |
|
1179 |
|
1180 memcpy(buf, enc->iv, copy_iv_len); |
|
1181 buf += copy_iv_len; |
|
1182 len -= copy_iv_len; |
|
1183 nread = copy_iv_len; |
|
1184 |
|
1185 enc->ivlen += copy_iv_len; |
|
1186 |
|
1187 if(len == 0) { |
|
1188 return copy_iv_len / s; |
|
1189 } |
|
1190 } |
|
1191 |
|
1192 if(enc->end) { |
|
1193 return 0; |
|
1194 } |
|
1195 |
|
1196 size_t remaining = len % 16; |
|
1197 len -= remaining; |
|
1198 |
|
1199 size_t inalloc = len; |
|
1200 ULONG inlen = 0; |
|
1201 unsigned char *in = malloc(inalloc); |
|
1202 |
|
1203 // fill the input buffer |
|
1204 while(inlen < inalloc) { |
|
1205 size_t r = enc->read(in + inlen, 1, inalloc - inlen, enc->stream); |
|
1206 if(r == 0) { |
|
1207 enc->end = 1; |
|
1208 break; |
|
1209 } |
|
1210 inlen += r; |
|
1211 } |
|
1212 |
|
1213 if(inlen == 0) { |
|
1214 return nread / s; |
|
1215 } |
|
1216 |
|
1217 // hash read data |
|
1218 BCryptHashData(enc->sha256.hHash, in, inlen, 0); |
|
1219 |
|
1220 // create output buffer |
|
1221 ULONG outalloc = inlen + 16; |
|
1222 ULONG outlen = 0; |
|
1223 char *out = malloc(outalloc); |
|
1224 |
|
1225 // encrypt |
|
1226 if(BCryptEncrypt(enc->ctx.hKey, in, inlen, NULL, enc->ctx.pbIV, 16, out, outalloc, &outlen, BCRYPT_BLOCK_PADDING)) { |
|
1227 fprintf(stderr, "Error: BCryptEncrypt failed\n"); |
|
1228 } |
|
1229 |
|
1230 // check if the output fits in buf, if not, save the remaining bytes in tmp |
|
1231 if(outlen > len) { |
|
1232 size_t tmplen = outlen - len; |
|
1233 char *tmp = malloc(tmplen); |
|
1234 memcpy(tmp, out+len, tmplen); |
|
1235 |
|
1236 enc->tmp = tmp; |
|
1237 enc->tmplen = tmplen; |
|
1238 enc->tmpoff = 0; |
|
1239 |
|
1240 outlen = len; |
|
1241 } |
|
1242 |
|
1243 // fill read buffer and return |
|
1244 memcpy(buf, out, outlen); |
|
1245 nread += outlen; |
|
1246 |
|
1247 free(in); |
|
1248 free(out); |
|
1249 |
|
1250 return nread / s; |
|
1251 } |
|
1252 |
|
1253 void aes_encrypter_close(AESEncrypter *enc) { |
|
1254 enc->end = 1; |
|
1255 } |
|
1256 |
|
1257 int aes_encrypter_reset(AESEncrypter *enc, curl_off_t offset, int origin) { |
|
1258 if(origin != SEEK_SET || offset != 0 || !enc->seek) { |
|
1259 return CURL_SEEKFUNC_CANTSEEK; |
|
1260 } |
|
1261 |
|
1262 enc->ivlen = 0; |
|
1263 memcpy(enc->ctx.pbIV, enc->iv, 16); |
|
1264 if(enc->seek(enc->stream, 0, SEEK_SET) != 0) { |
|
1265 return CURL_SEEKFUNC_FAIL; |
|
1266 } |
|
1267 return CURL_SEEKFUNC_OK; |
|
1268 } |
|
1269 |
|
1270 char* aes_encrypt(const char *in, size_t len, DavKey *key) { |
|
1271 // create random IV |
|
1272 char iv[16]; |
|
1273 if(dav_rand_bytes(iv, 16)) { |
|
1274 return NULL; |
|
1275 } |
|
1276 |
|
1277 // initialize bcrypt stuff |
|
1278 BCRYPT_ALG_HANDLE hAlg = NULL; |
|
1279 BCRYPT_KEY_HANDLE hKey = NULL; |
|
1280 void *pbKeyObject = NULL; |
|
1281 if(cng_init_key(&hAlg, &hKey, &pbKeyObject, key)) { |
|
1282 return NULL; |
|
1283 } |
|
1284 |
|
1285 // create output buffer |
|
1286 ULONG outlen = len + 128; |
|
1287 char *out = malloc(outlen); |
|
1288 |
|
1289 // the output must start with the IV |
|
1290 memcpy(out, iv, 16); |
|
1291 char *encbuf = out + 16; |
|
1292 ULONG enclen = outlen - 16; |
|
1293 ULONG encoutlen = 0; |
|
1294 |
|
1295 // encrypt |
|
1296 if(BCryptEncrypt(hKey, (PUCHAR)in, len, NULL, (PUCHAR)iv, 16, encbuf, enclen, &encoutlen, BCRYPT_BLOCK_PADDING)) { |
|
1297 fprintf(stderr, "Error: BCryptEncrypt failed\n"); |
|
1298 cng_cleanup(hAlg, hKey, NULL, pbKeyObject); |
|
1299 free(out); |
|
1300 return NULL; |
|
1301 } |
|
1302 |
|
1303 outlen = encoutlen + 16; // length of encrypted data + 16 bytes IV |
|
1304 |
|
1305 // base64 encode |
|
1306 char *outstr = util_base64encode(out, outlen); |
|
1307 |
|
1308 cng_cleanup(hAlg, hKey, NULL, pbKeyObject); |
|
1309 free(out); |
|
1310 |
|
1311 return outstr; |
|
1312 } |
|
1313 |
|
1314 char* aes_decrypt(const char *in, size_t *len, DavKey *key) { |
|
1315 BCRYPT_ALG_HANDLE hAlg = NULL; |
|
1316 BCRYPT_KEY_HANDLE hKey = NULL; |
|
1317 void *pbKeyObject = NULL; |
|
1318 if(cng_init_key(&hAlg, &hKey, &pbKeyObject, key)) { |
|
1319 return NULL; |
|
1320 } |
|
1321 |
|
1322 int inlen; |
|
1323 unsigned char *buf = (unsigned char*)util_base64decode_len(in, &inlen); |
|
1324 if(inlen < 16 || !buf) { |
|
1325 cng_cleanup(hAlg, hKey, NULL, pbKeyObject); |
|
1326 if(buf) { |
|
1327 free(buf); |
|
1328 } |
|
1329 return NULL; |
|
1330 } |
|
1331 |
|
1332 // encrypted data starts with IV |
|
1333 char iv[16]; |
|
1334 memcpy(iv, buf, 16); |
|
1335 |
|
1336 // decrypt data |
|
1337 char *data = buf + 16; // encrypted data starts after IV |
|
1338 size_t datalen = inlen - 16; |
|
1339 |
|
1340 // create output buffer |
|
1341 ULONG outlen = inlen; |
|
1342 char *out = malloc(outlen + 1); |
|
1343 |
|
1344 // decrypt |
|
1345 if(BCryptDecrypt(hKey, data, datalen, NULL, iv, 16, out, outlen, &outlen, BCRYPT_BLOCK_PADDING)) { |
|
1346 cng_cleanup(hAlg, hKey, NULL, pbKeyObject); |
|
1347 free(out); |
|
1348 free(buf); |
|
1349 return NULL; |
|
1350 } |
|
1351 |
|
1352 // decrypt finished, return |
|
1353 out[outlen] = 0; |
|
1354 *len = (size_t)outlen; |
|
1355 return out; |
|
1356 } |
|
1357 |
|
1358 void dav_get_hash(DAV_SHA_CTX *sha256, unsigned char *buf) { |
|
1359 BCryptFinishHash(sha256->hHash, buf, DAV_SHA256_DIGEST_LENGTH, 0); |
|
1360 } |
|
1361 |
|
1362 |
|
1363 char* dav_create_hash(const char *data, size_t len) { |
|
1364 unsigned char hash[DAV_SHA256_DIGEST_LENGTH]; |
|
1365 DAV_SHA_CTX *ctx = dav_hash_init(); |
|
1366 if(ctx) { |
|
1367 dav_hash_update(ctx, data, len); |
|
1368 dav_hash_final(ctx, hash); |
|
1369 } |
|
1370 return util_hexstr(hash, DAV_SHA256_DIGEST_LENGTH); |
|
1371 } |
|
1372 |
|
1373 DAV_SHA_CTX* dav_hash_init(void) { |
|
1374 DAV_SHA_CTX *ctx = malloc(sizeof(DAV_SHA_CTX)); |
|
1375 if(!ctx) { |
|
1376 return NULL; |
|
1377 } |
|
1378 if(cng_hash_init(ctx)) { |
|
1379 free(ctx); |
|
1380 return NULL; |
|
1381 } |
|
1382 return ctx; |
|
1383 } |
|
1384 |
|
1385 void dav_hash_update(DAV_SHA_CTX *ctx, const char *data, size_t len) { |
|
1386 BCryptHashData(ctx->hHash, (PUCHAR)data, len, 0); |
|
1387 } |
|
1388 |
|
1389 void dav_hash_final(DAV_SHA_CTX *ctx, unsigned char *buf) { |
|
1390 BCryptFinishHash(ctx->hHash, (PUCHAR)buf, DAV_SHA256_DIGEST_LENGTH, 0); |
|
1391 |
|
1392 // cleanup |
|
1393 cng_cleanup(ctx->hAlg, NULL, ctx->hHash, ctx->pbHashObject); |
|
1394 free(ctx); |
|
1395 } |
|
1396 |
|
1397 DavKey* dav_pw2key(const char *password, const unsigned char *salt, int saltlen, int pwfunc, int enc) { |
|
1398 if(!password) { |
|
1399 return NULL; |
|
1400 } |
|
1401 size_t len = strlen(password); |
|
1402 if(len == 0) { |
|
1403 return NULL; |
|
1404 } |
|
1405 |
|
1406 // setup key data and length |
|
1407 unsigned char keydata[128]; |
|
1408 int keylen = 32; |
|
1409 switch(enc) { |
|
1410 case DAV_KEY_AES128: keylen = 16; break; |
|
1411 case DAV_KEY_AES256: keylen = 32; break; |
|
1412 default: return NULL; |
|
1413 } |
|
1414 |
|
1415 LPCWSTR algid; |
|
1416 switch(pwfunc) { |
|
1417 case DAV_PWFUNC_PBKDF2_SHA256: algid = BCRYPT_SHA256_ALGORITHM; break; |
|
1418 case DAV_PWFUNC_PBKDF2_SHA512: algid = BCRYPT_SHA512_ALGORITHM; break; |
|
1419 default: return NULL; |
|
1420 } |
|
1421 |
|
1422 // open algorithm provider |
|
1423 BCRYPT_ALG_HANDLE hAlg; |
|
1424 ULONG status = BCryptOpenAlgorithmProvider(&hAlg, algid, NULL, BCRYPT_ALG_HANDLE_HMAC_FLAG); |
|
1425 if(status > 0) { |
|
1426 fprintf(stderr, "Error: dav_pw2key: BCryptOpenAlgorithmProvider failed: 0x%X\n", (unsigned int)status); |
|
1427 return NULL; |
|
1428 } |
|
1429 |
|
1430 // derive key |
|
1431 status = BCryptDeriveKeyPBKDF2( |
|
1432 hAlg, |
|
1433 (PUCHAR)password, |
|
1434 len, |
|
1435 (PUCHAR)salt, |
|
1436 saltlen, |
|
1437 DAV_CRYPTO_ITERATION_COUNT, |
|
1438 keydata, |
|
1439 128, |
|
1440 0); |
|
1441 |
|
1442 BCryptCloseAlgorithmProvider(hAlg,0); |
|
1443 |
|
1444 if(status) { |
|
1445 fprintf(stderr, "Error: dav_pw2key: BCryptDeriveKeyPBKDF2 failed: 0x%X\n", (unsigned int)status); |
|
1446 return NULL; |
|
1447 } |
|
1448 |
|
1449 // create DavKey with generated data |
|
1450 DavKey *key = malloc(sizeof(DavKey)); |
|
1451 key->data = malloc(keylen); |
|
1452 key->length = keylen; |
|
1453 key->name = NULL; |
|
1454 key->type = enc; |
|
1455 memcpy(key->data, keydata, keylen); |
|
1456 return key; |
|
1457 } |
|
1458 #endif |
|
1459 |
|
1460 |
|
1461 |
894 UcxBuffer* aes_encrypt_buffer(UcxBuffer *in, DavKey *key) { |
1462 UcxBuffer* aes_encrypt_buffer(UcxBuffer *in, DavKey *key) { |
895 UcxBuffer *encbuf = ucx_buffer_new( |
1463 UcxBuffer *encbuf = ucx_buffer_new( |
896 NULL, |
1464 NULL, |
897 in->size+16, |
1465 in->size+16, |
898 UCX_BUFFER_AUTOEXTEND); |
1466 UCX_BUFFER_AUTOEXTEND); |