static void test_crypto_pwbox(void *arg) { uint8_t *boxed=NULL, *decoded=NULL; size_t len, dlen; unsigned i; const char msg[] = "This bunny reminds you that you still have a " "salamander in your sylladex. She is holding the bunny Dave got you. " "It’s sort of uncanny how similar they are, aside from the knitted " "enhancements. Seriously, what are the odds?? So weird."; const char pw[] = "I'm a night owl and a wise bird too"; const unsigned flags[] = { 0, S2K_FLAG_NO_SCRYPT, S2K_FLAG_LOW_MEM, S2K_FLAG_NO_SCRYPT|S2K_FLAG_LOW_MEM, S2K_FLAG_USE_PBKDF2 }; (void)arg; for (i = 0; i < ARRAY_LENGTH(flags); ++i) { tt_int_op(0, OP_EQ, crypto_pwbox(&boxed, &len, (const uint8_t*)msg, strlen(msg), pw, strlen(pw), flags[i])); tt_assert(boxed); tt_assert(len > 128+32); tt_int_op(0, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len, pw, strlen(pw))); tt_assert(decoded); tt_uint_op(dlen, OP_EQ, strlen(msg)); tt_mem_op(decoded, OP_EQ, msg, dlen); tor_free(decoded); tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len, pw, strlen(pw)-1)); boxed[len-1] ^= 1; tt_int_op(UNPWBOX_BAD_SECRET, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len, pw, strlen(pw))); boxed[0] = 255; tt_int_op(UNPWBOX_CORRUPTED, OP_EQ, crypto_unpwbox(&decoded, &dlen, boxed, len, pw, strlen(pw))); tor_free(boxed); } done: tor_free(boxed); tor_free(decoded); }
int read_encrypted_secret_key(ed25519_secret_key_t *out, const char *fname) { int r = -1; uint8_t *secret = NULL; size_t secret_len = 0; char pwbuf[256]; uint8_t encrypted_key[256]; char *tag = NULL; int saved_errno = 0; ssize_t encrypted_len = crypto_read_tagged_contents_from_file(fname, ENC_KEY_HEADER, &tag, encrypted_key, sizeof(encrypted_key)); if (encrypted_len < 0) { saved_errno = errno; log_info(LD_OR, "%s is missing", fname); r = 0; goto done; } if (strcmp(tag, ENC_KEY_TAG)) { saved_errno = EINVAL; goto done; } while (1) { ssize_t pwlen = do_getpass("Enter pasphrase for master key:", pwbuf, sizeof(pwbuf), 0, get_options()); if (pwlen < 0) { saved_errno = EINVAL; goto done; } const int r = crypto_unpwbox(&secret, &secret_len, encrypted_key, encrypted_len, pwbuf, pwlen); if (r == UNPWBOX_CORRUPTED) { log_err(LD_OR, "%s is corrupted.", fname); saved_errno = EINVAL; goto done; } else if (r == UNPWBOX_OKAY) { break; } /* Otherwise, passphrase is bad, so try again till user does ctrl-c or gets * it right. */ } if (secret_len != ED25519_SECKEY_LEN) { log_err(LD_OR, "%s is corrupted.", fname); saved_errno = EINVAL; goto done; } memcpy(out->seckey, secret, ED25519_SECKEY_LEN); r = 1; done: memwipe(encrypted_key, 0, sizeof(encrypted_key)); memwipe(pwbuf, 0, sizeof(pwbuf)); tor_free(tag); if (secret) { memwipe(secret, 0, secret_len); tor_free(secret); } if (saved_errno) errno = saved_errno; return r; }