mz_crypt_apple.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. /* mz_crypt_apple.c -- Crypto/hash functions for Apple
  2. Version 2.9.2, February 12, 2020
  3. part of the MiniZip project
  4. Copyright (C) 2010-2020 Nathan Moinvaziri
  5. https://github.com/nmoinvaz/minizip
  6. This program is distributed under the terms of the same license as zlib.
  7. See the accompanying LICENSE file for the full text of the license.
  8. */
  9. #include "mz.h"
  10. #include <CoreFoundation/CoreFoundation.h>
  11. #include <CommonCrypto/CommonCryptor.h>
  12. #include <CommonCrypto/CommonDigest.h>
  13. #include <CommonCrypto/CommonHMAC.h>
  14. #include <Security/Security.h>
  15. #include <Security/SecPolicy.h>
  16. /***************************************************************************/
  17. int32_t mz_crypt_rand(uint8_t *buf, int32_t size)
  18. {
  19. if (SecRandomCopyBytes(kSecRandomDefault, size, buf) != errSecSuccess)
  20. return 0;
  21. return size;
  22. }
  23. /***************************************************************************/
  24. typedef struct mz_crypt_sha_s {
  25. CC_SHA1_CTX ctx1;
  26. CC_SHA256_CTX ctx256;
  27. int32_t error;
  28. int32_t initialized;
  29. uint16_t algorithm;
  30. } mz_crypt_sha;
  31. /***************************************************************************/
  32. void mz_crypt_sha_reset(void *handle)
  33. {
  34. mz_crypt_sha *sha = (mz_crypt_sha *)handle;
  35. sha->error = 0;
  36. sha->initialized = 0;
  37. }
  38. int32_t mz_crypt_sha_begin(void *handle)
  39. {
  40. mz_crypt_sha *sha = (mz_crypt_sha *)handle;
  41. if (sha == NULL)
  42. return MZ_PARAM_ERROR;
  43. mz_crypt_sha_reset(handle);
  44. if (sha->algorithm == MZ_HASH_SHA1)
  45. sha->error = CC_SHA1_Init(&sha->ctx1);
  46. else if (sha->algorithm == MZ_HASH_SHA256)
  47. sha->error = CC_SHA256_Init(&sha->ctx256);
  48. else
  49. return MZ_PARAM_ERROR;
  50. if (!sha->error)
  51. return MZ_HASH_ERROR;
  52. sha->initialized = 1;
  53. return MZ_OK;
  54. }
  55. int32_t mz_crypt_sha_update(void *handle, const void *buf, int32_t size)
  56. {
  57. mz_crypt_sha *sha = (mz_crypt_sha *)handle;
  58. if (sha == NULL || buf == NULL || !sha->initialized)
  59. return MZ_PARAM_ERROR;
  60. if (sha->algorithm == MZ_HASH_SHA1)
  61. sha->error = CC_SHA1_Update(&sha->ctx1, buf, size);
  62. else
  63. sha->error = CC_SHA256_Update(&sha->ctx256, buf, size);
  64. if (!sha->error)
  65. return MZ_HASH_ERROR;
  66. return size;
  67. }
  68. int32_t mz_crypt_sha_end(void *handle, uint8_t *digest, int32_t digest_size)
  69. {
  70. mz_crypt_sha *sha = (mz_crypt_sha *)handle;
  71. if (sha == NULL || digest == NULL || !sha->initialized)
  72. return MZ_PARAM_ERROR;
  73. if (sha->algorithm == MZ_HASH_SHA1)
  74. {
  75. if (digest_size < MZ_HASH_SHA1_SIZE)
  76. return MZ_BUF_ERROR;
  77. sha->error = CC_SHA1_Final(digest, &sha->ctx1);
  78. }
  79. else
  80. {
  81. if (digest_size < MZ_HASH_SHA256_SIZE)
  82. return MZ_BUF_ERROR;
  83. sha->error = CC_SHA256_Final(digest, &sha->ctx256);
  84. }
  85. if (!sha->error)
  86. return MZ_HASH_ERROR;
  87. return MZ_OK;
  88. }
  89. void mz_crypt_sha_set_algorithm(void *handle, uint16_t algorithm)
  90. {
  91. mz_crypt_sha *sha = (mz_crypt_sha *)handle;
  92. sha->algorithm = algorithm;
  93. }
  94. void *mz_crypt_sha_create(void **handle)
  95. {
  96. mz_crypt_sha *sha = NULL;
  97. sha = (mz_crypt_sha *)MZ_ALLOC(sizeof(mz_crypt_sha));
  98. if (sha != NULL)
  99. {
  100. memset(sha, 0, sizeof(mz_crypt_sha));
  101. sha->algorithm = MZ_HASH_SHA256;
  102. }
  103. if (handle != NULL)
  104. *handle = sha;
  105. return sha;
  106. }
  107. void mz_crypt_sha_delete(void **handle)
  108. {
  109. mz_crypt_sha *sha = NULL;
  110. if (handle == NULL)
  111. return;
  112. sha = (mz_crypt_sha *)*handle;
  113. if (sha != NULL)
  114. {
  115. mz_crypt_sha_reset(*handle);
  116. MZ_FREE(sha);
  117. }
  118. *handle = NULL;
  119. }
  120. /***************************************************************************/
  121. typedef struct mz_crypt_aes_s {
  122. CCCryptorRef crypt;
  123. int32_t mode;
  124. int32_t error;
  125. } mz_crypt_aes;
  126. /***************************************************************************/
  127. void mz_crypt_aes_reset(void *handle)
  128. {
  129. mz_crypt_aes *aes = (mz_crypt_aes *)handle;
  130. if (aes->crypt != NULL)
  131. CCCryptorRelease(aes->crypt);
  132. aes->crypt = NULL;
  133. }
  134. int32_t mz_crypt_aes_encrypt(void *handle, uint8_t *buf, int32_t size)
  135. {
  136. mz_crypt_aes *aes = (mz_crypt_aes *)handle;
  137. size_t data_moved = 0;
  138. if (aes == NULL || buf == NULL)
  139. return MZ_PARAM_ERROR;
  140. if (size != MZ_AES_BLOCK_SIZE)
  141. return MZ_PARAM_ERROR;
  142. aes->error = CCCryptorUpdate(aes->crypt, buf, size, buf, size, &data_moved);
  143. if (aes->error != kCCSuccess)
  144. return MZ_HASH_ERROR;
  145. return size;
  146. }
  147. int32_t mz_crypt_aes_decrypt(void *handle, uint8_t *buf, int32_t size)
  148. {
  149. mz_crypt_aes *aes = (mz_crypt_aes *)handle;
  150. size_t data_moved = 0;
  151. if (aes == NULL || buf == NULL)
  152. return MZ_PARAM_ERROR;
  153. if (size != MZ_AES_BLOCK_SIZE)
  154. return MZ_PARAM_ERROR;
  155. aes->error = CCCryptorUpdate(aes->crypt, buf, size, buf, size, &data_moved);
  156. if (aes->error != kCCSuccess)
  157. return MZ_HASH_ERROR;
  158. return size;
  159. }
  160. int32_t mz_crypt_aes_set_encrypt_key(void *handle, const void *key, int32_t key_length)
  161. {
  162. mz_crypt_aes *aes = (mz_crypt_aes *)handle;
  163. if (aes == NULL || key == NULL || key_length == 0)
  164. return MZ_PARAM_ERROR;
  165. mz_crypt_aes_reset(handle);
  166. aes->error = CCCryptorCreate(kCCEncrypt, kCCAlgorithmAES, kCCOptionECBMode,
  167. key, key_length, NULL, &aes->crypt);
  168. if (aes->error != kCCSuccess)
  169. return MZ_HASH_ERROR;
  170. return MZ_OK;
  171. }
  172. int32_t mz_crypt_aes_set_decrypt_key(void *handle, const void *key, int32_t key_length)
  173. {
  174. mz_crypt_aes *aes = (mz_crypt_aes *)handle;
  175. if (aes == NULL || key == NULL || key_length == 0)
  176. return MZ_PARAM_ERROR;
  177. mz_crypt_aes_reset(handle);
  178. aes->error = CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES, kCCOptionECBMode,
  179. key, key_length, NULL, &aes->crypt);
  180. if (aes->error != kCCSuccess)
  181. return MZ_HASH_ERROR;
  182. return MZ_OK;
  183. }
  184. void mz_crypt_aes_set_mode(void *handle, int32_t mode)
  185. {
  186. mz_crypt_aes *aes = (mz_crypt_aes *)handle;
  187. aes->mode = mode;
  188. }
  189. void *mz_crypt_aes_create(void **handle)
  190. {
  191. mz_crypt_aes *aes = NULL;
  192. aes = (mz_crypt_aes *)MZ_ALLOC(sizeof(mz_crypt_aes));
  193. if (aes != NULL)
  194. memset(aes, 0, sizeof(mz_crypt_aes));
  195. if (handle != NULL)
  196. *handle = aes;
  197. return aes;
  198. }
  199. void mz_crypt_aes_delete(void **handle)
  200. {
  201. mz_crypt_aes *aes = NULL;
  202. if (handle == NULL)
  203. return;
  204. aes = (mz_crypt_aes *)*handle;
  205. if (aes != NULL)
  206. {
  207. mz_crypt_aes_reset(*handle);
  208. MZ_FREE(aes);
  209. }
  210. *handle = NULL;
  211. }
  212. /***************************************************************************/
  213. typedef struct mz_crypt_hmac_s {
  214. CCHmacContext ctx;
  215. int32_t initialized;
  216. int32_t error;
  217. uint16_t algorithm;
  218. } mz_crypt_hmac;
  219. /***************************************************************************/
  220. static void mz_crypt_hmac_free(void *handle)
  221. {
  222. mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
  223. memset(&hmac->ctx, 0, sizeof(hmac->ctx));
  224. }
  225. void mz_crypt_hmac_reset(void *handle)
  226. {
  227. mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
  228. mz_crypt_hmac_free(handle);
  229. hmac->error = 0;
  230. }
  231. int32_t mz_crypt_hmac_init(void *handle, const void *key, int32_t key_length)
  232. {
  233. mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
  234. CCHmacAlgorithm algorithm = 0;
  235. if (hmac == NULL || key == NULL)
  236. return MZ_PARAM_ERROR;
  237. mz_crypt_hmac_reset(handle);
  238. if (hmac->algorithm == MZ_HASH_SHA1)
  239. algorithm = kCCHmacAlgSHA1;
  240. else if (hmac->algorithm == MZ_HASH_SHA256)
  241. algorithm = kCCHmacAlgSHA256;
  242. else
  243. return MZ_PARAM_ERROR;
  244. CCHmacInit(&hmac->ctx, algorithm, key, key_length);
  245. return MZ_OK;
  246. }
  247. int32_t mz_crypt_hmac_update(void *handle, const void *buf, int32_t size)
  248. {
  249. mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
  250. if (hmac == NULL || buf == NULL)
  251. return MZ_PARAM_ERROR;
  252. CCHmacUpdate(&hmac->ctx, buf, size);
  253. return MZ_OK;
  254. }
  255. int32_t mz_crypt_hmac_end(void *handle, uint8_t *digest, int32_t digest_size)
  256. {
  257. mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
  258. if (hmac == NULL || digest == NULL)
  259. return MZ_PARAM_ERROR;
  260. if (hmac->algorithm == MZ_HASH_SHA1)
  261. {
  262. if (digest_size < MZ_HASH_SHA1_SIZE)
  263. return MZ_BUF_ERROR;
  264. CCHmacFinal(&hmac->ctx, digest);
  265. }
  266. else
  267. {
  268. if (digest_size < MZ_HASH_SHA256_SIZE)
  269. return MZ_BUF_ERROR;
  270. CCHmacFinal(&hmac->ctx, digest);
  271. }
  272. return MZ_OK;
  273. }
  274. void mz_crypt_hmac_set_algorithm(void *handle, uint16_t algorithm)
  275. {
  276. mz_crypt_hmac *hmac = (mz_crypt_hmac *)handle;
  277. hmac->algorithm = algorithm;
  278. }
  279. int32_t mz_crypt_hmac_copy(void *src_handle, void *target_handle)
  280. {
  281. mz_crypt_hmac *source = (mz_crypt_hmac *)src_handle;
  282. mz_crypt_hmac *target = (mz_crypt_hmac *)target_handle;
  283. if (source == NULL || target == NULL)
  284. return MZ_PARAM_ERROR;
  285. memcpy(&target->ctx, &source->ctx, sizeof(CCHmacContext));
  286. return MZ_OK;
  287. }
  288. void *mz_crypt_hmac_create(void **handle)
  289. {
  290. mz_crypt_hmac *hmac = NULL;
  291. hmac = (mz_crypt_hmac *)MZ_ALLOC(sizeof(mz_crypt_hmac));
  292. if (hmac != NULL)
  293. {
  294. memset(hmac, 0, sizeof(mz_crypt_hmac));
  295. hmac->algorithm = MZ_HASH_SHA256;
  296. }
  297. if (handle != NULL)
  298. *handle = hmac;
  299. return hmac;
  300. }
  301. void mz_crypt_hmac_delete(void **handle)
  302. {
  303. mz_crypt_hmac *hmac = NULL;
  304. if (handle == NULL)
  305. return;
  306. hmac = (mz_crypt_hmac *)*handle;
  307. if (hmac != NULL)
  308. {
  309. mz_crypt_hmac_free(*handle);
  310. MZ_FREE(hmac);
  311. }
  312. *handle = NULL;
  313. }
  314. /***************************************************************************/
  315. #if defined(MZ_ZIP_SIGNING)
  316. int32_t mz_crypt_sign(uint8_t *message, int32_t message_size, uint8_t *cert_data, int32_t cert_data_size,
  317. const char *cert_pwd, uint8_t **signature, int32_t *signature_size)
  318. {
  319. CFStringRef password_ref = NULL;
  320. CFDictionaryRef options_dict = NULL;
  321. CFDictionaryRef identity_trust = NULL;
  322. CFDataRef signature_out = NULL;
  323. CFDataRef pkcs12_data = NULL;
  324. CFArrayRef items = 0;
  325. SecIdentityRef identity = NULL;
  326. SecTrustRef trust = NULL;
  327. OSStatus status = noErr;
  328. const void *options_key[2] = { kSecImportExportPassphrase, kSecReturnRef };
  329. const void *options_values[2] = { 0, kCFBooleanTrue };
  330. int32_t err = MZ_SIGN_ERROR;
  331. if (message == NULL || cert_data == NULL || signature == NULL || signature_size == NULL)
  332. return MZ_PARAM_ERROR;
  333. *signature = NULL;
  334. *signature_size = 0;
  335. password_ref = CFStringCreateWithCString(0, cert_pwd, kCFStringEncodingUTF8);
  336. options_values[0] = password_ref;
  337. options_dict = CFDictionaryCreate(0, options_key, options_values, 2, 0, 0);
  338. if (options_dict)
  339. pkcs12_data = CFDataCreate(0, cert_data, cert_data_size);
  340. if (pkcs12_data)
  341. status = SecPKCS12Import(pkcs12_data, options_dict, &items);
  342. if (status == noErr)
  343. identity_trust = CFArrayGetValueAtIndex(items, 0);
  344. if (identity_trust)
  345. identity = (SecIdentityRef)CFDictionaryGetValue(identity_trust, kSecImportItemIdentity);
  346. if (identity)
  347. trust = (SecTrustRef)CFDictionaryGetValue(identity_trust, kSecImportItemTrust);
  348. if (trust)
  349. {
  350. status = CMSEncodeContent(identity, NULL, NULL, FALSE, 0, message, message_size, &signature_out);
  351. if (status == errSecSuccess)
  352. {
  353. *signature_size = CFDataGetLength(signature_out);
  354. *signature = (uint8_t *)MZ_ALLOC(*signature_size);
  355. memcpy(*signature, CFDataGetBytePtr(signature_out), *signature_size);
  356. err = MZ_OK;
  357. }
  358. }
  359. if (signature_out)
  360. CFRelease(signature_out);
  361. if (items)
  362. CFRelease(items);
  363. if (pkcs12_data)
  364. CFRelease(pkcs12_data);
  365. if (options_dict)
  366. CFRelease(options_dict);
  367. if (password_ref)
  368. CFRelease(password_ref);
  369. return err;
  370. }
  371. int32_t mz_crypt_sign_verify(uint8_t *message, int32_t message_size, uint8_t *signature, int32_t signature_size)
  372. {
  373. CMSDecoderRef decoder = NULL;
  374. CMSSignerStatus signer_status = 0;
  375. CFDataRef message_out = NULL;
  376. SecPolicyRef trust_policy = NULL;
  377. OSStatus status = noErr;
  378. OSStatus verify_status = noErr;
  379. size_t signer_count = 0;
  380. size_t i = 0;
  381. int32_t err = MZ_SIGN_ERROR;
  382. if (message == NULL || signature == NULL)
  383. return MZ_PARAM_ERROR;
  384. status = CMSDecoderCreate(&decoder);
  385. if (status == errSecSuccess)
  386. status = CMSDecoderUpdateMessage(decoder, signature, signature_size);
  387. if (status == errSecSuccess)
  388. status = CMSDecoderFinalizeMessage(decoder);
  389. if (status == errSecSuccess)
  390. trust_policy = SecPolicyCreateBasicX509();
  391. if (status == errSecSuccess && trust_policy)
  392. {
  393. CMSDecoderGetNumSigners(decoder, &signer_count);
  394. if (signer_count > 0)
  395. err = MZ_OK;
  396. for (i = 0; i < signer_count; i += 1)
  397. {
  398. status = CMSDecoderCopySignerStatus(decoder, i, trust_policy, TRUE, &signer_status, NULL, &verify_status);
  399. if (status != errSecSuccess || verify_status != 0 || signer_status != kCMSSignerValid)
  400. {
  401. err = MZ_SIGN_ERROR;
  402. break;
  403. }
  404. }
  405. }
  406. if (err == MZ_OK)
  407. {
  408. status = CMSDecoderCopyContent(decoder, &message_out);
  409. if ((status != errSecSuccess) ||
  410. (CFDataGetLength(message_out) != message_size) ||
  411. (memcmp(message, CFDataGetBytePtr(message_out), message_size) != 0))
  412. err = MZ_SIGN_ERROR;
  413. }
  414. if (trust_policy)
  415. CFRelease(trust_policy);
  416. if (decoder)
  417. CFRelease(decoder);
  418. return err;
  419. }
  420. #endif