Пример #1
0
static Variant mcrypt_generic(CObjRef td, CStrRef data, bool dencrypt) {
  MCrypt *pm = td.getTyped<MCrypt>();
  if (!pm->m_init) {
    raise_warning("Operation disallowed prior to mcrypt_generic_init().");
    return false;
  }

  if (data.empty()) {
    raise_warning("An empty string was passed");
    return false;
  }

  unsigned char* data_s;
  int block_size, data_size;
  /* Check blocksize */
  if (mcrypt_enc_is_block_mode(pm->m_td) == 1) { /* It's a block algorithm */
    block_size = mcrypt_enc_get_block_size(pm->m_td);
    data_size = (((data.size() - 1) / block_size) + 1) * block_size;
    data_s = (unsigned char*)malloc(data_size + 1);
    memset(data_s, 0, data_size);
    memcpy(data_s, data.data(), data.size());
  } else { /* It's not a block algorithm */
    data_size = data.size();
    data_s = (unsigned char*)malloc(data_size + 1);
    memcpy(data_s, data.data(), data.size());
  }

  if (dencrypt) {
    mdecrypt_generic(pm->m_td, data_s, data_size);
  } else {
    mcrypt_generic(pm->m_td, data_s, data_size);
  }
  data_s[data_size] = '\0';
  return String((char*)data_s, data_size, AttachString);
}
Пример #2
0
void dump_testcase_keysize(MCRYPT td, int key_size) {
    unsigned char *key, *iv = NULL;
    int iv_size, block_size;
    int mc_ret;
    padding_t padding;

    key = gen_rand_data(key_size);

    iv_size = mcrypt_enc_get_iv_size(td);
    if (iv_size != 0) {
        iv = gen_rand_data(iv_size);
    }

    /*
     * Generate a test case for these plaintext sizes:
     *
     *  * empty:              test behavior of padding on empty blocks
     *  * 5-byte:             odd, and smaller than any block size
     *  * block_size - 1:     edge case
     *  * block_size:         generally guaranteed to work
     *  * block_size * 2 - 1: multiblock edge case
     *  * block_size * 3:     more multiblock
     */
    block_size = mcrypt_enc_get_block_size(td);

    padding = mcrypt_enc_is_block_mode(td) ? PADDING_PKCS7 : PADDING_NONE;

    for (; padding <= PADDING_ZEROS; padding++) {
        dump_testcase_block(td, key, key_size, iv, iv_size, 0, padding);
        dump_testcase_block(td, key, key_size, iv, iv_size, 5, padding);
        dump_testcase_block(td, key, key_size, iv, iv_size, block_size - 1,
                            padding);
        dump_testcase_block(td, key, key_size, iv, iv_size, block_size,
                            padding);
        dump_testcase_block(td, key, key_size, iv, iv_size,
                            block_size * 2 - 1, padding);
        dump_testcase_block(td, key, key_size, iv, iv_size, block_size * 3,
                            padding);
    }

    free(key);
    if (iv) free(iv);

    return;
}
Пример #3
0
static Variant mcrypt_generic(const Resource& td, const String& data,
                              bool dencrypt) {
  auto pm = cast<MCrypt>(td);
  if (!pm->m_init) {
    raise_warning("Operation disallowed prior to mcrypt_generic_init().");
    return false;
  }

  if (data.empty()) {
    raise_warning("An empty string was passed");
    return false;
  }

  String s;
  unsigned char* data_s;
  int block_size, data_size;
  /* Check blocksize */
  if (mcrypt_enc_is_block_mode(pm->m_td) == 1) { /* It's a block algorithm */
    block_size = mcrypt_enc_get_block_size(pm->m_td);
    data_size = (((data.size() - 1) / block_size) + 1) * block_size;
    s = String(data_size, ReserveString);
    data_s = (unsigned char *)s.mutableData();
    memset(data_s, 0, data_size);
    memcpy(data_s, data.data(), data.size());
  } else { /* It's not a block algorithm */
    data_size = data.size();
    s = String(data_size, ReserveString);
    data_s = (unsigned char *)s.mutableData();
    memcpy(data_s, data.data(), data.size());
  }

  if (dencrypt) {
    mdecrypt_generic(pm->m_td, data_s, data_size);
  } else {
    mcrypt_generic(pm->m_td, data_s, data_size);
  }
  s.setSize(data_size);
  return s;
}
Пример #4
0
static Variant php_mcrypt_do_crypt(CStrRef cipher, CStrRef key, CStrRef data,
                                   CStrRef mode, CStrRef iv, bool dencrypt) {
  MCRYPT td = mcrypt_module_open((char*)cipher.data(),
                                 (char*)MCG(algorithms_dir).data(),
                                 (char*)mode.data(),
                                 (char*)MCG(modes_dir).data());
  if (td == MCRYPT_FAILED) {
    raise_warning(MCRYPT_OPEN_MODULE_FAILED);
    return false;
  }

  /* Checking for key-length */
  int max_key_length = mcrypt_enc_get_key_size(td);
  if (key.size() > max_key_length) {
    raise_warning("Size of key is too large for this algorithm");
  }
  int count;
  int *key_length_sizes = mcrypt_enc_get_supported_key_sizes(td, &count);
  int use_key_length;
  char *key_s = NULL;
  if (count == 0 && key_length_sizes == NULL) { // all lengths 1 - k_l_s = OK
    use_key_length = key.size();
    key_s = (char*)malloc(use_key_length);
    memcpy(key_s, key.data(), use_key_length);
  } else if (count == 1) {  /* only m_k_l = OK */
    key_s = (char*)malloc(key_length_sizes[0]);
    memset(key_s, 0, key_length_sizes[0]);
    memcpy(key_s, key.data(), MIN(key.size(), key_length_sizes[0]));
    use_key_length = key_length_sizes[0];
  } else { /* dertermine smallest supported key > length of requested key */
    use_key_length = max_key_length; /* start with max key length */
    for (int i = 0; i < count; i++) {
      if (key_length_sizes[i] >= key.size() &&
          key_length_sizes[i] < use_key_length) {
        use_key_length = key_length_sizes[i];
      }
    }
    key_s = (char*)malloc(use_key_length);
    memset(key_s, 0, use_key_length);
    memcpy(key_s, key.data(), MIN(key.size(), use_key_length));
  }
  mcrypt_free(key_length_sizes);

  /* Check IV */
  char *iv_s = NULL;
  int iv_size = mcrypt_enc_get_iv_size(td);

  /* IV is required */
  if (mcrypt_enc_mode_has_iv(td) == 1) {
    if (!iv.empty()) {
      if (iv_size != iv.size()) {
        raise_warning("The IV parameter must be as long as the blocksize");
      } else {
        iv_s = (char*)malloc(iv_size + 1);
        memcpy(iv_s, iv.data(), iv_size);
      }
    } else {
      raise_warning("Attempt to use an empty IV, which is NOT recommended");
      iv_s = (char*)malloc(iv_size + 1);
      memset(iv_s, 0, iv_size + 1);
    }
  }

  int block_size;
  unsigned long int data_size;
  String s;
  char *data_s;
  /* Check blocksize */
  if (mcrypt_enc_is_block_mode(td) == 1) { /* It's a block algorithm */
    block_size = mcrypt_enc_get_block_size(td);
    data_size = (((data.size() - 1) / block_size) + 1) * block_size;
    s = String(data_size, ReserveString);
    data_s = (char*)s.mutableSlice().ptr;
    memset(data_s, 0, data_size);
    memcpy(data_s, data.data(), data.size());
  } else { /* It's not a block algorithm */
    data_size = data.size();
    s = String(data_size, ReserveString);
    data_s = (char*)s.mutableSlice().ptr;
    memcpy(data_s, data.data(), data.size());
  }

  if (mcrypt_generic_init(td, key_s, use_key_length, iv_s) < 0) {
    raise_warning("Mcrypt initialisation failed");
    return false;
  }
  if (dencrypt) {
    mdecrypt_generic(td, data_s, data_size);
  } else {
    mcrypt_generic(td, data_s, data_size);
  }

  /* freeing vars */
  mcrypt_generic_end(td);
  if (key_s != NULL) {
    free(key_s);
  }
  if (iv_s != NULL) {
    free(iv_s);
  }
  return s.setSize(data_size);
}
Пример #5
0
bool f_mcrypt_enc_is_block_mode(CObjRef td) {
  return mcrypt_enc_is_block_mode(td.getTyped<MCrypt>()->m_td) == 1;
}
Пример #6
0
int main()
{
	MCRYPT td, td2;
	int i, t, imax;
	int j, jmax, ivsize;
	int x = 0, siz;
	char **names;
	char **modes;
	char *text;
	unsigned char *IV;
	unsigned char *key;
	int keysize;
	
	names = mcrypt_list_algorithms (ALGORITHMS_DIR, &jmax);
	modes = mcrypt_list_modes (MODES_DIR, &imax);

	if (names==NULL || modes==NULL) {
		fprintf(stderr, "Error getting algorithms/modes\n");
		exit(1);
	}
	
	for (j=0;j<jmax;j++) {
		printf( "Algorithm: %s... ", names[j]);

		if (mcrypt_module_self_test( names[j], ALGORITHMS_DIR)==0) {
			printf( "ok\n");
		} else {
			x=1;
			printf( "\n");
		}
		printf( "Modes:\n");
			for (i=0;i<imax;i++) {
				td = mcrypt_module_open(names[j], ALGORITHMS_DIR, modes[i], MODES_DIR);
				td2 = mcrypt_module_open(names[j], ALGORITHMS_DIR, modes[i], MODES_DIR);
				if (td != MCRYPT_FAILED && td2 != MCRYPT_FAILED) {
					keysize = mcrypt_enc_get_key_size(td);
					key = calloc(1, keysize);
					if (key==NULL) exit(1);
					
					for (t=0;t<keysize;t++)
						key[t] = (t % 255) + 13;
					
					ivsize = mcrypt_enc_get_iv_size(td);
					if (ivsize>0) {
						IV = calloc( 1, ivsize);
						if (IV==NULL) exit(1);
						for (t=0;t<ivsize;t++)
							IV[t] = (t*2 % 255) + 15;
					}
					if (mcrypt_generic_init( td, key, keysize, IV) < 0) {
						fprintf(stderr, "Failed to Initialize algorithm!\n");
						return -1;
					}

					if (mcrypt_enc_is_block_mode(td)!=0)
						siz = (strlen(TEXT) / mcrypt_enc_get_block_size(td))*mcrypt_enc_get_block_size(td);
					else siz = strlen(TEXT);

					text = calloc( 1, siz);
					if (text==NULL) exit(1);
					
					memmove( text, TEXT, siz);

					mcrypt_generic( td, text, siz);

					if (mcrypt_generic_init( td2, key, keysize, IV) < 0) {
						fprintf(stderr, "Failed to Initialize algorithm!\n");
						return -1;
					}

					mdecrypt_generic( td2, text, siz);
					if ( memcmp( text, TEXT, siz) == 0) {
						printf( "   %s: ok\n", modes[i]);
					} else {
						printf( "   %s: failed\n", modes[i]);
						x=1;
					}
					mcrypt_generic_deinit(td);
					mcrypt_generic_deinit(td2);
					mcrypt_module_close(td);
					mcrypt_module_close(td2);					free(text);
					free(key);
					if (ivsize>0) free(IV);
				}
			}
		printf("\n");
		
	}	
	mcrypt_free_p(names, jmax);
	mcrypt_free_p(modes, imax);
	

	if (x>0) fprintf(stderr, "\nProbably some of the algorithms listed above failed. "
				"Try not to use these algorithms, and file a bug report to [email protected]\n\n");
	return x;
}
Пример #7
0
void dump_testcase_block(MCRYPT td, unsigned char *key, int key_size,
                         unsigned char *iv, int iv_size, int data_size,
                         padding_t padding) {
    int mc_ret;
    int is_block, block_size, block_overlap, block_fill;
    int i;
    unsigned char *plaintext, *ciphertext;

    mc_ret = mcrypt_generic_init(td, (void *)key, key_size, (void *)iv);
    if (mc_ret < 0) {
        mcrypt_perror(mc_ret);
        return;
    }

    plaintext = gen_rand_data(data_size);
    if (plaintext == NULL) {
        return;
    }

    is_block = mcrypt_enc_is_block_mode(td);
    if (is_block) {
        block_size = mcrypt_enc_get_block_size(td);
        block_overlap = data_size % block_size;
        block_fill = block_size - block_overlap;
        if (padding == PADDING_NONE) {
            /* do nothing */
        }
        else if (padding == PADDING_PKCS7) {
            if (block_fill == 0) {
                /* ALWAYS add padding */
                block_fill = block_size;
            }
            plaintext = (unsigned char *)realloc(plaintext,
                                                 data_size + block_fill);
            for (i = 0; i < block_fill; i++) {
                plaintext[data_size+i] = block_fill;
            }
            data_size = data_size + block_fill;
            if ((data_size % block_size) != 0) {
                fprintf(stderr, "bad data size!\n");
                exit(1);
            }
        }
        else if (padding == PADDING_ZEROS) {
            if (block_overlap != 0) {
                plaintext = (unsigned char *)realloc(plaintext,
                                                     data_size + block_fill);
                for (i = 0; i < block_fill; i++) {
                    plaintext[data_size+i] = '\0';
                }
                data_size = data_size + block_fill;
            }
        }
        else {
            fprintf(stderr, "bad error\n");
            exit(1);
        }
    }

    ciphertext = malloc(data_size);
    if (ciphertext == NULL) {
        fprintf(stderr, "Out of memory\n");
        return;
    }

    memcpy( (void *)ciphertext, (void *)plaintext, data_size);

    mc_ret = mcrypt_generic(td, ciphertext, data_size);
    if (mc_ret == 0) {
        char *enc_key, *enc_iv, *enc_pt, *enc_ct;
        enc_key = dump_value( (void *)key, key_size );
        enc_iv  = dump_value( (void *)iv, iv_size );
        enc_pt  = dump_value( (void *)plaintext, data_size );
        enc_ct  = dump_value( (void *)ciphertext, data_size );

        printf("algo=%s,mode=%s,key=%s,iv=%s,padding=%s,pt=%s,ct=%s\n",
               testing_algo, testing_mode, enc_key, enc_iv,
               padding_name(padding), enc_pt, enc_ct);

        free(enc_key);
        free(enc_iv);
        free(enc_pt);
        free(enc_ct);
    }

    free(plaintext);
    free(ciphertext);

    mc_ret = mcrypt_generic_deinit(td);
    if (mc_ret < 0) {
        fprintf(stderr, "Error %d during deinit of %s in %s mode"
                " (%d-byte key)\n", testing_algo, testing_mode, key_size);
        return;
    }
}
Пример #8
0
bool HHVM_FUNCTION(mcrypt_enc_is_block_mode, const Resource& td) {
  return mcrypt_enc_is_block_mode(cast<MCrypt>(td)->m_td) == 1;
}
Пример #9
0
bool HHVM_FUNCTION(mcrypt_enc_is_block_mode, const Resource& td) {
  return mcrypt_enc_is_block_mode(td.getTyped<MCrypt>()->m_td) == 1;
}
Пример #10
0
/* {{{ php_mcrypt_filter_create
 * Instantiate mcrypt filter
 */
static php_stream_filter *php_mcrypt_filter_create(const char *filtername, zval *filterparams, int persistent)
{
	int encrypt = 1, iv_len, key_len, keyl, result;
	const char *cipher = filtername + sizeof("mcrypt.") - 1;
	zval *tmpzval;
	MCRYPT mcrypt_module;
	char *iv = NULL, *key = NULL;
	char *algo_dir = INI_STR("mcrypt.algorithms_dir");
	char *mode_dir = INI_STR("mcrypt.modes_dir");
	char *mode = "cbc";
	php_mcrypt_filter_data *data;

	if (strncasecmp(filtername, "mdecrypt.", sizeof("mdecrypt.") - 1) == 0) {
		encrypt = 0;
		cipher += sizeof("de") - 1;
	} else if (strncasecmp(filtername, "mcrypt.", sizeof("mcrypt.") - 1) != 0) {
		/* Should never happen */
		return NULL;
	}

	if (!filterparams || Z_TYPE_P(filterparams) != IS_ARRAY) {
		php_error_docref(NULL, E_WARNING, "Filter parameters for %s must be an array", filtername);
		return NULL;
	}

	if ((tmpzval = zend_hash_str_find(Z_ARRVAL_P(filterparams), ZEND_STRL("mode")))) {
		if (Z_TYPE_P(tmpzval) == IS_STRING) {
			mode = Z_STRVAL_P(tmpzval);
		} else {
			php_error_docref(NULL, E_WARNING, "mode is not a string, ignoring");
		}
	}

	if ((tmpzval=zend_hash_str_find(Z_ARRVAL_P(filterparams), ZEND_STRL("algorithms_dir")))) {
		if (Z_TYPE_P(tmpzval) == IS_STRING) {
			algo_dir = Z_STRVAL_P(tmpzval);
		} else {
			php_error_docref(NULL, E_WARNING, "algorithms_dir is not a string, ignoring");
		}
	}

	if ((tmpzval=zend_hash_str_find(Z_ARRVAL_P(filterparams), ZEND_STRL("modes_dir")))) {
		if (Z_TYPE_P(tmpzval) == IS_STRING) {
			mode_dir = Z_STRVAL_P(tmpzval);
		} else {
			php_error_docref(NULL, E_WARNING, "modes_dir is not a string, ignoring");
		}
	}

	if ((tmpzval = zend_hash_str_find(Z_ARRVAL_P(filterparams), ZEND_STRL("key"))) &&
		Z_TYPE_P(tmpzval) == IS_STRING) {
		key = Z_STRVAL_P(tmpzval);
		key_len = (int)Z_STRLEN_P(tmpzval);
	} else {
		php_error_docref(NULL, E_WARNING, "key not specified or is not a string");
		return NULL;
	}

	mcrypt_module = mcrypt_module_open((char *)cipher, algo_dir, mode, mode_dir);
	if (mcrypt_module == MCRYPT_FAILED) {
		php_error_docref(NULL, E_WARNING, "Could not open encryption module");
		return NULL;
	}
	iv_len = mcrypt_enc_get_iv_size(mcrypt_module);
	keyl = mcrypt_enc_get_key_size(mcrypt_module);
	if (keyl < key_len) {
		key_len = keyl;
	}

	if (!(tmpzval = zend_hash_str_find(Z_ARRVAL_P(filterparams), ZEND_STRL("iv"))) ||
		Z_TYPE_P(tmpzval) != IS_STRING) {
		php_error_docref(NULL, E_WARNING, "Filter parameter[iv] not provided or not of type: string");
		mcrypt_module_close(mcrypt_module);
		return NULL;
	}

	iv = emalloc(iv_len + 1);
	if ((size_t)iv_len <= Z_STRLEN_P(tmpzval)) {
		memcpy(iv, Z_STRVAL_P(tmpzval), iv_len);
	} else {
		memcpy(iv, Z_STRVAL_P(tmpzval), Z_STRLEN_P(tmpzval));
		memset(iv + Z_STRLEN_P(tmpzval), 0, iv_len - Z_STRLEN_P(tmpzval));
	}

	result = mcrypt_generic_init(mcrypt_module, key, key_len, iv);
	efree(iv);
	if (result < 0) {
		switch (result) {
			case -3:
				php_error_docref(NULL, E_WARNING, "Key length incorrect");
				break;
			case -4:
				php_error_docref(NULL, E_WARNING, "Memory allocation error");
				break;
			case -1:
			default:
				php_error_docref(NULL, E_WARNING, "Unknown error");
				break;
		}
		mcrypt_module_close(mcrypt_module);
		return NULL;
	}

	data = pemalloc(sizeof(php_mcrypt_filter_data), persistent);
	data->module = mcrypt_module;
	data->encrypt = encrypt;
	if (mcrypt_enc_is_block_mode(mcrypt_module)) {
		data->blocksize = mcrypt_enc_get_block_size(mcrypt_module);
		data->block_buffer = pemalloc(data->blocksize, persistent);
	} else {
		data->blocksize = 0;
		data->block_buffer = NULL;
	}
	data->block_used = 0;
	data->persistent = persistent;

	return php_stream_filter_alloc(&php_mcrypt_filter_ops, data, persistent);
}
Пример #11
0
int main()
{
	MCRYPT td, td2;
	int i, t, imax;
	int j, jmax, ivsize;
	int x = 0, siz;
	char *text;
	unsigned char *IV;
	unsigned char *key;
	int keysize;
	
    td = mcrypt_module_open("idea", ALGORITHMS_DIR, "cbc", MODES_DIR);
    td2 = mcrypt_module_open("idea", ALGORITHMS_DIR, "cbc", MODES_DIR);

    if (td != MCRYPT_FAILED && td2 != MCRYPT_FAILED) {
        fprintf(stderr, "Created IDEA cipher.\n");

        keysize = mcrypt_enc_get_key_size(td);
        fprintf(stderr, "Cipher key size %d.\n", keysize);

        key = calloc(1, keysize);
        if (key==NULL) exit(1);
					
        for (t=0;t<keysize;t++)
            key[t] = (t % 255) + 13;
					
        ivsize = mcrypt_enc_get_iv_size(td);
        fprintf(stderr, "IV size %d.\n", ivsize);
        if (ivsize>0) {
            IV = calloc( 1, ivsize);
            if (IV==NULL) exit(1);
            for (t=0;t<ivsize;t++)
                IV[t] = (t*2 % 255) + 15;
        }

        if (mcrypt_generic_init( td, key, keysize, IV) < 0) {
            fprintf(stderr, "Failed to Initialize algorithm!\n");
            return -1;
        }

        if (mcrypt_enc_is_block_mode(td)!=0)
            siz = (strlen(TEXT) / mcrypt_enc_get_block_size(td))*mcrypt_enc_get_block_size(td);
        else siz = strlen(TEXT);

        text = calloc( 1, siz);
        if (text==NULL) exit(1);
					
        memmove( text, TEXT, siz);

        mcrypt_generic( td, text, siz);

        if (mcrypt_generic_init( td2, key, keysize, IV) < 0) {
            fprintf(stderr, "Failed to Initialize algorithm!\n");
            return -1;
        }

        mdecrypt_generic( td2, text, siz);
        if ( memcmp( text, TEXT, siz) == 0) {
            printf( "   %s: ok\n", "cbc");
        } else {
            printf( "   %s: failed\n", "cbc");
            x=1;
        }

        mcrypt_generic_deinit(td);
        mcrypt_generic_deinit(td2);
        mcrypt_module_close(td);
        mcrypt_module_close(td2);
        free(text);
        free(key);
        if (ivsize>0) free(IV);
    }

    return 0;
}