Example #1
0
static int ede_cfb64_test(unsigned char *cfb_cipher)
{
    DES_key_schedule ks;
    int err = 0, i, n;

    DES_set_key_checked(&cfb_key, &ks);
    memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv));
    n = 0;
    DES_ede3_cfb64_encrypt(plain, cfb_buf1, 12, &ks, &ks, &ks, &cfb_tmp, &n,
                           DES_ENCRYPT);
    DES_ede3_cfb64_encrypt(&(plain[12]), &(cfb_buf1[12]),
                           sizeof(plain) - 12, &ks, &ks, &ks,
                           &cfb_tmp, &n, DES_ENCRYPT);
    if (memcmp(cfb_cipher, cfb_buf1, sizeof(plain)) != 0) {
        err = 1;
        printf("ede_cfb_encrypt encrypt error\n");
        for (i = 0; i < 24; i += 8)
            printf("%s\n", pt(&(cfb_buf1[i])));
    }
    memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv));
    n = 0;
    DES_ede3_cfb64_encrypt(cfb_buf1, cfb_buf2, (long)17, &ks, &ks, &ks,
                           &cfb_tmp, &n, DES_DECRYPT);
    DES_ede3_cfb64_encrypt(&(cfb_buf1[17]), &(cfb_buf2[17]),
                           sizeof(plain) - 17, &ks, &ks, &ks,
                           &cfb_tmp, &n, DES_DECRYPT);
    if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0) {
        err = 1;
        printf("ede_cfb_encrypt decrypt error\n");
        for (i = 0; i < 24; i += 8)
            printf("%s\n", pt(&(cfb_buf2[i])));
    }
    return (err);
}
Example #2
0
/*
 * The input and output encrypted as though 64bit cfb mode is being used.
 * The extra state information to record how much of the 64bit block we have
 * used is contained in *num;
 */

void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out,
                            long length, DES_key_schedule *ks1,
                            DES_key_schedule *ks2, DES_key_schedule *ks3,
                            DES_cblock *ivec, int *num, int enc)
{
    DES_LONG v0, v1;
    long l = length;
    int n = *num;
    DES_LONG ti[2];
    unsigned char *iv, c, cc;

    iv = &(*ivec)[0];
    if (enc) {
        while (l--) {
            if (n == 0) {
                c2l(iv, v0);
                c2l(iv, v1);

                ti[0] = v0;
                ti[1] = v1;
                DES_encrypt3(ti, ks1, ks2, ks3);
                v0 = ti[0];
                v1 = ti[1];

                iv = &(*ivec)[0];
                l2c(v0, iv);
                l2c(v1, iv);
                iv = &(*ivec)[0];
            }
            c = *(in++) ^ iv[n];
            *(out++) = c;
            iv[n] = c;
            n = (n + 1) & 0x07;
        }
    } else {
        while (l--) {
            if (n == 0) {
                c2l(iv, v0);
                c2l(iv, v1);

                ti[0] = v0;
                ti[1] = v1;
                DES_encrypt3(ti, ks1, ks2, ks3);
                v0 = ti[0];
                v1 = ti[1];

                iv = &(*ivec)[0];
                l2c(v0, iv);
                l2c(v1, iv);
                iv = &(*ivec)[0];
            }
            cc = *(in++);
            c = iv[n];
            iv[n] = cc;
            *(out++) = c ^ cc;
            n = (n + 1) & 0x07;
        }
    }
    v0 = v1 = ti[0] = ti[1] = c = cc = 0;
    *num = n;
}

#ifdef undef                    /* MACRO */
void DES_ede2_cfb64_encrypt(unsigned char *in, unsigned char *out,
                            long length, DES_key_schedule ks1,
                            DES_key_schedule ks2, DES_cblock (*ivec),
                            int *num, int enc)
{
    DES_ede3_cfb64_encrypt(in, out, length, ks1, ks2, ks1, ivec, num, enc);
}
Example #3
0
static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
			      const unsigned char *in, unsigned int inl)
{
	DES_ede3_cfb64_encrypt(in, out, (long)inl, 
			       &data(ctx)->ks1, &data(ctx)->ks2, &data(ctx)->ks3,
			       (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt);
	return 1;
}
Example #4
0
void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out,
  long length, des_key_schedule ks1, des_key_schedule ks2,
  des_key_schedule ks3, _ossl_old_des_cblock *ivec, int *num, int enc)
  {
  DES_ede3_cfb64_encrypt(in, out, length,
    (DES_key_schedule *)ks1, (DES_key_schedule *)ks2,
    (DES_key_schedule *)ks3, ivec, num, enc);
  }
Example #5
0
void TripleDESCryptor::Decrypt(const char* input, char* output, size_t length) const
{
	int n = 0;
	DES_cblock ivec = {0};
	DES_key_schedule ks1(ks1_);
	DES_key_schedule ks2(ks2_);
	DES_key_schedule ks3(ks3_);
	DES_ede3_cfb64_encrypt((const unsigned char*)input, (unsigned char*)output, length, &ks1, &ks2, &ks3, &ivec, &n, DES_DECRYPT);
}
Example #6
0
static void 
tripledes_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in,
			size_t count)
{
	DES_key_schedule *keys = crypt->encrypt_key;

	DES_ede3_cfb64_encrypt(in, out, (long)count,
		&keys[0], &keys[1], &keys[2], (DES_cblock *)(void *)crypt->iv,
		&crypt->num, DES_DECRYPT);
}
Example #7
0
static int check(unsigned char *keydata, int ks)
{
	// Decrypt first data block in order to check the first two bits of
	// the MPI. If they are correct, there's a good chance that the
	// password is correct, too.
	unsigned char ivec[32];
	unsigned char out[BIG_ENOUGH * 2] = { 0 };
	int tmp = 0;
	uint32_t num_bits;
	int checksumOk;
	int i;

	// Quick Hack
	memcpy(ivec, cur_salt->iv, blockSize(cur_salt->cipher_algorithm));
	switch (cur_salt->cipher_algorithm) {
		case CIPHER_IDEA: {
					   IDEA_KEY_SCHEDULE iks;
					   JtR_idea_set_encrypt_key(keydata, &iks);
					   JtR_idea_cfb64_encrypt(cur_salt->data, out, SALT_LENGTH, &iks, ivec, &tmp, IDEA_DECRYPT);
				   }
				   break;
		case CIPHER_CAST5: {
					   CAST_KEY ck;
					   CAST_set_key(&ck, ks, keydata);
					   CAST_cfb64_encrypt(cur_salt->data, out, CAST_BLOCK, &ck, ivec, &tmp, CAST_DECRYPT);
				   }
				   break;
		case CIPHER_BLOWFISH: {
					      BF_KEY ck;
					      BF_set_key(&ck, ks, keydata);
					      BF_cfb64_encrypt(cur_salt->data, out, BF_BLOCK, &ck, ivec, &tmp, BF_DECRYPT);
				      }
				      break;
		case CIPHER_AES128:
		case CIPHER_AES192:
		case CIPHER_AES256: {
					    AES_KEY ck;
					    AES_set_encrypt_key(keydata, ks * 8, &ck);
					    AES_cfb128_encrypt(cur_salt->data, out, AES_BLOCK_SIZE, &ck, ivec, &tmp, AES_DECRYPT);
				    }
				    break;
		case CIPHER_3DES: {
					  DES_cblock key1, key2, key3;
					  DES_cblock divec;
					  DES_key_schedule ks1, ks2, ks3;
					  int num = 0;
					  memcpy(key1, keydata + 0, 8);
					  memcpy(key2, keydata + 8, 8);
					  memcpy(key3, keydata + 16, 8);
					  memcpy(divec, ivec, 8);
					  DES_set_key((DES_cblock *)key1, &ks1);
					  DES_set_key((DES_cblock *)key2, &ks2);
					  DES_set_key((DES_cblock *)key3, &ks3);
					  DES_ede3_cfb64_encrypt(cur_salt->data, out, SALT_LENGTH, &ks1, &ks2, &ks3, &divec, &num, DES_DECRYPT);
				    }
				    break;

		default:
				    printf("(check) Unknown Cipher Algorithm %d ;(\n", cur_salt->cipher_algorithm);
				    break;
	}
	num_bits = ((out[0] << 8) | out[1]);
	if (num_bits < MIN_BN_BITS || num_bits > cur_salt->bits) {
		return 0;
	}
	// Decrypt all data
	memcpy(ivec, cur_salt->iv, blockSize(cur_salt->cipher_algorithm));
	tmp = 0;
	switch (cur_salt->cipher_algorithm) {
		case CIPHER_IDEA: {
					   IDEA_KEY_SCHEDULE iks;
					   JtR_idea_set_encrypt_key(keydata, &iks);
					   JtR_idea_cfb64_encrypt(cur_salt->data, out, cur_salt->datalen, &iks, ivec, &tmp, IDEA_DECRYPT);
				   }
				   break;
		case CIPHER_CAST5: {
					   CAST_KEY ck;
					   CAST_set_key(&ck, ks, keydata);
					   CAST_cfb64_encrypt(cur_salt->data, out, cur_salt->datalen, &ck, ivec, &tmp, CAST_DECRYPT);
				   }
				   break;
		case CIPHER_BLOWFISH: {
					      BF_KEY ck;
					      BF_set_key(&ck, ks, keydata);
					      BF_cfb64_encrypt(cur_salt->data, out, cur_salt->datalen, &ck, ivec, &tmp, BF_DECRYPT);
				      }
				      break;
		case CIPHER_AES128:
		case CIPHER_AES192:
		case CIPHER_AES256: {
					    AES_KEY ck;
					    AES_set_encrypt_key(keydata, ks * 8, &ck);
					    AES_cfb128_encrypt(cur_salt->data, out, cur_salt->datalen, &ck, ivec, &tmp, AES_DECRYPT);
				    }
				    break;
		case CIPHER_3DES: {
					  DES_cblock key1, key2, key3;
					  DES_cblock divec;
					  DES_key_schedule ks1, ks2, ks3;
					  int num = 0;
					  memcpy(key1, keydata + 0, 8);
					  memcpy(key2, keydata + 8, 8);
					  memcpy(key3, keydata + 16, 8);
					  memcpy(divec, ivec, 8);
					  DES_set_key((DES_cblock *) key1, &ks1);
					  DES_set_key((DES_cblock *) key2, &ks2);
					  DES_set_key((DES_cblock *) key3, &ks3);
					  DES_ede3_cfb64_encrypt(cur_salt->data, out, cur_salt->datalen, &ks1, &ks2, &ks3, &divec, &num, DES_DECRYPT);
				    }
				    break;
		default:
				    break;
	}
	// Verify
	checksumOk = 0;
	switch (cur_salt->usage) {
		case 254: {
				  uint8_t checksum[SHA_DIGEST_LENGTH];
				  SHA_CTX ctx;
				  SHA1_Init(&ctx);
				  SHA1_Update(&ctx, out, cur_salt->datalen - SHA_DIGEST_LENGTH);
				  SHA1_Final(checksum, &ctx);
				  if (memcmp(checksum, out + cur_salt->datalen - SHA_DIGEST_LENGTH, SHA_DIGEST_LENGTH) == 0)
					  return 1;  /* we have a 20 byte verifier ;) */
				  else
					  return 0;
			  } break;
		case 0:
		case 255: {
				  // https://tools.ietf.org/html/rfc4880#section-3.7.2
				  uint16_t sum = 0;
				  for (i = 0; i < cur_salt->datalen - 2; i++) {
					  sum += out[i];
				  }
				  if (sum == ((out[cur_salt->datalen - 2] << 8) | out[cur_salt->datalen - 1])) {
					  checksumOk = 1;
				  }
			  } break;
		default:
			  break;
	}
	// If the checksum is ok, try to parse the first MPI of the private key
	// Stop relying on checksum altogether, GnuPG ignores it (after
	// documenting why though!)
	if (checksumOk) {
		BIGNUM *b = NULL;
		uint32_t blen = (num_bits + 7) / 8;
		int ret;
		if (cur_salt->datalen == 24 && blen != 20)  /* verifier 1 */
			return 0;
		if (blen < cur_salt->datalen && ((b = BN_bin2bn(out + 2, blen, NULL)) != NULL)) {
			char *str = BN_bn2hex(b);
			DSA dsa;
			ElGamal_secret_key elg;
			RSA_secret_key rsa;
			if (strlen(str) != blen * 2) { /* verifier 2 */
				OPENSSL_free(str);
				return 0;
			}
			OPENSSL_free(str);

			if (cur_salt->pk_algorithm == 17) { /* DSA check */
				dsa.p = BN_bin2bn(cur_salt->p, cur_salt->pl, NULL);
				// puts(BN_bn2hex(dsa.p));
				dsa.q = BN_bin2bn(cur_salt->q, cur_salt->ql, NULL);
				// puts(BN_bn2hex(dsa.q));
				dsa.g = BN_bin2bn(cur_salt->g, cur_salt->gl, NULL);
				// puts(BN_bn2hex(dsa.g));
				dsa.priv_key = b;
				dsa.pub_key = BN_bin2bn(cur_salt->y, cur_salt->yl, NULL);
				// puts(BN_bn2hex(dsa.pub_key));
				ret = check_dsa_secret_key(&dsa); /* verifier 3 */
				if (ret != 0)
					return 0;
			}
			if (cur_salt->pk_algorithm == 16 || cur_salt->pk_algorithm == 20) { /* ElGamal check */
				elg.p = BN_bin2bn(cur_salt->p, cur_salt->pl, NULL);
				// puts(BN_bn2hex(elg.p));
				elg.g = BN_bin2bn(cur_salt->g, cur_salt->gl, NULL);
				// puts(BN_bn2hex(elg.g));
				elg.x = b;
				// puts(BN_bn2hex(elg.x));
				elg.y = BN_bin2bn(cur_salt->y, cur_salt->yl, NULL);
				// puts(BN_bn2hex(elg.y));
				ret = check_elg_secret_key(&elg); /* verifier 3 */
				if (ret != 0)
					return 0;
			}
			if (cur_salt->pk_algorithm == 1) { /* RSA check */
				// http://www.ietf.org/rfc/rfc4880.txt
				int length = 0;
				length += give_multi_precision_integer(out, length, &cur_salt->dl, cur_salt->d);
				length += give_multi_precision_integer(out, length, &cur_salt->pl, cur_salt->p);
				length += give_multi_precision_integer(out, length, &cur_salt->ql, cur_salt->q);

				rsa.n = BN_bin2bn(cur_salt->n, cur_salt->nl, NULL);
				rsa.p = BN_bin2bn(cur_salt->p, cur_salt->pl, NULL);
				rsa.q = BN_bin2bn(cur_salt->q, cur_salt->ql, NULL);

				ret = check_rsa_secret_key(&rsa);
				if (ret != 0)
					return 0;
			}
			return 1;
		}
	}
	return 0;
}
int main(void)
{
    int         i;
    BIO*        bio_out;

    DES_cblock          key1;
    DES_cblock          key2;
    DES_cblock          key3;
    DES_key_schedule    schedule1;
    DES_key_schedule    schedule2;
    DES_key_schedule    schedule3;

    unsigned char const iv_data[DES_KEY_SZ] = {
        0xcc, 0xfe, 0xcd, 0x3e, 0x21, 0xde, 0x1c, 0x31
    };

    unsigned char       iv[DES_KEY_SZ]; 

    char*   data    = "The worthwhile problems are the ones you can"
                      "really solve or help solve, the ones you can"
                      "really contribute something to. No "
                      "problem is too small or too trivial if we "
                      "can really do something about it."
                      "- Richard Feynman";
    
    int     length  = strlen(data);

    /* Intialise to '0' to indicate that '0' bytes of the IV has been used */
    int     num     = 0;

    char*	ciphertext = (char*) malloc(sizeof(char) * length); 
    char*	plaintext  = (char*) malloc(sizeof(char) * length); 

    /* Copy the IV data to the IV array. The IV array will be updated by the DES_cfb64_encrypt call.*/
    memcpy(iv, iv_data, DES_KEY_SZ);

    /* In this example, we shall be generating a random key. Before this can
     * happen, we must seed the PRNG. OpenSSL ensures that the PRNG is transparently 
     * seeded on systems that provide the "/dev/urandom" file. 
     */

    /* Cater for seeding the PRNG in Windows */
#ifdef OPENSSL_SYS_WIN32
    /* Add entropy */
#endif
   
    /* Generate the random keys (as expected by DES) */
    DES_random_key(&key1);
    DES_random_key(&key2);
    DES_random_key(&key3);

    /* Check the odd parity of the key and its weakness. In doing so, 
     * convert to the architecture dependent format.  
     */
    DES_set_key_checked(&key1, &schedule1);
    DES_set_key_checked(&key2, &schedule2);
    DES_set_key_checked(&key3, &schedule3);

    DES_ede3_cfb64_encrypt(data, ciphertext, length, &schedule1, &schedule2, &schedule3, (DES_cblock*)iv, &num, DES_ENCRYPT);

    bio_out = BIO_new_fp(stdout, BIO_NOCLOSE);

    BIO_printf(bio_out, "Original plaintext: %s\n\n", data);

    BIO_printf(bio_out, "Ciphertext: ");

    /* print out the ciphertext */
    for (i = 0; i < length; i++)
        BIO_printf(bio_out, "%02x", ((unsigned char*)ciphertext)[i]);
    
    BIO_printf(bio_out, "\n\n");

    /* start the decryption process */
    
    /* Re-intialise to '0' to indicate that '0' bytes of the IV has been used */
    num = 0;

    /* First, copy the original IV data back to the IV array - as it was 
     * overwritten during the encryption process 
     */
    memcpy(iv, iv_data, DES_KEY_SZ);

    DES_ede3_cfb64_encrypt(ciphertext, plaintext, length, &schedule1, &schedule2, &schedule3, (DES_cblock*)iv, &num, DES_DECRYPT);

    BIO_printf(bio_out, "Recovered plaintext: ");
    
    /* print out the plaintext */
    for (i = 0; i < length; i++)
        BIO_printf(bio_out, "%c", ((unsigned char*)plaintext)[i]);

    BIO_printf(bio_out, "\n");

    BIO_free(bio_out);
 
    free(ciphertext);
    free(plaintext);

    return 0;

}