pegh is a file encryption tool using passwords with modern, standardized, and authenticated encryption.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1488 lines
50 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. /*
  2. * pegh is a file encryption tool using passwords and authenticated encryption
  3. * Copyright (C) 2019 Travis Burtrum
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. * You should have received a copy of the GNU Affero General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. /* compile with: cc pegh.c -lcrypto -O3 -o pegh */
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19. #include <limits.h>
  20. #include <errno.h>
  21. #if !defined(_WIN32) && (_POSIX_C_SOURCE >= 1 || _XOPEN_SOURCE || _POSIX_SOURCE)
  22. #define USE_TERMIOS 1
  23. #endif
  24. #ifdef USE_TERMIOS
  25. #include <termios.h>
  26. #endif
  27. #ifdef _WIN32
  28. #include <windows.h>
  29. #include <io.h>
  30. #include <fcntl.h>
  31. #define STDIN 0
  32. #define STDOUT 1
  33. #endif
  34. /* default of OpenSSL for now... */
  35. #if !defined(PEGH_OPENSSL) && !defined(PEGH_LIBSODIUM)
  36. #define PEGH_OPENSSL 1
  37. #endif
  38. #ifdef PEGH_OPENSSL
  39. #include <openssl/conf.h>
  40. #include <openssl/evp.h>
  41. #include <openssl/err.h>
  42. #include <openssl/rand.h>
  43. #endif /* PEGH_OPENSSL */
  44. #ifdef PEGH_LIBSODIUM
  45. #include <sodium.h>
  46. #endif /* PEGH_LIBSODIUM */
  47. /*
  48. * tweak default scrypt hardness params here
  49. *
  50. * https://tools.ietf.org/html/rfc7914#section-2
  51. * https://blog.filippo.io/the-scrypt-parameters/
  52. */
  53. const uint32_t SCRYPT_N = 32768;
  54. const uint8_t SCRYPT_R = 8;
  55. const uint8_t SCRYPT_P = 1;
  56. const size_t SCRYPT_MAX_MEM = 1024 * 1024 * 64; /* 64 megabytes */
  57. /* memory use will be twice this */
  58. const uint32_t DEFAULT_CHUNK_SIZE_MB = 32;
  59. /*
  60. * this should be increased regularly, and only checked on encryption
  61. * to allow old archives to be decrypted with shorter passwords
  62. */
  63. const size_t MINIMUM_PASSWORD_LEN = 12;
  64. /* technically they can only enter at most 2 less than this */
  65. const size_t MANUAL_ENTRY_PASSWORD_MAX_LEN = 66;
  66. /*
  67. * pegh file format, numbers are inclusive 0-based byte array indices
  68. *
  69. * 0th byte is always version number, everything else depends on version number
  70. *
  71. * |------------------------------------------------------------------------------------------------------|
  72. * | Version 0, scrypt key derivation, AES-256-GCM encryption, 43 byte header, 16 byte auth tag per chunk |
  73. * | The 12-byte IV for the first chunk is 0, and is incremented by 1 for each successive chunk, if it |
  74. * | ever rolls back over to 0 encryption should be aborted (chunk size should be increased). The last |
  75. * | chunk has Additional Authenticated Data (AAD) sent in, a single byte value 0, which is used to flag |
  76. * | the last chunk and detect file truncation. |
  77. * |--------------|---------------------------------------------|-----------------------------------------|
  78. * | indices | format | value interpretation |
  79. * |--------------|---------------------------------------------|-----------------------------------------|
  80. * | 0 | 8 bit unsigned byte | pegh file format version |
  81. * | 1-4 | 32 bit unsigned integer in big endian order | scrypt N parameter |
  82. * | 5 | 8 bit unsigned byte | scrypt r parameter |
  83. * | 6 | 8 bit unsigned byte | scrypt p parameter |
  84. * | 7-10 | 32 bit unsigned integer in big endian order | aes encrypted chunk size |
  85. * | 11-42 | 32 randomly generated bytes | scrypt key derivation seed |
  86. * | 43+end | any number of chunks, chunk_size + 16 long | chunks followed by AES-256-GCM auth tag |
  87. * |------------------------------------------------------------------------------------------------------|
  88. *
  89. * Version 1 has the exact same structure as version 0, except Chacha20-Poly1305 encryption instead of AES-256-GCM,
  90. * key, IV, tag lengths are all the same.
  91. */
  92. /* don't touch below here unless you know what you are doing */
  93. #define PEGH_VERSION "0.9.3"
  94. /* 256 bit key required for AES-256 */
  95. #define KEY_LEN 32
  96. /* 1 for file format version, 4 for N, 1 for r, 1 for p, 4 for block/buffer size */
  97. const size_t PRE_SALT_LEN = 11;
  98. /* from libsodium's crypto_pwhash_scryptsalsa208sha256_SALTBYTES */
  99. #define SALT_LEN 32
  100. /* AES-GCM/Chacha20-Poly1305 should only ever have an IV_LEN of 12 */
  101. #define IV_LEN 12
  102. const size_t AEAD_TAG_LEN = 16;
  103. /* libsodium only supports AES on specific platforms, this jazz is to fallback to openssl impls in those cases */
  104. typedef int (*aead_func)(const unsigned char *, const size_t,
  105. const unsigned char *, const unsigned char *,
  106. const unsigned char*, const size_t,
  107. unsigned char *, unsigned char *
  108. );
  109. typedef int (*stream_func)(const aead_func, const unsigned char *, unsigned char *, size_t,
  110. unsigned char *, unsigned char *,
  111. FILE *, FILE *, FILE *
  112. );
  113. #ifdef PEGH_OPENSSL
  114. /* this is because we read up to buffer_size at once, and then send that value to openssl which uses int instead of size_t, limit of 2gb */
  115. static const size_t CHUNK_SIZE_MAX_OPENSSL_GCM = INT_MAX;
  116. /* if libsodium is around we use it's chacha impl */
  117. #ifndef PEGH_LIBSODIUM
  118. static const size_t CHUNK_SIZE_MAX_CHACHA = INT_MAX;
  119. #endif
  120. /*
  121. * returns 1 on success, 0 on failure
  122. *
  123. * these will be read from:
  124. * plaintext
  125. * plaintext_len
  126. * key must be length KEY_LEN
  127. * iv must be length IV_LEN
  128. *
  129. * these will be written into:
  130. * ciphertext must have the capacity of at least plaintext_len
  131. * tag must have the capacity of at least AEAD_TAG_LEN
  132. */
  133. int aead_encrypt_openssl(const EVP_CIPHER *type, const unsigned char *plaintext, const size_t plaintext_len,
  134. const unsigned char *key,
  135. const unsigned char *iv,
  136. const unsigned char* aad, const size_t aad_len,
  137. unsigned char *ciphertext,
  138. unsigned char *tag
  139. )
  140. {
  141. EVP_CIPHER_CTX *ctx;
  142. int ciphertext_written, ret = 0;
  143. do {
  144. /* Create and initialise the context */
  145. if(!(ctx = EVP_CIPHER_CTX_new()))
  146. break;
  147. /* Initialise the encryption operation. */
  148. if(1 != EVP_EncryptInit_ex(ctx, type, NULL, NULL, NULL))
  149. break;
  150. /* Setting IV length is not necessary because the default of 12 bytes (96 bits) will be used
  151. if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, IV_LEN, NULL))
  152. break;
  153. */
  154. /* Initialise key and IV */
  155. if(1 != EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv))
  156. break;
  157. if(aad_len > 0) {
  158. /*
  159. * Provide any AAD data. This can be called zero or more times as
  160. * required
  161. */
  162. if(1 != EVP_EncryptUpdate(ctx, NULL, &ciphertext_written, aad, (int) aad_len))
  163. break;
  164. }
  165. /*
  166. * Provide the message to be encrypted, and obtain the encrypted output.
  167. * EVP_EncryptUpdate can be called multiple times if necessary
  168. */
  169. if(1 != EVP_EncryptUpdate(ctx, ciphertext, &ciphertext_written, plaintext, (int) plaintext_len))
  170. break;
  171. /* if this isn't true, GCM is broken, we probably don't need to check...
  172. if(ciphertext_written != plaintext_len) {
  173. if(NULL != err)
  174. fprintf(err, "ciphertext_written (%d) != plaintext_len (%d)\n", ciphertext_written, plaintext_len);
  175. break;
  176. }
  177. */
  178. /*
  179. * Finalise the encryption. Normally ciphertext bytes may be written at
  180. * this stage, but this does not occur in GCM mode
  181. */
  182. if(1 != EVP_EncryptFinal_ex(ctx, NULL, &ciphertext_written))
  183. break;
  184. /* Get the tag */
  185. ret = EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, AEAD_TAG_LEN, tag);
  186. } while(0);
  187. /* Clean up */
  188. if(ctx)
  189. EVP_CIPHER_CTX_free(ctx);
  190. return ret;
  191. }
  192. /*
  193. * returns 1 on success, 0 on failure
  194. *
  195. * these will be read from:
  196. * ciphertext
  197. * ciphertext_len
  198. * key must be length KEY_LEN
  199. * iv must be length IV_LEN
  200. * tag must be length AEAD_TAG_LEN
  201. *
  202. * these will be written into:
  203. * plaintext must have the capacity of at least ciphertext_len
  204. */
  205. int aead_decrypt_openssl(const EVP_CIPHER *type, const unsigned char *ciphertext, const size_t ciphertext_len,
  206. const unsigned char *key,
  207. const unsigned char *iv,
  208. const unsigned char* aad, const size_t aad_len,
  209. unsigned char *tag,
  210. unsigned char *plaintext
  211. )
  212. {
  213. EVP_CIPHER_CTX *ctx;
  214. int plaintext_written, ret = 0;
  215. do {
  216. /* Create and initialise the context */
  217. if(!(ctx = EVP_CIPHER_CTX_new()))
  218. break;
  219. /* Initialise the decryption operation. */
  220. if(!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL))
  221. break;
  222. /* Setting IV length is not necessary because the default of 12 bytes (96 bits) will be used
  223. if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, IV_LEN, NULL))
  224. break;
  225. */
  226. /* Initialise key and IV */
  227. if(!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv))
  228. break;
  229. if(aad_len > 0) {
  230. /*
  231. * Provide any AAD data. This can be called zero or more times as
  232. * required
  233. */
  234. if(1 != EVP_DecryptUpdate(ctx, NULL, &plaintext_written, aad, (int) aad_len))
  235. break;
  236. }
  237. /*
  238. * Provide the message to be decrypted, and obtain the plaintext output.
  239. * EVP_DecryptUpdate can be called multiple times if necessary
  240. */
  241. if(!EVP_DecryptUpdate(ctx, plaintext, &plaintext_written, ciphertext, (int) ciphertext_len))
  242. break;
  243. /* if this isn't true, GCM is broken, we probably don't need to check...
  244. if(plaintext_written != ciphertext_len) {
  245. if(NULL != err)
  246. fprintf(err, "plaintext_written (%d) != ciphertext_len (%d)\n", plaintext_written, ciphertext_len);
  247. break;
  248. }
  249. */
  250. /* Set expected tag value. Works in OpenSSL 1.0.1d and later */
  251. if(!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, AEAD_TAG_LEN, tag))
  252. break;
  253. /*
  254. * Finalise the decryption. A return value of 1 indicates success,
  255. * return value of 0 is a failure - the plaintext is not trustworthy.
  256. */
  257. ret = EVP_DecryptFinal_ex(ctx, NULL, &plaintext_written);
  258. } while(0);
  259. /* Clean up */
  260. if(ctx)
  261. EVP_CIPHER_CTX_free(ctx);
  262. return ret;
  263. }
  264. int gcm_encrypt_openssl(const unsigned char *plaintext, const size_t plaintext_len,
  265. const unsigned char *key,
  266. const unsigned char *iv,
  267. const unsigned char* aad, const size_t aad_len,
  268. unsigned char *ciphertext,
  269. unsigned char *tag
  270. ) {
  271. return aead_encrypt_openssl(EVP_aes_256_gcm(), plaintext, plaintext_len,
  272. key, iv,
  273. aad, aad_len,
  274. ciphertext, tag);
  275. }
  276. int gcm_decrypt_openssl(const unsigned char *ciphertext, const size_t ciphertext_len,
  277. const unsigned char *key,
  278. const unsigned char *iv,
  279. const unsigned char* aad, const size_t aad_len,
  280. unsigned char *tag,
  281. unsigned char *plaintext
  282. )
  283. {
  284. return aead_decrypt_openssl(EVP_aes_256_gcm(), ciphertext, ciphertext_len,
  285. key, iv,
  286. aad, aad_len,
  287. tag,
  288. plaintext);
  289. }
  290. /* if both PEGH_OPENSSL and PEGH_LIBSODIUM are defined, we only want the AES funcs from OpenSSL */
  291. #ifndef PEGH_LIBSODIUM
  292. int chacha_encrypt(const unsigned char *plaintext, const size_t plaintext_len,
  293. const unsigned char *key,
  294. const unsigned char *iv,
  295. const unsigned char* aad, const size_t aad_len,
  296. unsigned char *ciphertext,
  297. unsigned char *tag
  298. ) {
  299. return aead_encrypt_openssl(EVP_chacha20_poly1305(), plaintext, plaintext_len,
  300. key, iv,
  301. aad, aad_len,
  302. ciphertext, tag);
  303. }
  304. int chacha_decrypt(const unsigned char *ciphertext, const size_t ciphertext_len,
  305. const unsigned char *key,
  306. const unsigned char *iv,
  307. const unsigned char* aad, const size_t aad_len,
  308. unsigned char *tag,
  309. unsigned char *plaintext
  310. )
  311. {
  312. return aead_decrypt_openssl(EVP_chacha20_poly1305(), ciphertext, ciphertext_len,
  313. key, iv,
  314. aad, aad_len,
  315. tag,
  316. plaintext);
  317. }
  318. /* returns 1 on success, 0 on error */
  319. int scrypt_derive_key(char *password, const size_t password_len,
  320. uint32_t scrypt_max_mem, uint32_t N,
  321. uint8_t r, uint8_t p, unsigned char *salt, unsigned char *key, FILE *err) {
  322. /* derive key using salt, password, and scrypt parameters */
  323. if (EVP_PBE_scrypt(
  324. password, password_len,
  325. salt, SALT_LEN,
  326. (uint64_t) N, (uint64_t) r, (uint64_t) p,
  327. (uint64_t) scrypt_max_mem,
  328. key, KEY_LEN
  329. ) <= 0) {
  330. if(NULL != err) {
  331. fprintf(err, "scrypt key derivation error\n");
  332. ERR_print_errors_fp(err);
  333. }
  334. return 0;
  335. }
  336. return 1;
  337. }
  338. /* returns 1 on success, 0 on error */
  339. int random_salt(unsigned char *salt) {
  340. return RAND_bytes(salt, SALT_LEN) <= 0 ? 0 : 1;
  341. }
  342. void wipe_memory(void * const ptr, const size_t len) {
  343. OPENSSL_cleanse(ptr, len);
  344. }
  345. #endif /* PEGH_LIBSODIUM */
  346. #endif /* PEGH_OPENSSL */
  347. #ifdef PEGH_LIBSODIUM
  348. /*
  349. * unlike openssl, libsodium uses proper types, so we can go all the way up to the "still secure" limit of around 64gb for aes and 256gb for chacha
  350. * but 32-bit systems have SIZE_MAX smaller than that, so special case that here
  351. */
  352. #if 274877906880 > SIZE_MAX
  353. static const size_t CHUNK_SIZE_MAX_LIBSODIUM_GCM = SIZE_MAX;
  354. static const size_t CHUNK_SIZE_MAX_CHACHA = SIZE_MAX;
  355. #else
  356. /* https://crypto.stackexchange.com/a/22643 */
  357. static const size_t CHUNK_SIZE_MAX_LIBSODIUM_GCM = 68719476704; /* (2^36)-32 or slightly less than 64gb */
  358. /* https://libsodium.gitbook.io/doc/secret-key_cryptography/aead/chacha20-poly1305/ietf_chacha20-poly1305_construction */
  359. static const size_t CHUNK_SIZE_MAX_CHACHA = 274877906880; /* 64*(2^32)-64 or slightly less than 256gb */
  360. #endif
  361. /*
  362. * returns 1 on success, 0 on failure
  363. *
  364. * these will be read from:
  365. * plaintext
  366. * plaintext_len
  367. * key must be length KEY_LEN
  368. * iv must be length IV_LEN
  369. *
  370. * these will be written into:
  371. * ciphertext must have the capacity of at least plaintext_len
  372. * tag must have the capacity of at least AEAD_TAG_LEN
  373. */
  374. int gcm_encrypt_libsodium(const unsigned char *plaintext, const size_t plaintext_len,
  375. const unsigned char *key,
  376. const unsigned char *iv,
  377. const unsigned char* aad, const size_t aad_len,
  378. unsigned char *ciphertext,
  379. unsigned char *tag
  380. )
  381. {
  382. crypto_aead_aes256gcm_encrypt_detached(ciphertext,
  383. tag, NULL,
  384. plaintext, plaintext_len,
  385. aad, aad_len,
  386. NULL, iv, key);
  387. return 1;
  388. }
  389. /*
  390. * returns 1 on success, 0 on failure
  391. *
  392. * these will be read from:
  393. * ciphertext
  394. * ciphertext_len
  395. * key must be length KEY_LEN
  396. * iv must be length IV_LEN
  397. * tag must be length AEAD_TAG_LEN
  398. *
  399. * these will be written into:
  400. * plaintext must have the capacity of at least ciphertext_len
  401. */
  402. int gcm_decrypt_libsodium(const unsigned char *ciphertext, const size_t ciphertext_len,
  403. const unsigned char *key,
  404. const unsigned char *iv,
  405. const unsigned char* aad, const size_t aad_len,
  406. unsigned char *tag,
  407. unsigned char *plaintext
  408. )
  409. {
  410. return crypto_aead_aes256gcm_decrypt_detached(plaintext,
  411. NULL,
  412. ciphertext, (size_t) ciphertext_len,
  413. tag,
  414. aad, aad_len,
  415. iv, key) != 0 ? 0 : 1;
  416. }
  417. /*
  418. * returns 1 on success, 0 on failure
  419. *
  420. * these will be read from:
  421. * plaintext
  422. * plaintext_len
  423. * key must be length KEY_LEN
  424. * iv must be length IV_LEN
  425. *
  426. * these will be written into:
  427. * ciphertext must have the capacity of at least plaintext_len
  428. * tag must have the capacity of at least AEAD_TAG_LEN
  429. */
  430. int chacha_encrypt(const unsigned char *plaintext, const size_t plaintext_len,
  431. const unsigned char *key,
  432. const unsigned char *iv,
  433. const unsigned char* aad, const size_t aad_len,
  434. unsigned char *ciphertext,
  435. unsigned char *tag
  436. )
  437. {
  438. crypto_aead_chacha20poly1305_ietf_encrypt_detached(ciphertext,
  439. tag, NULL,
  440. plaintext, plaintext_len,
  441. aad, aad_len,
  442. NULL, iv, key);
  443. return 1;
  444. }
  445. /*
  446. * returns 1 on success, 0 on failure
  447. *
  448. * these will be read from:
  449. * ciphertext
  450. * ciphertext_len
  451. * key must be length KEY_LEN
  452. * iv must be length IV_LEN
  453. * tag must be length AEAD_TAG_LEN
  454. *
  455. * these will be written into:
  456. * plaintext must have the capacity of at least ciphertext_len
  457. */
  458. int chacha_decrypt(const unsigned char *ciphertext, const size_t ciphertext_len,
  459. const unsigned char *key,
  460. const unsigned char *iv,
  461. const unsigned char* aad, const size_t aad_len,
  462. unsigned char *tag,
  463. unsigned char *plaintext
  464. )
  465. {
  466. return crypto_aead_chacha20poly1305_ietf_decrypt_detached(plaintext,
  467. NULL,
  468. ciphertext, (size_t) ciphertext_len,
  469. tag,
  470. aad, aad_len,
  471. iv, key) != 0 ? 0 : 1;
  472. }
  473. /* returns 1 on success, 0 on error */
  474. int scrypt_derive_key(char *password, const size_t password_len,
  475. uint32_t scrypt_max_mem, uint32_t N,
  476. uint8_t r, uint8_t p, unsigned char *salt, unsigned char *key, FILE *err) {
  477. size_t needed_memory;
  478. /* derive key using salt, password, and scrypt parameters */
  479. /* this is how crypto_pwhash_scryptsalsa208sha256_ll calculates the memory needed, so do it here first and check */
  480. needed_memory = (size_t) 128 * r * p;
  481. needed_memory += (size_t) 128 * r * (size_t) N;
  482. needed_memory += (size_t) 256 * r + 64;
  483. if (needed_memory > scrypt_max_mem) {
  484. if(NULL != err) {
  485. /* +1 is to round up here and avoid math.h and ceil()... */
  486. fprintf(err, "scrypt key derivation error, needed memory %lu mb, allowed memory %d mb, increase -m\n", (needed_memory / 1024 / 1024) + 1, scrypt_max_mem / 1024 / 1024);
  487. }
  488. return 0;
  489. }
  490. if (crypto_pwhash_scryptsalsa208sha256_ll(
  491. (const uint8_t *) password, password_len,
  492. salt, SALT_LEN,
  493. (uint64_t) N, (uint32_t) r, (uint32_t) p,
  494. key, KEY_LEN
  495. ) < 0) {
  496. if(NULL != err) {
  497. fprintf(err, "scrypt key derivation error\n");
  498. }
  499. return 0;
  500. }
  501. return 1;
  502. }
  503. /* returns 1 on success, 0 on error */
  504. int random_salt(unsigned char *salt) {
  505. randombytes_buf(salt, SALT_LEN);
  506. return 1;
  507. }
  508. void wipe_memory(void * const ptr, const size_t len) {
  509. sodium_memzero(ptr, len);
  510. }
  511. #endif /* PEGH_LIBSODIUM */
  512. /* always prefer libsodium AES if possible because it's faster */
  513. #ifdef PEGH_LIBSODIUM
  514. /* if PEGH_OPENSSL is defined, these can be redefined at runtime depending on CPU, otherwise const */
  515. #ifndef PEGH_OPENSSL
  516. #define PEGH_CONST const
  517. #else
  518. #define PEGH_CONST
  519. #endif
  520. static PEGH_CONST aead_func gcm_encrypt = gcm_encrypt_libsodium;
  521. static PEGH_CONST aead_func gcm_decrypt = gcm_decrypt_libsodium;
  522. static PEGH_CONST size_t CHUNK_SIZE_MAX_GCM = CHUNK_SIZE_MAX_LIBSODIUM_GCM;
  523. #elif PEGH_OPENSSL
  524. static const aead_func gcm_encrypt = gcm_encrypt_openssl;
  525. static const aead_func gcm_decrypt = gcm_decrypt_openssl;
  526. static const size_t CHUNK_SIZE_MAX_GCM = CHUNK_SIZE_MAX_OPENSSL_GCM;
  527. #endif
  528. /* returns 1 on success, 0 on failure */
  529. int iv_increment_forbid_zero(unsigned char *n, const size_t nlen, FILE *err)
  530. {
  531. int all_zero = 0;
  532. size_t i = 0U;
  533. uint_fast16_t c = 1U;
  534. for (; i < nlen; ++i) {
  535. c += (uint_fast16_t) n[i];
  536. if(c != 0)
  537. all_zero = 1;
  538. n[i] = (unsigned char) c;
  539. c >>= 8;
  540. }
  541. if(all_zero == 0 && NULL != err)
  542. fprintf(err, "aborting before IV reuse could happen, increase block_size ?\n");
  543. return all_zero;
  544. }
  545. /* returns 1 on success, 0 on failure */
  546. int encrypt_stream(const aead_func encrypt, const unsigned char *key, unsigned char *iv, size_t buffer_size,
  547. unsigned char *plaintext, unsigned char *ciphertext,
  548. FILE *in, FILE *out, FILE *err
  549. ) {
  550. unsigned char aad[1] = {0};
  551. unsigned char* plaintext_read_zone = plaintext + 1;
  552. size_t plaintext_read, extra_byte_idx = buffer_size - 1;
  553. /* read single byte */
  554. plaintext_read = fread(plaintext, 1, 1, in);
  555. if(plaintext_read != 1) {
  556. if(NULL != err)
  557. fprintf(err, "Cowardly refusing to encrypt empty file...\n");
  558. return 0;
  559. }
  560. while ((plaintext_read = fread(plaintext_read_zone, 1, buffer_size, in)) == buffer_size) {
  561. /* there are more chunks after this */
  562. if(1 != encrypt(plaintext, plaintext_read, key, iv, NULL, 0, ciphertext, ciphertext + plaintext_read))
  563. return 0;
  564. /* save extra byte at end */
  565. plaintext[0] = plaintext_read_zone[extra_byte_idx];
  566. if(1 != iv_increment_forbid_zero(iv, IV_LEN, err))
  567. return 0;
  568. fwrite(ciphertext, 1, plaintext_read + AEAD_TAG_LEN, out);
  569. }
  570. /* this is the last chunk, use AD */
  571. plaintext_read += 1;
  572. if(1 != encrypt(plaintext, plaintext_read, key, iv, aad, 1, ciphertext, ciphertext + plaintext_read))
  573. return 0;
  574. fwrite(ciphertext, 1, plaintext_read + AEAD_TAG_LEN, out);
  575. return 1;
  576. }
  577. /* returns 1 on success, 0 on failure */
  578. int decrypt_stream(const aead_func decrypt, const unsigned char *key, unsigned char *iv, size_t buffer_size,
  579. unsigned char *plaintext, unsigned char *ciphertext,
  580. FILE *in, FILE *out, FILE *err
  581. ) {
  582. unsigned char aad[1] = {0};
  583. unsigned char* ciphertext_read_zone = ciphertext + 1;
  584. size_t ciphertext_read, extra_byte_idx = buffer_size + AEAD_TAG_LEN - 1;
  585. buffer_size += AEAD_TAG_LEN;
  586. ciphertext_read = fread(ciphertext, 1, 1, in);
  587. if(ciphertext_read != 1) {
  588. if(NULL != err)
  589. fprintf(err, "File too small for decryption, truncated?\n");
  590. return 0;
  591. }
  592. while ((ciphertext_read = fread(ciphertext_read_zone, 1, buffer_size, in)) == buffer_size) {
  593. if(ciphertext_read < AEAD_TAG_LEN) {
  594. if(NULL != err)
  595. fprintf(err, "File too small for decryption, truncated?\n");
  596. return 0;
  597. }
  598. ciphertext_read -= AEAD_TAG_LEN;
  599. if(1 != decrypt(ciphertext, ciphertext_read, key, iv, NULL, 0, ciphertext + ciphertext_read, plaintext))
  600. return 0;
  601. /* save extra byte at end */
  602. ciphertext[0] = ciphertext_read_zone[extra_byte_idx];
  603. if(1 != iv_increment_forbid_zero(iv, IV_LEN, err))
  604. return 0;
  605. fwrite(plaintext, 1, ciphertext_read, out);
  606. }
  607. /* this is the last chunk, use AD */
  608. ciphertext_read += 1;
  609. if(ciphertext_read < AEAD_TAG_LEN) {
  610. if(NULL != err)
  611. fprintf(err, "File too small for decryption, truncated?\n");
  612. return 0;
  613. }
  614. ciphertext_read -= AEAD_TAG_LEN;
  615. if(1 != decrypt(ciphertext, ciphertext_read, key, iv, aad, 1, ciphertext + ciphertext_read, plaintext))
  616. return 0;
  617. fwrite(plaintext, 1, ciphertext_read, out);
  618. return 1;
  619. }
  620. /*
  621. * reads buffer_size at a time from in, encrypts with AES-256-GCM, and writes them to out
  622. *
  623. * returns 1 on success, 0 on failure
  624. *
  625. * key must be length KEY_LEN
  626. * iv must be length IV_LEN
  627. *
  628. * buffer_size must be non-zero, this function will allocate this twice
  629. * in/out must be set
  630. * err can be NULL in which case no messages are printed
  631. */
  632. int stream(const stream_func crypt_stream, const aead_func aead, unsigned char *key, size_t buffer_size,
  633. FILE *in, FILE *out, FILE *err
  634. )
  635. {
  636. /* this is ok because the random salt makes the key random, and we increment this for encryption operation */
  637. unsigned char iv[IV_LEN] = {0};
  638. /* these are actually mallocd and freed */
  639. unsigned char *plaintext = NULL, *ciphertext = NULL;
  640. size_t chunk_size_max;
  641. int exit_code = 0, is_gcm;
  642. /* check chunk size */
  643. is_gcm = aead == gcm_decrypt || aead == gcm_encrypt;
  644. chunk_size_max = is_gcm ? CHUNK_SIZE_MAX_GCM : CHUNK_SIZE_MAX_CHACHA;
  645. if(buffer_size > chunk_size_max) {
  646. if(NULL != err) {
  647. #if defined(PEGH_OPENSSL) && defined(PEGH_LIBSODIUM)
  648. /* the ugliest branch, openssl limits only apply if it's GCM and we are using openssl's impl */
  649. if(is_gcm && gcm_decrypt == gcm_decrypt_openssl) {
  650. fprintf(err, "due to openssl API limitation, buffer_size can at most be %lu\n", chunk_size_max);
  651. } else {
  652. fprintf(err, "due to algorithm security constraints, buffer_size can at most be %lu\n", chunk_size_max);
  653. }
  654. #elif defined(PEGH_OPENSSL)
  655. fprintf(err, "due to openssl API limitation, buffer_size can at most be %lu\n", chunk_size_max);
  656. #elif defined(PEGH_LIBSODIUM)
  657. fprintf(err, "due to algorithm security constraints, buffer_size can at most be %lu\n", chunk_size_max);
  658. #endif
  659. }
  660. return 0;
  661. }
  662. plaintext = malloc(buffer_size + 1);
  663. if(!plaintext) {
  664. if(NULL != err)
  665. fprintf(err, "plaintext memory allocation failed\n");
  666. return 0;
  667. }
  668. ciphertext = malloc(buffer_size + AEAD_TAG_LEN + 1);
  669. if(!ciphertext) {
  670. if(NULL != err)
  671. fprintf(err, "ciphertext memory allocation failed\n");
  672. free(plaintext);
  673. return 0;
  674. }
  675. exit_code = crypt_stream(aead, key, iv, buffer_size, plaintext, ciphertext, in, out, err);
  676. free(plaintext);
  677. free(ciphertext);
  678. if(NULL != err && exit_code != 1) {
  679. #ifdef PEGH_OPENSSL
  680. /* print openssl errors */
  681. ERR_print_errors_fp(err);
  682. #endif
  683. fprintf(err, "%scryption failed\n", crypt_stream == decrypt_stream ? "de" : "en");
  684. }
  685. return exit_code;
  686. }
  687. /* buf must be at least 4 bytes */
  688. uint32_t read_uint32_big_endian(const unsigned char *buf) {
  689. return (uint32_t) ((buf[0] & 0xFF) << 24)
  690. | (uint32_t) ((buf[1] & 0xFF) << 16)
  691. | (uint32_t) ((buf[2] & 0xFF) << 8)
  692. | (uint32_t) (buf[3] & 0xFF);
  693. }
  694. /* buf must be at least 4 bytes */
  695. void write_uint32_big_endian(uint32_t val, unsigned char *buf) {
  696. buf[0] = (unsigned char) ((val >> 24) & 0xFF);
  697. buf[1] = (val >> 16) & 0xFF;
  698. buf[2] = (val >> 8) & 0xFF;
  699. buf[3] = val & 0xFF;
  700. }
  701. /* returns 1 on success, 0 on failure */
  702. int scrypt_derive_key_stream(const stream_func crypt_stream, const aead_func aead,
  703. char *password, const size_t password_len,
  704. uint32_t scrypt_max_mem, size_t buffer_size,
  705. FILE *in, FILE *out, FILE *err,
  706. uint32_t N, uint8_t r, uint8_t p, unsigned char *salt) {
  707. unsigned char key[KEY_LEN] = {0};
  708. int ret;
  709. ret = scrypt_derive_key(password, password_len, scrypt_max_mem, N, r, p, salt, key, err);
  710. wipe_memory(password, password_len);
  711. if(ret == 1)
  712. ret = stream(crypt_stream, aead, key, buffer_size, in, out, err);
  713. wipe_memory(key, KEY_LEN);
  714. return ret;
  715. }
  716. /* returns 1 on success, 0 on failure */
  717. int check_version(uint8_t version, FILE *err) {
  718. if(version != 0 && version != 1) {
  719. fprintf(stderr, "Error: unsupported file format version %d, we only support version 0 (AES-256-GCM) and 1 (Chacha20-Poly1305)\n", version);
  720. return 0;
  721. }
  722. #ifdef PEGH_LIBSODIUM
  723. /* check for AES encrypted but libsodium/hardware AES is not available */
  724. #ifdef PEGH_OPENSSL
  725. /* if we've already checked/set this, don't again */
  726. else if (gcm_encrypt != gcm_encrypt_openssl && version == 0 && crypto_aead_aes256gcm_is_available() == 0) {
  727. /* swap to OpenSSL AES which is always supported */
  728. if(NULL != err)
  729. fprintf(err, "Warning: libsodium does not support AES-256-GCM on this CPU, falling back to openssl version instead...\n");
  730. gcm_encrypt = gcm_encrypt_openssl;
  731. gcm_decrypt = gcm_decrypt_openssl;
  732. CHUNK_SIZE_MAX_GCM = CHUNK_SIZE_MAX_OPENSSL_GCM;
  733. #else
  734. else if (version == 0 && crypto_aead_aes256gcm_is_available() == 0) {
  735. /* nothing we can do */
  736. fprintf(stderr, "Error: libsodium does not support AES-256-GCM on this CPU, compile/use openssl version?\n");
  737. return 19;
  738. #endif /* PEGH_OPENSSL */
  739. }
  740. #endif /* PEGH_LIBSODIUM */
  741. /* silence unused-parameter warning */
  742. (void)err;
  743. return 1;
  744. }
  745. /* returns 1 on success, 0 on failure */
  746. int pegh_encrypt(char *password, const size_t password_len,
  747. uint32_t scrypt_max_mem, size_t buffer_size,
  748. FILE *in, FILE *out, FILE *err,
  749. uint8_t version,
  750. uint32_t N, uint8_t r, uint8_t p)
  751. {
  752. unsigned char salt[SALT_LEN] = {0};
  753. if(1 != check_version(version, err)) {
  754. fprintf(stderr, "Error: encryption aborting, try version 1 (Chacha20-Poly1305) which is universally supported\n");
  755. return 0;
  756. }
  757. /* first write the version and parameters */
  758. salt[0] = version;
  759. write_uint32_big_endian(N, salt+1);
  760. salt[5] = r;
  761. salt[6] = p;
  762. write_uint32_big_endian((uint32_t) buffer_size, salt+7);
  763. fwrite(salt, 1, PRE_SALT_LEN, out);
  764. /* generate random salt, then write it out */
  765. if (random_salt(salt) != 1) {
  766. if(NULL != err) {
  767. fprintf(err, "random salt generation error\n");
  768. #ifdef PEGH_OPENSSL
  769. ERR_print_errors_fp(err);
  770. #endif
  771. }
  772. return 0;
  773. }
  774. fwrite(salt, 1, SALT_LEN, out);
  775. return scrypt_derive_key_stream(encrypt_stream, version == 0 ? gcm_encrypt : chacha_encrypt,
  776. password, password_len,
  777. scrypt_max_mem, buffer_size, in, out, err, N, r, p, salt);
  778. }
  779. /* returns 1 on success, 0 on failure */
  780. int pegh_decrypt(char *password, const size_t password_len,
  781. uint32_t scrypt_max_mem, size_t max_buffer_size,
  782. FILE *in, FILE *out, FILE *err)
  783. {
  784. unsigned char salt[SALT_LEN] = {0};
  785. int version_exit_code;
  786. size_t header_read, buffer_size;
  787. uint32_t N;
  788. uint8_t version, r, p;
  789. /* first read the version and parameters */
  790. header_read = fread(salt, 1, PRE_SALT_LEN, in);
  791. if(header_read != PRE_SALT_LEN) {
  792. if(NULL != err)
  793. fprintf(err, "File too small for decryption, invalid header?\n");
  794. return 0;
  795. }
  796. version = salt[0];
  797. if(1 != (version_exit_code = check_version(version, err))) {
  798. fprintf(stderr, "Error: decryption aborting, this file cannot be decrypted with this version/CPU\n");
  799. return version_exit_code;
  800. }
  801. N = read_uint32_big_endian(salt+1);
  802. r = salt[5];
  803. p = salt[6];
  804. buffer_size = read_uint32_big_endian(salt+7);
  805. if(buffer_size > max_buffer_size) {
  806. if(NULL != err)
  807. fprintf(err, "memory required to decrypt file is %lu MB but only %lu MB allowed, increase -c\n", buffer_size / 1024 / 1024, max_buffer_size / 1024 / 1024);
  808. return 0;
  809. }
  810. /* next read salt */
  811. header_read = fread(salt, 1, SALT_LEN, in);
  812. if(header_read != SALT_LEN) {
  813. if(NULL != err)
  814. fprintf(err, "File too small for decryption, invalid header?\n");
  815. return 0;
  816. }
  817. return scrypt_derive_key_stream(decrypt_stream, version == 0 ? gcm_decrypt : chacha_decrypt,
  818. password, password_len,
  819. scrypt_max_mem, buffer_size, in, out, err, N, r, p, salt);
  820. }
  821. int help(int exit_code) {
  822. /* this ridiculous split is because C89 only supports strings of 509 characters */
  823. fprintf(stderr, "\
  824. usage: pegh [options...] password\n\
  825. password: minimum required length is %lu\n\
  826. -e encrypt input to output, default mode\n\
  827. -d decrypt input to output\n\
  828. -i <filename> file to use for input, - means stdin, default stdin\n\
  829. -o <filename> file to use for output, - means stdout, default stdout\n\
  830. -a append to -o instead of truncate\n\
  831. -v pegh file format version to output,\n", MINIMUM_PASSWORD_LEN);
  832. fprintf(stderr, "\
  833. either 0 (AES-256-GCM) or 1 (Chacha20-Poly1305),\n\
  834. default: 0 if AES is hardware accelerated, 1 otherwise\n\
  835. -c <mb> chunk size for encryption, while decrypting/encrypting twice\n\
  836. this ram will be used, the same amount will be needed for\n\
  837. decryption as encryption. This value is saved in the file\n\
  838. format, so decryption will fail if this isn't set high enough,\n");
  839. fprintf(stderr, "\
  840. these are only allocated after scrypt is finished so max usage\n\
  841. will be the highest of these only, not both combined,\n\
  842. max: %lu (AES-256-GCM) or %lu (Chacha20-Poly1305),\n\
  843. default: %d\n\
  844. -m <max_mb> maximum megabytes of ram to use when deriving key from password\n\
  845. with scrypt, applies for encryption AND decryption, must\n\
  846. almost linearly scale with -N, if too low operation will fail,\n\
  847. default: %d\n", CHUNK_SIZE_MAX_GCM / 1024 / 1024, CHUNK_SIZE_MAX_CHACHA / 1024 / 1024, DEFAULT_CHUNK_SIZE_MB, SCRYPT_MAX_MEM / 1024 / 1024);
  848. fprintf(stderr, "\
  849. -f <filename> read password from file instead of argument, - means stdin\n\
  850. -g prompt for password, confirm on encryption, max characters: %lu\n",
  851. MANUAL_ENTRY_PASSWORD_MAX_LEN - 2
  852. );
  853. fprintf(stderr, "\
  854. -N <num> scrypt parameter N, only applies for encryption, default %d\n\
  855. this is rounded up to the next highest power of 2\n\
  856. -r <num> scrypt parameter r, only applies for encryption, default %d\n\
  857. -p <num> scrypt parameter p, only applies for encryption, default %d\n\
  858. -s <num> multiplication factor to apply to both -N and -m for easy\n\
  859. work scaling, rounded up to the next highest power of 2,\n", SCRYPT_N, SCRYPT_R, SCRYPT_P);
  860. fprintf(stderr, "\
  861. BEWARE: -s 32 requires 2G ram, -s 64 requires 4G and so on,\n\
  862. default: 1\n\
  863. -h print this usage text\n\
  864. -q do not print error output to stderr\n\
  865. -V show version number and format version support then quit\n\
  866. \nFor additional info on scrypt params refer to:\n\
  867. https://blog.filippo.io/the-scrypt-parameters/\n\
  868. https://tools.ietf.org/html/rfc7914#section-2\n\n");
  869. return exit_code;
  870. }
  871. void help_exit(int exit_code) {
  872. help(exit_code);
  873. exit(exit_code);
  874. }
  875. uint32_t parse_int_arg(int optind, int argc, char **argv) {
  876. uint64_t tmp = 0;
  877. if(optind >= argc) {
  878. fprintf(stderr, "Error: %s requires an argument\n", argv[optind - 1]);
  879. help_exit(2);
  880. return 0;
  881. }
  882. errno = 0;
  883. tmp = strtoul(argv[optind], NULL, 10);
  884. if(errno != 0 || tmp < 1 || tmp > UINT_MAX) {
  885. fprintf(stderr, "Error: %s %s failed to parse as a number\n", argv[optind - 1], argv[optind]);
  886. help_exit(2);
  887. return 0;
  888. }
  889. return (uint32_t) tmp;
  890. }
  891. uint8_t parse_byte_arg(int optind, int argc, char **argv) {
  892. uint32_t tmp;
  893. tmp = parse_int_arg(optind, argc, argv);
  894. if(tmp > 255) {
  895. fprintf(stderr, "Error: %s %s failed to parse as a number 1-255\n", argv[optind - 1], argv[optind]);
  896. help_exit(2);
  897. return 0;
  898. }
  899. return (uint8_t) tmp;
  900. }
  901. char* parse_filename_arg(int optind, int argc, char **argv) {
  902. if(optind >= argc) {
  903. fprintf(stderr, "Error: %s requires an argument\n", argv[optind - 1]);
  904. help_exit(2);
  905. return 0;
  906. }
  907. /* - means stdin or stdout, we return NULL */
  908. return strlen(argv[optind]) == 1 && argv[optind][0] == '-' ? NULL : argv[optind];
  909. }
  910. uint32_t next_highest_power_of_2(uint32_t v) {
  911. --v;
  912. v |= v >> 1;
  913. v |= v >> 2;
  914. v |= v >> 4;
  915. v |= v >> 8;
  916. v |= v >> 16;
  917. return ++v;
  918. }
  919. /* in_filename NULL means stdin */
  920. char* read_file_fully(const char *in_filename, size_t *file_len) {
  921. char* contents;
  922. size_t read, actual_size = 0, total_size = 1024;
  923. FILE *in = stdin;
  924. if(NULL != in_filename) {
  925. in = fopen(in_filename, "rb");
  926. if(!in) {
  927. fprintf (stderr, "Error: file '%s' cannot be opened for reading\n", in_filename);
  928. return NULL;
  929. }
  930. }
  931. #ifdef _WIN32
  932. else {
  933. /* windows in/out is text and mangles certain bytes by default... */
  934. setmode(STDIN, O_BINARY);
  935. }
  936. #endif
  937. contents = malloc(total_size);
  938. if(!contents) {
  939. fprintf (stderr, "Error: memory cannot be allocated to read file '%s'\n", in_filename);
  940. if(NULL != in_filename) {
  941. fclose(in);
  942. }
  943. return NULL;
  944. }
  945. while ((read = fread(contents + actual_size, 1, 512, in)) > 0) {
  946. actual_size += read;
  947. if ((actual_size + 512) > total_size) {
  948. total_size = total_size * 2;
  949. contents = realloc(contents, total_size);
  950. if(!contents) {
  951. fprintf (stderr, "Error: memory cannot be allocated to read file '%s'\n", in_filename);
  952. if(NULL != in_filename) {
  953. fclose(in);
  954. }
  955. return NULL;
  956. }
  957. }
  958. }
  959. if(NULL != in_filename) {
  960. fclose(in);
  961. }
  962. /* now let's size it down to the minimum size */
  963. contents = realloc(contents, actual_size);
  964. if (!contents) {
  965. fprintf (stderr, "Error: memory cannot be allocated to read file '%s'\n", in_filename);
  966. return NULL;
  967. }
  968. *file_len = actual_size;
  969. return contents;
  970. }
  971. /* returns -1 on error, or 0+ for length of string read into buff */
  972. int read_passwd(char *prompt, char *buff, int buff_len, FILE *in, FILE *out)
  973. {
  974. int pass_len;
  975. /*
  976. * Turn echoing off and fail if we cant.
  977. * we support POSIX and Windows here
  978. */
  979. #ifdef USE_TERMIOS
  980. struct termios orig_input_flags, new_input_flags;
  981. if (tcgetattr (fileno (in), &orig_input_flags) != 0)
  982. return -1;
  983. new_input_flags = orig_input_flags;
  984. new_input_flags.c_lflag &= (tcflag_t) ~ECHO;
  985. if (tcsetattr (fileno (in), TCSAFLUSH, &new_input_flags) != 0)
  986. return -1;
  987. #endif
  988. #ifdef _WIN32
  989. HANDLE hStdin;
  990. DWORD orig_input_flags;
  991. hStdin = GetStdHandle(STD_INPUT_HANDLE);
  992. if (hStdin == INVALID_HANDLE_VALUE)
  993. return -1;
  994. /* Save the current input mode, to be restored on exit. */
  995. if (! GetConsoleMode(hStdin, &orig_input_flags) )
  996. return -1;
  997. if (! SetConsoleMode(hStdin, orig_input_flags & (DWORD) ~ENABLE_ECHO_INPUT) )
  998. return -1;
  999. #endif
  1000. /* Display the prompt */
  1001. fprintf(out, "%s", prompt);
  1002. /* Read the password. cast is safe because buff_len is int */
  1003. pass_len = fgets (buff, buff_len, in) == NULL ? 0 : (int) strlen(buff);
  1004. /* Remove the line feed */
  1005. if (pass_len >= 1 && buff[pass_len - 1] == '\n') {
  1006. buff[--pass_len] = 0;
  1007. }
  1008. /* Remove the carriage return */
  1009. if (pass_len >= 1 && buff[pass_len - 1] == '\r') {
  1010. buff[--pass_len] = 0;
  1011. }
  1012. /* Restore terminal. we could check failure here but if it failed, what could we do? */
  1013. #ifdef USE_TERMIOS
  1014. tcsetattr (fileno (in), TCSAFLUSH, &orig_input_flags);
  1015. fprintf(out, "\n"); /* windows does this automatically */
  1016. #endif
  1017. #ifdef _WIN32
  1018. SetConsoleMode(hStdin, orig_input_flags);
  1019. #endif
  1020. return pass_len;
  1021. }
  1022. /* returns -1 on error, or 0+ for length of string read into buff */
  1023. int read_passwd_console(char *prompt, char *buff, int buff_len) {
  1024. int pass_len;
  1025. FILE *in;
  1026. #ifdef _WIN32
  1027. in = fopen("CONIN$", "r+");
  1028. /* this *should* work here but does not, just using stderr for now
  1029. out = fopen("CONOUT$", "w");
  1030. */
  1031. if(in) {
  1032. pass_len = read_passwd(prompt, buff, buff_len, in, stderr);
  1033. fclose(in);
  1034. return pass_len;
  1035. }
  1036. #else
  1037. in = fopen("/dev/tty", "r+");
  1038. if(in) {
  1039. pass_len = read_passwd(prompt, buff, buff_len, in, in);
  1040. fclose(in);
  1041. return pass_len;
  1042. }
  1043. #endif
  1044. /* oh well, we tried */
  1045. return read_passwd(prompt, buff, buff_len, stdin, stderr);
  1046. }
  1047. /* returns -1 on error, or 0+ for length of string read into buff */
  1048. int read_passwd_console_confirm(char *buff, int buff_len, int min_passwd_length) {
  1049. int pass_len, confirm_len;
  1050. char *confirm_passwd;
  1051. confirm_passwd = malloc((size_t) buff_len);
  1052. if(!confirm_passwd)
  1053. return -1;
  1054. while(1) {
  1055. pass_len = read_passwd_console("Enter encryption password: ", buff, buff_len);
  1056. if(-1 == pass_len)
  1057. break; /* fail */
  1058. if(pass_len < min_passwd_length) {
  1059. fprintf(stderr, "Error: Minimum password length is %d but was only %d, try again...\n", min_passwd_length, pass_len);
  1060. continue;
  1061. }
  1062. if(pass_len == (buff_len - 1)) {
  1063. fprintf(stderr, "Error: Maximum password length for manual entry (%d) exceeded, try again...\n", buff_len - 2);
  1064. continue;
  1065. }
  1066. confirm_len = read_passwd_console("Confirm password: ", confirm_passwd, buff_len);
  1067. if(-1 == confirm_len)
  1068. break; /* fail */
  1069. if(pass_len == confirm_len && strcmp(buff, confirm_passwd) == 0)
  1070. break; /* finally success! */
  1071. fprintf(stderr, "Error: Entered passwords do not match, try again...\n");
  1072. }
  1073. /* wipe confirm password */
  1074. wipe_memory(confirm_passwd, (size_t) buff_len);
  1075. if(pass_len == -1 || pass_len == 0) {
  1076. /* wipe entire password buffer */
  1077. wipe_memory(buff, (size_t) buff_len);
  1078. } else {
  1079. /* wipe the unused portion of the read password too, in case some secrets exist there */
  1080. wipe_memory(buff + (pass_len + 1), (size_t) (buff_len - pass_len - 1));
  1081. }
  1082. free(confirm_passwd);
  1083. return pass_len;
  1084. }
  1085. /* returns 0 on success, 1 on cryptography failure, 19 on "libsodium only and CPU does not support AES" error, 2 on other failure */
  1086. int main(int argc, char **argv)
  1087. {
  1088. int optind, decrypt = 0, append = 0, passwd_prompt = 0, exit_code = 2, version = -1;
  1089. char *password = NULL;
  1090. uint32_t N = SCRYPT_N, scrypt_max_mem = SCRYPT_MAX_MEM, buffer_size = DEFAULT_CHUNK_SIZE_MB * 1024 * 1024, scale = 1;
  1091. uint8_t r = SCRYPT_R, p = SCRYPT_P;
  1092. size_t password_len;
  1093. FILE *in = stdin, *out = stdout, *err = stderr;
  1094. char *in_filename = NULL, *out_filename = NULL;
  1095. #ifdef PEGH_LIBSODIUM
  1096. if (sodium_init() == -1) {
  1097. fprintf(stderr, "Error: libsodium could not be initialized, compile/use openssl version?\n");
  1098. return 1;
  1099. }
  1100. #endif /* PEGH_LIBSODIUM */
  1101. for (optind = 1; optind < argc; ++optind) {
  1102. if(strlen(argv[optind]) == 2 && argv[optind][0] == '-') {
  1103. /* -- means stop parsing options */
  1104. if(argv[optind][1] == '-') {
  1105. ++optind;
  1106. break;
  1107. }
  1108. switch (argv[optind][1]) {
  1109. case 'e':
  1110. decrypt = 0;
  1111. break;
  1112. case 'd':
  1113. decrypt = 1;
  1114. break;
  1115. case 'a':
  1116. append = 1;
  1117. break;
  1118. case 'i':
  1119. in_filename = parse_filename_arg(++optind, argc, argv);
  1120. break;
  1121. case 'o':
  1122. out_filename = parse_filename_arg(++optind, argc, argv);
  1123. break;
  1124. case 'f':
  1125. password = read_file_fully(parse_filename_arg(++optind, argc, argv), &password_len);
  1126. break;
  1127. case 'g':
  1128. passwd_prompt = 1;
  1129. break;
  1130. case 'c':
  1131. buffer_size = parse_int_arg(++optind, argc, argv) * 1024 * 1024;
  1132. break;
  1133. case 'm':
  1134. scrypt_max_mem = parse_int_arg(++optind, argc, argv) * 1024 * 1024;
  1135. break;
  1136. case 'N':
  1137. N = next_highest_power_of_2(parse_int_arg(++optind, argc, argv));
  1138. break;
  1139. case 's':
  1140. scale = next_highest_power_of_2(parse_int_arg(++optind, argc, argv));
  1141. break;
  1142. case 'r':
  1143. r = parse_byte_arg(++optind, argc, argv);
  1144. break;
  1145. case 'p':
  1146. p = parse_byte_arg(++optind, argc, argv);
  1147. break;
  1148. case 'q':
  1149. err = NULL;
  1150. break;
  1151. case 'v':
  1152. if(++optind >= argc) {
  1153. fprintf(stderr, "Error: %s requires an argument\n", argv[optind - 1]);
  1154. return help(2);
  1155. }
  1156. if(strlen(argv[optind]) != 1 || (argv[optind][0] != '0' && argv[optind][0] != '1')) {
  1157. fprintf(stderr, "Error: unsupported file format version %s, we only support version 0 (AES-256-GCM) and 1 (Chacha20-Poly1305)\n", argv[optind]);
  1158. return help(2);
  1159. }
  1160. if(argv[optind][0] == '0') {
  1161. version = 0;
  1162. #ifdef PEGH_LIBSODIUM
  1163. if(1 != check_version(0, NULL)) {
  1164. return help(19);
  1165. }
  1166. #endif
  1167. } else {
  1168. version = 1;
  1169. }
  1170. break;
  1171. case 'V':
  1172. fprintf(stderr, "pegh %s\nformat versions supported: 0 (AES-256-GCM) and 1 (Chacha20-Poly1305)\n", PEGH_VERSION);
  1173. return 0;
  1174. case 'h':
  1175. return help(0);
  1176. default:
  1177. fprintf(stderr, "Error: invalid option %s\n", argv[optind]);
  1178. return help(exit_code);
  1179. }
  1180. } else if (password == NULL) {
  1181. password = argv[optind];
  1182. password_len = strlen(password);
  1183. } else {
  1184. fprintf (stderr, "Error: more than one password provided\n");
  1185. return help(exit_code);
  1186. }
  1187. }
  1188. if(password == NULL) {
  1189. if(passwd_prompt) {
  1190. password = malloc(MANUAL_ENTRY_PASSWORD_MAX_LEN);
  1191. if(!password) {
  1192. fprintf (stderr, "Error: cannot allocate memory to prompt for password\n");
  1193. return exit_code;
  1194. }
  1195. if(decrypt) {
  1196. /* for decryption, we just read the password once, maybe print a warning, try to decrypt */
  1197. optind = read_passwd_console("Enter decryption password: ", password, MANUAL_ENTRY_PASSWORD_MAX_LEN);
  1198. if(optind == (MANUAL_ENTRY_PASSWORD_MAX_LEN - 1)) {
  1199. /* possibly truncated */
  1200. fprintf (stderr, "Warning: read maximum characters (%d) for password, possibly truncated, attempting decryption anyway...!\n", optind);
  1201. }
  1202. } else {
  1203. optind = read_passwd_console_confirm(password, MANUAL_ENTRY_PASSWORD_MAX_LEN, MINIMUM_PASSWORD_LEN);
  1204. }
  1205. if(optind == -1) {
  1206. fprintf (stderr, "Error: cannot prompt user for password!\n");
  1207. return exit_code;
  1208. }
  1209. password_len = (size_t) optind;
  1210. } else {
  1211. if(argc == optind) {
  1212. fprintf (stderr, "Error: no password provided\n");
  1213. return help(exit_code);
  1214. }
  1215. if((argc - optind) != 1) {
  1216. fprintf (stderr, "Error: more than one password provided\n");
  1217. return help(exit_code);
  1218. }
  1219. password = argv[optind];
  1220. password_len = strlen(password);
  1221. }
  1222. }
  1223. if(0 == decrypt && password_len < MINIMUM_PASSWORD_LEN) {
  1224. fprintf (stderr, "Error: Minimum password length is %lu but was only %lu\n", MINIMUM_PASSWORD_LEN, password_len);
  1225. return help(exit_code);
  1226. }
  1227. /* apply scale */
  1228. N *= scale;
  1229. scrypt_max_mem *= scale;
  1230. /*
  1231. fprintf (stderr, "decrypt = %d, key = %s, scrypt_max_mem = %d, N = %d, r = %d, p = %d, scale = %d\n",
  1232. decrypt, password, scrypt_max_mem, N, r, p, scale);
  1233. return 0;
  1234. */
  1235. if(NULL != in_filename) {
  1236. in = fopen(in_filename, "rb");
  1237. if(!in) {
  1238. fprintf (stderr, "Error: file '%s' cannot be opened for reading\n", in_filename);
  1239. return exit_code;
  1240. }
  1241. }
  1242. #ifdef _WIN32
  1243. else {
  1244. /* windows in/out is text and mangles certain bytes by default... */
  1245. setmode(STDIN, O_BINARY);
  1246. }
  1247. #endif
  1248. if(NULL != out_filename) {
  1249. out = fopen(out_filename, append ? "ab" : "wb");
  1250. if(!out) {
  1251. fprintf (stderr, "Error: file '%s' cannot be opened for writing\n", out_filename);
  1252. if(NULL != in_filename)
  1253. fclose(in);
  1254. return exit_code;
  1255. }
  1256. }
  1257. #ifdef _WIN32
  1258. else {
  1259. /* windows in/out is text and mangles certain bytes by default... */
  1260. setmode(STDOUT, O_BINARY);
  1261. }
  1262. #endif
  1263. if(decrypt)
  1264. exit_code = pegh_decrypt(password, password_len, scrypt_max_mem, buffer_size, in, out, err);
  1265. else {
  1266. if(-1 == version) {
  1267. /* they left this as default, so attempt to pick best (fastest) version */
  1268. #ifdef PEGH_LIBSODIUM
  1269. /* libsodium is easy, it only supports AES if it is CPU hardware accelerated,
  1270. * so if it is AES is fastest, otherwise must use Chacha20
  1271. */
  1272. version = crypto_aead_aes256gcm_is_available() == 0 ? 1 : 0;
  1273. #elif defined(PEGH_OPENSSL)
  1274. /* OpenSSL is NOT easy, ideally we'd also pick AES if hardware accelerated,
  1275. * and Chacha20 otherwise, there is *a* way https://stackoverflow.com/a/25284682
  1276. * but not a good/supported/standard way, for now just assume AES is faster on
  1277. * 64-bit platforms???
  1278. */
  1279. #if (1024UL * 1024 * 1024 * 32) > SIZE_MAX
  1280. /* small SIZE_MAX, Chacha20 */
  1281. version = 1;
  1282. #else
  1283. /* greater than 32gb SIZE_MAX, AES */
  1284. version = 0;
  1285. #endif
  1286. #endif /* PEGH_OPENSSL */
  1287. }
  1288. exit_code = pegh_encrypt(password, password_len, scrypt_max_mem, buffer_size, in, out, err, (uint8_t) version, N, r, p);
  1289. }
  1290. if(NULL != in_filename) {
  1291. fclose(in);
  1292. }
  1293. if(NULL != out_filename) {
  1294. fclose(out);
  1295. }
  1296. /* to the OS, 0 means success, the above functions 1 means success */
  1297. return exit_code == 1 ? 0 : (exit_code == 0 ? 1 : exit_code);
  1298. }