diff --git a/MANIFEST.in b/MANIFEST.in index bbb10fd4..4a456feb 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,8 +1,7 @@ include MANIFEST.in -include ACKS build-aux/* ChangeLog COPYRIGHT Doc/* TODO +include ACKS ChangeLog COPYRIGHT Doc/* TODO graft LEGAL recursive-include src *.h *.c -include buildenv.in include src/config.h.in include *.py -include configure +include configure configure.ac diff --git a/configure b/configure index f4fd00bb..9f3694f0 100755 --- a/configure +++ b/configure @@ -1,11 +1,13 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for FULL-PACKAGE-NAME VERSION. +# Generated by GNU Autoconf 2.68 for FULL-PACKAGE-NAME VERSION. # # Report bugs to . # # -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +# Foundation, Inc. # # # This configure script is free software; the Free Software Foundation @@ -134,31 +136,6 @@ export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh @@ -192,8 +169,7 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" +test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && @@ -238,25 +214,21 @@ IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 + # We cannot yet assume a decent shell, so we have to provide a + # neutralization value for shells without unset; and this also + # works around shells that cannot unset nonexistent variables. + # Preserve -v and -x to the replacement shell. + BASH_ENV=/dev/null + ENV=/dev/null + (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV + export CONFIG_SHELL + case $- in # (((( + *v*x* | *x*v* ) as_opts=-vx ;; + *v* ) as_opts=-v ;; + *x* ) as_opts=-x ;; + * ) as_opts= ;; + esac + exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : @@ -359,14 +331,6 @@ $as_echo X"$as_dir" | } # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take @@ -488,10 +452,6 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). @@ -526,16 +486,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. + # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' + as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -pR' + as_ln_s='cp -p' fi else - as_ln_s='cp -pR' + as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -547,8 +507,28 @@ else as_mkdir_p=false fi -as_test_x='test -x' -as_executable_p=as_fn_executable_p +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -622,31 +602,11 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='am__EXEEXT_FALSE -am__EXEEXT_TRUE -LTLIBOBJS +ac_subst_vars='LTLIBOBJS LIBOBJS EGREP GREP CPP -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -am__fastdepCC_FALSE -am__fastdepCC_TRUE -CCDEPMODE -am__nodep -AMDEPBACKSLASH -AMDEP_FALSE -AMDEP_TRUE -am__quote -am__include -DEPDIR OBJEXT EXEEXT ac_ct_CC @@ -654,33 +614,6 @@ CPPFLAGS LDFLAGS CFLAGS CC -AM_BACKSLASH -AM_DEFAULT_VERBOSITY -AM_DEFAULT_V -AM_V -am__untar -am__tar -AMTAR -am__leading_dot -SET_MAKE -AWK -mkdir_p -MKDIR_P -INSTALL_STRIP_PROGRAM -STRIP -install_sh -MAKEINFO -AUTOHEADER -AUTOMAKE -AUTOCONF -ACLOCAL -VERSION -PACKAGE -CYGPATH_W -am__isrc -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM target_alias host_alias build_alias @@ -722,8 +655,6 @@ SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking -enable_silent_rules -enable_dependency_tracking with_gmp with_mpir ' @@ -1191,6 +1122,8 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe + $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi @@ -1333,15 +1266,6 @@ Fine tuning of the installation directories: _ACEOF cat <<\_ACEOF - -Program names: - --program-prefix=PREFIX prepend PREFIX to installed program names - --program-suffix=SUFFIX append SUFFIX to installed program names - --program-transform-name=PROGRAM run sed PROGRAM on installed program names - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi @@ -1351,17 +1275,6 @@ if test -n "$ac_init_help"; then esac cat <<\_ACEOF -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-silent-rules less verbose build output (undo: "make V=1") - --disable-silent-rules verbose build output (undo: "make V=0") - --enable-dependency-tracking - do not reject slow dependency extractors - --disable-dependency-tracking - speeds up one-time build - Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) @@ -1445,9 +1358,9 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF FULL-PACKAGE-NAME configure VERSION -generated by GNU Autoconf 2.69 +generated by GNU Autoconf 2.68 -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1523,7 +1436,7 @@ $as_echo "$ac_try_echo"; } >&5 test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || - test -x conftest$ac_exeext + $as_test_x conftest$ac_exeext }; then : ac_retval=0 else @@ -1814,8 +1727,7 @@ int main () { static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))]; -test_array [0] = 0; -return test_array [0]; +test_array [0] = 0 ; return 0; @@ -1831,8 +1743,7 @@ main () { static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1) < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))]; -test_array [0] = 0; -return test_array [0]; +test_array [0] = 0 ; return 0; @@ -1943,8 +1854,7 @@ int main () { static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)]; -test_array [0] = 0; -return test_array [0]; +test_array [0] = 0 ; return 0; @@ -2044,7 +1954,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by FULL-PACKAGE-NAME $as_me VERSION, which was -generated by GNU Autoconf 2.69. Invocation command line was +generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2394,255 +2304,23 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers src/config.h" -ac_aux_dir= -for ac_dir in build-aux "$srcdir"/build-aux; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - - -ac_config_files="$ac_config_files buildenv" - - -am__api_version='1.14' - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 -$as_echo_n "checking whether build environment is sane... " >&6; } -# Reject unsafe characters in $srcdir or the absolute working directory -# name. Accept space and tab only in the latter. -am_lf=' -' -case `pwd` in - *[\\\"\#\$\&\'\`$am_lf]*) - as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; -esac -case $srcdir in - *[\\\"\#\$\&\'\`$am_lf\ \ ]*) - as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; -esac - -# Do 'set' in a subshell so we don't clobber the current shell's -# arguments. Must try -L first in case configure is actually a -# symlink; some systems play weird games with the mod time of symlinks -# (eg FreeBSD returns the mod time of the symlink's containing -# directory). -if ( - am_has_slept=no - for am_try in 1 2; do - echo "timestamp, slept: $am_has_slept" > conftest.file - set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` - if test "$*" = "X"; then - # -L didn't work. - set X `ls -t "$srcdir/configure" conftest.file` - fi - if test "$*" != "X $srcdir/configure conftest.file" \ - && test "$*" != "X conftest.file $srcdir/configure"; then - - # If neither matched, then we have a broken ls. This can happen - # if, for instance, CONFIG_SHELL is bash and it inherits a - # broken ls alias from the environment. This has actually - # happened. Such a system could not be considered "sane". - as_fn_error $? "ls -t appears to fail. Make sure there is not a broken - alias in your environment" "$LINENO" 5 - fi - if test "$2" = conftest.file || test $am_try -eq 2; then - break - fi - # Just in case. - sleep 1 - am_has_slept=yes - done - test "$2" = conftest.file - ) -then - # Ok. - : -else - as_fn_error $? "newly created file is older than distributed files! -Check your system clock" "$LINENO" 5 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -# If we didn't sleep, we still need to ensure time stamps of config.status and -# generated files are strictly newer. -am_sleep_pid= -if grep 'slept: no' conftest.file >/dev/null 2>&1; then - ( sleep 1 ) & - am_sleep_pid=$! -fi - -rm -f conftest.file - -test "$program_prefix" != NONE && - program_transform_name="s&^&$program_prefix&;$program_transform_name" -# Use a double $ so make ignores it. -test "$program_suffix" != NONE && - program_transform_name="s&\$&$program_suffix&;$program_transform_name" -# Double any \ or $. -# By default was `s,x,x', remove it if useless. -ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' -program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` - -# expand $ac_aux_dir to an absolute path -am_aux_dir=`cd $ac_aux_dir && pwd` - -if test x"${MISSING+set}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; - *) - MISSING="\${SHELL} $am_aux_dir/missing" ;; - esac -fi -# Use eval to expand $SHELL -if eval "$MISSING --is-lightweight"; then - am_missing_run="$MISSING " -else - am_missing_run= - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 -$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;} -fi - -if test x"${install_sh}" != xset; then - case $am_aux_dir in - *\ * | *\ *) - install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; - *) - install_sh="\${SHELL} $am_aux_dir/install-sh" - esac -fi -# Installed binaries are usually stripped using 'strip' when the user -# run "make install-strip". However 'strip' might not be the right -# tool to use in cross-compilation environments, therefore Automake -# will honor the 'STRIP' environment variable to overrule this program. -if test "$cross_compiling" != no; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 +# Checks for programs. +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -2650,8 +2328,8 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -2661,10 +2339,10 @@ IFS=$as_save_IFS fi fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } @@ -2672,17 +2350,17 @@ fi fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : +if ${ac_cv_prog_ac_ct_CC+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -2690,8 +2368,8 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -2701,17 +2379,17 @@ IFS=$as_save_IFS fi fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi - if test "x$ac_ct_STRIP" = x; then - STRIP=":" + if test "x$ac_ct_CC" = x; then + CC="" else case $cross_compiling:$ac_tool_warned in yes:) @@ -2719,68 +2397,23 @@ yes:) $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac - STRIP=$ac_ct_STRIP + CC=$ac_ct_CC fi else - STRIP="$ac_cv_prog_STRIP" -fi - -fi -INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 -$as_echo_n "checking for a thread-safe mkdir -p... " >&6; } -if test -z "$MKDIR_P"; then - if ${ac_cv_path_mkdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in mkdir gmkdir; do - for ac_exec_ext in '' $ac_executable_extensions; do - as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue - case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( - 'mkdir (GNU coreutils) '* | \ - 'mkdir (coreutils) '* | \ - 'mkdir (fileutils) '4.1*) - ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext - break 3;; - esac - done - done - done -IFS=$as_save_IFS - -fi - - test -d ./--version && rmdir ./--version - if test "${ac_cv_path_mkdir+set}" = set; then - MKDIR_P="$ac_cv_path_mkdir -p" - else - # As a last resort, use the slow shell script. Don't cache a - # value for MKDIR_P within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - MKDIR_P="$ac_install_sh -d" - fi + CC="$ac_cv_prog_CC" fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 -$as_echo "$MKDIR_P" >&6; } -for ac_prog in gawk mawk nawk awk -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AWK+:} false; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else - if test -n "$AWK"; then - ac_cv_prog_AWK="$AWK" # Let the user override the test. + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -2788,8 +2421,8 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AWK="$ac_prog" + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -2799,277 +2432,21 @@ IFS=$as_save_IFS fi fi -AWK=$ac_cv_prog_AWK -if test -n "$AWK"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 -$as_echo "$AWK" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$AWK" && break -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 -$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } -set x ${MAKE-make} -ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` -if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat >conftest.make <<\_ACEOF -SHELL = /bin/sh -all: - @echo '@@@%%%=$(MAKE)=@@@%%%' -_ACEOF -# GNU make sometimes prints "make[1]: Entering ...", which would confuse us. -case `${MAKE-make} -f conftest.make 2>/dev/null` in - *@@@%%%=?*=@@@%%%*) - eval ac_cv_prog_make_${ac_make}_set=yes;; - *) - eval ac_cv_prog_make_${ac_make}_set=no;; -esac -rm -f conftest.make -fi -if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - SET_MAKE= +CC=$ac_cv_prog_CC +if test -n "$CC"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 +$as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - SET_MAKE="MAKE=${MAKE-make}" -fi - -rm -rf .tst 2>/dev/null -mkdir .tst 2>/dev/null -if test -d .tst; then - am__leading_dot=. -else - am__leading_dot=_ -fi -rmdir .tst 2>/dev/null - -# Check whether --enable-silent-rules was given. -if test "${enable_silent_rules+set}" = set; then : - enableval=$enable_silent_rules; -fi - -case $enable_silent_rules in # ((( - yes) AM_DEFAULT_VERBOSITY=0;; - no) AM_DEFAULT_VERBOSITY=1;; - *) AM_DEFAULT_VERBOSITY=1;; -esac -am_make=${MAKE-make} -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 -$as_echo_n "checking whether $am_make supports nested variables... " >&6; } -if ${am_cv_make_support_nested_variables+:} false; then : - $as_echo_n "(cached) " >&6 -else - if $as_echo 'TRUE=$(BAR$(V)) -BAR0=false -BAR1=true -V=1 -am__doit: - @$(TRUE) -.PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then - am_cv_make_support_nested_variables=yes -else - am_cv_make_support_nested_variables=no -fi fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 -$as_echo "$am_cv_make_support_nested_variables" >&6; } -if test $am_cv_make_support_nested_variables = yes; then - AM_V='$(V)' - AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' -else - AM_V=$AM_DEFAULT_VERBOSITY - AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY -fi -AM_BACKSLASH='\' - -if test "`cd $srcdir && pwd`" != "`pwd`"; then - # Use -I$(srcdir) only when $(srcdir) != ., so that make's output - # is not polluted with repeated "-I." - am__isrc=' -I$(srcdir)' - # test to see if srcdir already configured - if test -f $srcdir/config.status; then - as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 - fi -fi - -# test whether we have cygpath -if test -z "$CYGPATH_W"; then - if (cygpath --version) >/dev/null 2>/dev/null; then - CYGPATH_W='cygpath -w' - else - CYGPATH_W=echo - fi -fi - - -# Define the identity of the package. - PACKAGE='full-package-name' - VERSION='VERSION' - - -# Some tools Automake needs. - -ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} - - -AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} - - -AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} - - -AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} - - -MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} - -# For better backward compatibility. To be removed once Automake 1.9.x -# dies out for good. For more background, see: -# -# -mkdir_p='$(MKDIR_P)' - -# We need awk for the "check" target. The system "awk" is bad on -# some platforms. -# Always define AMTAR for backward compatibility. Yes, it's still used -# in the wild :-( We should find a proper way to deprecate it ... -AMTAR='$${TAR-tar}' - - -# We'll loop over all known methods to create a tar archive until one works. -_am_tools='gnutar pax cpio none' - -am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' - - - - - - -# POSIX will say in a future version that running "rm -f" with no argument -# is OK; and we want to be able to make that assumption in our Makefile -# recipes. So use an aggressive probe to check that the usage we want is -# actually supported "in the wild" to an acceptable degree. -# See automake bug#10828. -# To make any issue more visible, cause the running configure to be aborted -# by default if the 'rm' program in use doesn't match our expectations; the -# user can still override this though. -if rm -f && rm -fr && rm -rf; then : OK; else - cat >&2 <<'END' -Oops! - -Your 'rm' program seems unable to run without file operands specified -on the command line, even when the '-f' option is present. This is contrary -to the behaviour of most rm programs out there, and not conforming with -the upcoming POSIX standard: -Please tell bug-automake@gnu.org about your system, including the value -of your $PATH and any error possibly output before this message. This -can help us improve future automake versions. -END - if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then - echo 'Configuration will proceed anyway, since you have set the' >&2 - echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 - echo >&2 - else - cat >&2 <<'END' -Aborting the configuration process, to ensure you take notice of the issue. - -You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . - -If you want to complete the configuration process using your problematic -'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM -to "yes", and re-run configure. - -END - as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi - - -# Checks for programs. -DEPDIR="${am__leading_dot}deps" - -ac_config_commands="$ac_config_commands depfiles" - - -am_make=${MAKE-make} -cat > confinc << 'END' -am__doit: - @echo this is the am__doit target -.PHONY: am__doit -END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } -am__include="#" -am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf - -# Check whether --enable-dependency-tracking was given. -if test "${enable_dependency_tracking+set}" = set; then : - enableval=$enable_dependency_tracking; -fi - -if test "x$enable_dependency_tracking" != xno; then - am_depcomp="$ac_aux_dir/depcomp" - AMDEPBACKSLASH='\' - am__nodep='_no' -fi - if test "x$enable_dependency_tracking" != xno; then - AMDEP_TRUE= - AMDEP_FALSE='#' -else - AMDEP_TRUE='#' - AMDEP_FALSE= -fi - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if ${ac_cv_prog_CC+:} false; then : @@ -3078,14 +2455,19 @@ else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else + ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -3093,6 +2475,18 @@ done done IFS=$as_save_IFS +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi fi fi CC=$ac_cv_prog_CC @@ -3106,177 +2500,27 @@ fi fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl.exe + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : +if ${ac_cv_prog_CC+:} false; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else - ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3320,7 +2564,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -3766,7 +3010,8 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include -struct stat; +#include +#include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); @@ -3795,775 +3040,62 @@ static char *f (char * (*g) (char **, int), char **p, ...) that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } -if ${am_cv_prog_cc_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF - # Make sure it works both with $CC and with simple cc. - # Following AC_PROG_CC_C_O, we do the test twice because some - # compilers refuse to overwrite an existing .o file with -o, - # though they will create one. - am_cv_prog_cc_c_o=yes - for am_i in 1 2; do - if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 - ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } \ - && test -f conftest2.$ac_objext; then - : OK - else - am_cv_prog_cc_c_o=no - break - fi - done - rm -f core conftest* - unset am_i -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -$as_echo "$am_cv_prog_cc_c_o" >&6; } -if test "$am_cv_prog_cc_c_o" != yes; then - # Losing compiler, so override with the script. - # FIXME: It is wrong to rewrite CC. - # But if we don't then we get into trouble of one sort or another. - # A longer-term fix would be to have automake use am__CC in this case, - # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" - CC="$am_aux_dir/compile $CC" -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -depcc="$CC" am_compiler_list= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 -$as_echo_n "checking dependency style of $depcc... " >&6; } -if ${am_cv_CC_dependencies_compiler_type+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then - # We make a subdir and do the tests there. Otherwise we can end up - # making bogus files that we don't know about and never remove. For - # instance it was reported that on HP-UX the gcc test will end up - # making a dummy file named 'D' -- because '-MD' means "put the output - # in D". - rm -rf conftest.dir - mkdir conftest.dir - # Copy depcomp to subdir because otherwise we won't find it if we're - # using a relative directory. - cp "$am_depcomp" conftest.dir - cd conftest.dir - # We will build objects and dependencies in a subdirectory because - # it helps to detect inapplicable dependency modes. For instance - # both Tru64's cc and ICC support -MD to output dependencies as a - # side effect of compilation, but ICC will put the dependencies in - # the current directory while Tru64 will put them in the object - # directory. - mkdir sub - - am_cv_CC_dependencies_compiler_type=none - if test "$am_compiler_list" = ""; then - am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` - fi - am__universal=false - case " $depcc " in #( - *\ -arch\ *\ -arch\ *) am__universal=true ;; - esac - - for depmode in $am_compiler_list; do - # Setup a source with many dependencies, because some compilers - # like to wrap large dependency lists on column 80 (with \), and - # we should not choose a depcomp mode which is confused by this. - # - # We need to recreate these files for each test, as the compiler may - # overwrite some of them when testing with obscure command lines. - # This happens at least with the AIX C compiler. - : > sub/conftest.c - for i in 1 2 3 4 5 6; do - echo '#include "conftst'$i'.h"' >> sub/conftest.c - # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with - # Solaris 10 /bin/sh. - echo '/* dummy */' > sub/conftst$i.h - done - echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf - - # We check with '-c' and '-o' for the sake of the "dashmstdout" - # mode. It turns out that the SunPro C++ compiler does not properly - # handle '-M -o', and we need to detect this. Also, some Intel - # versions had trouble with output in subdirs. - am__obj=sub/conftest.${OBJEXT-o} - am__minus_obj="-o $am__obj" - case $depmode in - gcc) - # This depmode causes a compiler race in universal mode. - test "$am__universal" = false || continue - ;; - nosideeffect) - # After this tag, mechanisms are not by side-effect, so they'll - # only be used when explicitly requested. - if test "x$enable_dependency_tracking" = xyes; then - continue - else - break - fi - ;; - msvc7 | msvc7msys | msvisualcpp | msvcmsys) - # This compiler won't grok '-c -o', but also, the minuso test has - # not run yet. These depmodes are late enough in the game, and - # so weak that their functioning should not be impacted. - am__obj=conftest.${OBJEXT-o} - am__minus_obj= - ;; - none) break ;; - esac - if depmode=$depmode \ - source=sub/conftest.c object=$am__obj \ - depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ - $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ - >/dev/null 2>conftest.err && - grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && - grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && - grep $am__obj sub/conftest.Po > /dev/null 2>&1 && - ${MAKE-make} -s -f confmf > /dev/null 2>&1; then - # icc doesn't choke on unknown options, it will just issue warnings - # or remarks (even with -Werror). So we grep stderr for any message - # that says an option was ignored or not supported. - # When given -MP, icc 7.0 and 7.1 complain thusly: - # icc: Command line warning: ignoring option '-M'; no argument required - # The diagnosis changed in icc 8.0: - # icc: Command line remark: option '-MP' not supported - if (grep 'ignoring option' conftest.err || - grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else - am_cv_CC_dependencies_compiler_type=$depmode - break - fi - fi - done - - cd .. - rm -rf conftest.dir -else - am_cv_CC_dependencies_compiler_type=none -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 -$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } -CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type - - if - test "x$enable_dependency_tracking" != xno \ - && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then - am__fastdepCC_TRUE= - am__fastdepCC_FALSE='#' -else - am__fastdepCC_TRUE='#' - am__fastdepCC_FALSE= -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C99" >&5 -$as_echo_n "checking for $CC option to accept ISO C99... " >&6; } -if ${ac_cv_prog_cc_c99+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c99=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include -#include - -// Check varargs macros. These examples are taken from C99 6.10.3.5. -#define debug(...) fprintf (stderr, __VA_ARGS__) -#define showlist(...) puts (#__VA_ARGS__) -#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) -static void -test_varargs_macros (void) -{ - int x = 1234; - int y = 5678; - debug ("Flag"); - debug ("X = %d\n", x); - showlist (The first, second, and third items.); - report (x>y, "x is %d but y is %d", x, y); -} - -// Check long long types. -#define BIG64 18446744073709551615ull -#define BIG32 4294967295ul -#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) -#if !BIG_OK - your preprocessor is broken; -#endif -#if BIG_OK -#else - your preprocessor is broken; -#endif -static long long int bignum = -9223372036854775807LL; -static unsigned long long int ubignum = BIG64; - -struct incomplete_array -{ - int datasize; - double data[]; -}; - -struct named_init { - int number; - const wchar_t *name; - double average; -}; - -typedef const char *ccp; - -static inline int -test_restrict (ccp restrict text) -{ - // See if C++-style comments work. - // Iterate through items via the restricted pointer. - // Also check for declarations in for loops. - for (unsigned int i = 0; *(text+i) != '\0'; ++i) - continue; - return 0; -} - -// Check varargs and va_copy. -static void -test_varargs (const char *format, ...) -{ - va_list args; - va_start (args, format); - va_list args_copy; - va_copy (args_copy, args); - - const char *str; - int number; - float fnumber; - - while (*format) - { - switch (*format++) - { - case 's': // string - str = va_arg (args_copy, const char *); - break; - case 'd': // int - number = va_arg (args_copy, int); - break; - case 'f': // float - fnumber = va_arg (args_copy, double); - break; - default: - break; - } - } - va_end (args_copy); - va_end (args); -} - -int -main () -{ - - // Check bool. - _Bool success = false; - - // Check restrict. - if (test_restrict ("String literal") == 0) - success = true; - char *restrict newvar = "Another string"; - - // Check varargs. - test_varargs ("s, d' f .", "string", 65, 34.234); - test_varargs_macros (); - - // Check flexible array members. - struct incomplete_array *ia = - malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); - ia->datasize = 10; - for (int i = 0; i < ia->datasize; ++i) - ia->data[i] = i * 1.234; - - // Check named initializers. - struct named_init ni = { - .number = 34, - .name = L"Test wide string", - .average = 543.34343, - }; - - ni.number = 58; - - int dynamic_array[ni.number]; - dynamic_array[ni.number - 1] = 543; - - // work around unused variable warnings - return (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == 'x' - || dynamic_array[ni.number - 1] != 543); - - ; - return 0; -} -_ACEOF -for ac_arg in '' -std=gnu99 -std=c99 -c99 -AC99 -D_STDC_C99= -qlanglvl=extc99 -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c99=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c99" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c99" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c99" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 -$as_echo "$ac_cv_prog_cc_c99" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c99" != xno; then : - -fi - - - -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - -case "$host_os" in # XXX - Does this break cross-compiling? -openbsd*) - # According to gcc-local(1), OpenBSD's gcc is modified to ignore /usr/local - # by default. However, libgmp is usually installed to /usr/local, so we - # want to look there for the libraries. - CFLAGS="$CFLAGS -I/usr/local/include" - LDFLAGS="$LDFLAGS -L/usr/local/lib" - ;; -*) - ;; -esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wall" >&5 -$as_echo_n "checking whether C compiler accepts -Wall... " >&6; } -if ${ax_cv_check_cflags___Wall+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CFLAGS - CFLAGS="$CFLAGS -Wall" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ax_cv_check_cflags___Wall=yes -else - ax_cv_check_cflags___Wall=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wall" >&5 -$as_echo "$ax_cv_check_cflags___Wall" >&6; } -if test x"$ax_cv_check_cflags___Wall" = xyes; then : - if ${CFLAGS+:} false; then : - case " $CFLAGS " in - *" -Wall "*) - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains -Wall"; } >&5 - (: CFLAGS already contains -Wall) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - ;; - *) - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS -Wall\""; } >&5 - (: CFLAGS="$CFLAGS -Wall") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - CFLAGS="$CFLAGS -Wall" - ;; - esac -else - CFLAGS="-Wall" -fi - -else - : -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wextra" >&5 -$as_echo_n "checking whether C compiler accepts -Wextra... " >&6; } -if ${ax_cv_check_cflags___Wextra+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CFLAGS - CFLAGS="$CFLAGS -Wextra" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ax_cv_check_cflags___Wextra=yes -else - ax_cv_check_cflags___Wextra=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wextra" >&5 -$as_echo "$ax_cv_check_cflags___Wextra" >&6; } -if test x"$ax_cv_check_cflags___Wextra" = xyes; then : - if ${CFLAGS+:} false; then : - case " $CFLAGS " in - *" -Wextra "*) - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains -Wextra"; } >&5 - (: CFLAGS already contains -Wextra) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - ;; - *) - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS -Wextra\""; } >&5 - (: CFLAGS="$CFLAGS -Wextra") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - CFLAGS="$CFLAGS -Wextra" - ;; - esac -else - CFLAGS="-Wextra" -fi - -else - : -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wno-missing-field-initializers" >&5 -$as_echo_n "checking whether C compiler accepts -Wno-missing-field-initializers... " >&6; } -if ${ax_cv_check_cflags___Wno_missing_field_initializers+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CFLAGS - CFLAGS="$CFLAGS -Wno-missing-field-initializers" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ax_cv_check_cflags___Wno_missing_field_initializers=yes -else - ax_cv_check_cflags___Wno_missing_field_initializers=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wno_missing_field_initializers" >&5 -$as_echo "$ax_cv_check_cflags___Wno_missing_field_initializers" >&6; } -if test x"$ax_cv_check_cflags___Wno_missing_field_initializers" = xyes; then : - if ${CFLAGS+:} false; then : - case " $CFLAGS " in - *" -Wno-missing-field-initializers "*) - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains -Wno-missing-field-initializers"; } >&5 - (: CFLAGS already contains -Wno-missing-field-initializers) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - ;; - *) - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS -Wno-missing-field-initializers\""; } >&5 - (: CFLAGS="$CFLAGS -Wno-missing-field-initializers") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - CFLAGS="$CFLAGS -Wno-missing-field-initializers" - ;; - esac -else - CFLAGS="-Wno-missing-field-initializers" -fi - -else - : -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -Wno-unused-parameter" >&5 -$as_echo_n "checking whether C compiler accepts -Wno-unused-parameter... " >&6; } -if ${ax_cv_check_cflags___Wno_unused_parameter+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CFLAGS - CFLAGS="$CFLAGS -Wno-unused-parameter" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ax_cv_check_cflags___Wno_unused_parameter=yes -else - ax_cv_check_cflags___Wno_unused_parameter=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$ax_check_save_flags -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___Wno_unused_parameter" >&5 -$as_echo "$ax_cv_check_cflags___Wno_unused_parameter" >&6; } -if test x"$ax_cv_check_cflags___Wno_unused_parameter" = xyes; then : - if ${CFLAGS+:} false; then : - case " $CFLAGS " in - *" -Wno-unused-parameter "*) - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS already contains -Wno-unused-parameter"; } >&5 - (: CFLAGS already contains -Wno-unused-parameter) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - ;; - *) - { { $as_echo "$as_me:${as_lineno-$LINENO}: : CFLAGS=\"\$CFLAGS -Wno-unused-parameter\""; } >&5 - (: CFLAGS="$CFLAGS -Wno-unused-parameter") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - CFLAGS="$CFLAGS -Wno-unused-parameter" - ;; - esac -else - CFLAGS="-Wno-unused-parameter" -fi - -else - : -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether C compiler accepts -maes" >&5 -$as_echo_n "checking whether C compiler accepts -maes... " >&6; } -if ${ax_cv_check_cflags___maes+:} false; then : - $as_echo_n "(cached) " >&6 -else - - ax_check_save_flags=$CFLAGS - CFLAGS="$CFLAGS -maes" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - +/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters + inside strings and character constants. */ +#define FOO(x) 'x' +int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; int main () { - +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ax_cv_check_cflags___maes=yes -else - ax_cv_check_cflags___maes=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - CFLAGS=$ax_check_save_flags +for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ + -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + if ac_fn_c_try_compile "$LINENO"; then : + ac_cv_prog_cc_c89=$ac_arg fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_check_cflags___maes" >&5 -$as_echo "$ax_cv_check_cflags___maes" >&6; } -if test x"$ax_cv_check_cflags___maes" = xyes; then : - - have_maes=yes - -$as_echo "#define HAVE_MAES 1" >>confdefs.h +rm -f core conftest.err conftest.$ac_objext + test "x$ac_cv_prog_cc_c89" != "xno" && break +done +rm -f conftest.$ac_ext +CC=$ac_save_CC +fi +# AC_CACHE_VAL +case "x$ac_cv_prog_cc_c89" in + x) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; + xno) + { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; + *) + CC="$CC $ac_cv_prog_cc_c89" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; +esac +if test "x$ac_cv_prog_cc_c89" != xno; then : -else - : fi +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + # Checks for libraries. @@ -4572,6 +3104,7 @@ if test "${with_gmp+set}" = set; then : withval=$with_gmp; fi + if test "x$with_gmp" != "xno"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __gmpz_init in -lgmp" >&5 @@ -4870,7 +3403,7 @@ do for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -4936,7 +3469,7 @@ do for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -5113,7 +3646,7 @@ fi done -for ac_header in inttypes.h sys/inttypes.h cpuid.h limits.h stddef.h stdint.h stdlib.h string.h wchar.h +for ac_header in inttypes.h limits.h stddef.h stdint.h stdlib.h string.h wchar.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" @@ -5126,25 +3659,6 @@ fi done -old_CPPFLAGS="$CPPFLAGS" -if test "x$have_maes" = "xyes"; then : - - CPPFLAGS="$CPPFLAGS -maes" - -fi -for ac_header in wmmintrin.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "wmmintrin.h" "ac_cv_header_wmmintrin_h" "$ac_includes_default" -if test "x$ac_cv_header_wmmintrin_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_WMMINTRIN_H 1 -_ACEOF - -fi - -done - -CPPFLAGS="$old_CPPFLAGS" # Checks for typedefs, structures, and compiler characteristics. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5 @@ -5299,43 +3813,6 @@ _ACEOF esac - ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" -if test "x$ac_cv_type_uintptr_t" = xyes; then : - -$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h - -else - for ac_type in 'unsigned int' 'unsigned long int' \ - 'unsigned long long int'; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$ac_includes_default -int -main () -{ -static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))]; -test_array [0] = 0; -return test_array [0]; - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -cat >>confdefs.h <<_ACEOF -#define uintptr_t $ac_type -_ACEOF - - ac_type= -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - test -z "$ac_type" && break - done -fi - - - # Checks for library functions. for ac_header in stdlib.h do : @@ -5416,18 +3893,6 @@ _ACEOF fi done -for ac_func in posix_memalign aligned_alloc _aligned_malloc -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -5538,30 +4003,6 @@ LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 -$as_echo_n "checking that generated files are newer than configure... " >&6; } - if test -n "$am_sleep_pid"; then - # Hide warnings about reused PIDs. - wait $am_sleep_pid 2>/dev/null - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5 -$as_echo "done" >&6; } - if test -n "$EXEEXT"; then - am__EXEEXT_TRUE= - am__EXEEXT_FALSE='#' -else - am__EXEEXT_TRUE='#' - am__EXEEXT_FALSE= -fi - -if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then - as_fn_error $? "conditional \"AMDEP\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi -if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then - as_fn_error $? "conditional \"am__fastdepCC\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 @@ -5860,16 +4301,16 @@ if (echo >conf$$.file) 2>/dev/null; then # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. + # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' + as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else - as_ln_s='cp -pR' + as_ln_s='cp -p' fi else - as_ln_s='cp -pR' + as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null @@ -5929,16 +4370,28 @@ else as_mkdir_p=false fi - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in #( + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -5960,7 +4413,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # values after options handling. ac_log=" This file was extended by FULL-PACKAGE-NAME $as_me VERSION, which was -generated by GNU Autoconf 2.69. Invocation command line was +generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -5973,9 +4426,6 @@ on `(hostname || uname -n) 2>/dev/null | sed 1q` _ACEOF -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; @@ -5984,9 +4434,7 @@ esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. -config_files="$ac_config_files" config_headers="$ac_config_headers" -config_commands="$ac_config_commands" _ACEOF @@ -6005,20 +4453,12 @@ Usage: $0 [OPTION]... [TAG]... do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE -Configuration files: -$config_files - Configuration headers: $config_headers -Configuration commands: -$config_commands - Report bugs to ." _ACEOF @@ -6026,18 +4466,15 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ FULL-PACKAGE-NAME config.status VERSION -configured by $0, generated by GNU Autoconf 2.69, +configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" -Copyright (C) 2012 Free Software Foundation, Inc. +Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' -INSTALL='$INSTALL' -MKDIR_P='$MKDIR_P' -AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF @@ -6074,14 +4511,6 @@ do $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in @@ -6120,7 +4549,7 @@ fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' @@ -6141,11 +4570,6 @@ _ASBOX _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" - _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 @@ -6155,8 +4579,6 @@ for ac_config_target in $ac_config_targets do case $ac_config_target in "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; - "buildenv") CONFIG_FILES="$CONFIG_FILES buildenv" ;; - "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac @@ -6168,9 +4590,7 @@ done # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree @@ -6200,164 +4620,6 @@ $debug || } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. @@ -6467,7 +4729,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_HEADERS" -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" +eval set X " :H $CONFIG_HEADERS " shift for ac_tag do @@ -6596,96 +4858,7 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac - ac_MKDIR_P=$MKDIR_P - case $MKDIR_P in - [\\/$]* | ?:[\\/]* ) ;; - */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -s&@MKDIR_P@&$ac_MKDIR_P&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; :H) # # CONFIG_HEADER @@ -6709,144 +4882,11 @@ $as_echo "$as_me: $ac_file is unchanged" >&6;} && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi -# Compute "$ac_file"'s index in $config_headers. -_am_arg="$ac_file" -_am_stamp_count=1 -for _am_header in $config_headers :; do - case $_am_header in - $_am_arg | $_am_arg:* ) - break ;; - * ) - _am_stamp_count=`expr $_am_stamp_count + 1` ;; - esac -done -echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || -$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$_am_arg" : 'X\(//\)[^/]' \| \ - X"$_am_arg" : 'X\(//\)$' \| \ - X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$_am_arg" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'`/stamp-h$_am_stamp_count - ;; - - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} ;; - esac - case $ac_file$ac_mode in - "depfiles":C) test x"$AMDEP_TRUE" != x"" || { - # Older Autoconf quotes --file arguments for eval, but not when files - # are listed without --file. Let's play safe and only enable the eval - # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; esac - shift - for mf - do - # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line - # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done - done -} - ;; - esac done # for ac_tag diff --git a/configure.ac b/configure.ac index 3bba18d3..b45655d4 100644 --- a/configure.ac +++ b/configure.ac @@ -1,57 +1,13 @@ # -*- Autoconf -*- -# PyCrypto's configure.ac file. # Process this file with autoconf to produce a configure script. -# -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. AC_PREREQ([2.67]) AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS]) AC_CONFIG_SRCDIR([src/pycrypto_compat.h]) AC_CONFIG_HEADERS([src/config.h]) -AC_CONFIG_AUX_DIR([build-aux]) -AC_CONFIG_MACRO_DIR([m4]) -AC_CONFIG_FILES([buildenv]) - -AM_INIT_AUTOMAKE([foreign no-define no-dist]) # Checks for programs. -AC_PROG_CC_C99 - -AC_CANONICAL_HOST() -case "$host_os" in # XXX - Does this break cross-compiling? -openbsd*) - # According to gcc-local(1), OpenBSD's gcc is modified to ignore /usr/local - # by default. However, libgmp is usually installed to /usr/local, so we - # want to look there for the libraries. - CFLAGS="$CFLAGS -I/usr/local/include" - LDFLAGS="$LDFLAGS -L/usr/local/lib" - ;; -*) - ;; -esac - -AX_CHECK_COMPILE_FLAG([-Wall], [AX_APPEND_FLAG([-Wall])]) -AX_CHECK_COMPILE_FLAG([-Wextra], [AX_APPEND_FLAG([-Wextra])]) -AX_CHECK_COMPILE_FLAG([-Wno-missing-field-initializers], [AX_APPEND_FLAG([-Wno-missing-field-initializers])]) -AX_CHECK_COMPILE_FLAG([-Wno-unused-parameter], [AX_APPEND_FLAG([-Wno-unused-parameter])]) -AX_CHECK_COMPILE_FLAG([-maes], [ - have_maes=yes - AC_DEFINE(HAVE_MAES, [1], [Define if CC supports -maes]) -]) +AC_PROG_CC # Checks for libraries. AC_ARG_WITH([gmp], AS_HELP_STRING([--without-gmp], [Build without gmp library (default: test)])) @@ -80,13 +36,7 @@ AC_CHECK_DECLS([mpz_powm_sec], [], [], [ ]]) # Checks for header files. -AC_CHECK_HEADERS([inttypes.h sys/inttypes.h cpuid.h limits.h stddef.h stdint.h stdlib.h string.h wchar.h]) -old_CPPFLAGS="$CPPFLAGS" -AS_IF([test "x$have_maes" = "xyes"], [ - CPPFLAGS="$CPPFLAGS -maes" -]) -AC_CHECK_HEADERS([wmmintrin.h]) -CPPFLAGS="$old_CPPFLAGS" +AC_CHECK_HEADERS([inttypes.h limits.h stddef.h stdint.h stdlib.h string.h wchar.h]) # Checks for typedefs, structures, and compiler characteristics. AC_C_INLINE @@ -99,11 +49,9 @@ AC_TYPE_UINT16_T AC_TYPE_UINT32_T AC_TYPE_UINT64_T AC_TYPE_UINT8_T -AC_TYPE_UINTPTR_T # Checks for library functions. AC_FUNC_MALLOC AC_CHECK_FUNCS([memmove memset]) -AC_CHECK_FUNCS([posix_memalign aligned_alloc _aligned_malloc]) AC_OUTPUT diff --git a/lib/Crypto/Cipher/AES.py b/lib/Crypto/Cipher/AES.py index c484846a..14f68d8c 100644 --- a/lib/Crypto/Cipher/AES.py +++ b/lib/Crypto/Cipher/AES.py @@ -31,88 +31,32 @@ As an example, encryption can be done as follows: >>> from Crypto.Cipher import AES - >>> from Crypto.Random import get_random_bytes + >>> from Crypto import Random >>> >>> key = b'Sixteen byte key' - >>> iv = get_random_bytes(16) + >>> iv = Random.new().read(AES.block_size) >>> cipher = AES.new(key, AES.MODE_CFB, iv) >>> msg = iv + cipher.encrypt(b'Attack at dawn') -A more complicated example is based on CCM, (see `MODE_CCM`) an `AEAD`_ mode -that provides both confidentiality and authentication for a message. - -It optionally allows the header of the message to remain in the clear, whilst still -being authenticated. The encryption is done as follows: - - >>> from Crypto.Cipher import AES - >>> from Crypto.Random import get_random_bytes - >>> - >>> - >>> hdr = b'To your eyes only' - >>> plaintext = b'Attack at dawn' - >>> key = b'Sixteen byte key' - >>> nonce = get_random_bytes(11) - >>> cipher = AES.new(key, AES.MODE_CCM, nonce) - >>> cipher.update(hdr) - >>> msg = nonce, hdr, cipher.encrypt(plaintext), cipher.digest() - -We assume that the tuple ``msg`` is transmitted to the receiver: - - >>> nonce, hdr, ciphertext, mac = msg - >>> key = b'Sixteen byte key' - >>> cipher = AES.new(key, AES.MODE_CCM, nonce) - >>> cipher.update(hdr) - >>> plaintext = cipher.decrypt(ciphertext) - >>> try: - >>> cipher.verify(mac) - >>> print "The message is authentic: hdr=%s, pt=%s" % (hdr, plaintext) - >>> except ValueError: - >>> print "Key incorrect or message corrupted" - .. __: http://en.wikipedia.org/wiki/Advanced_Encryption_Standard .. _NIST: http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf -.. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html :undocumented: __revision__, __package__ """ __revision__ = "$Id$" -import sys -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * from Crypto.Cipher import blockalgo from Crypto.Cipher import _AES -from Crypto.Util import cpuid -# Import _AESNI. If AES-NI is not available or _AESNI has not been built, set -# _AESNI to None. -try: - if cpuid.have_aes_ni(): - from Crypto.Cipher import _AESNI - else: - _AESNI = None -except ImportError: - _AESNI = None class AESCipher (blockalgo.BlockAlgo): """AES cipher object""" def __init__(self, key, *args, **kwargs): """Initialize an AES cipher object - + See also `new()` at the module level.""" - - # Check if the use_aesni was specified. - use_aesni = True - if kwargs.has_key('use_aesni'): - use_aesni = kwargs['use_aesni'] - del kwargs['use_aesni'] - - # Use _AESNI if the user requested AES-NI and it's available - if _AESNI is not None and use_aesni: - blockalgo.BlockAlgo.__init__(self, _AESNI, key, *args, **kwargs) - else: - blockalgo.BlockAlgo.__init__(self, _AES, key, *args, **kwargs) + blockalgo.BlockAlgo.__init__(self, _AES, key, *args, **kwargs) def new(key, *args, **kwargs): """Create a new AES cipher @@ -121,37 +65,22 @@ def new(key, *args, **kwargs): key : byte string The secret key to use in the symmetric cipher. It must be 16 (*AES-128*), 24 (*AES-192*), or 32 (*AES-256*) bytes long. - - Only in `MODE_SIV`, it needs to be 32, 48, or 64 bytes long. :Keywords: mode : a *MODE_** constant The chaining mode to use for encryption or decryption. Default is `MODE_ECB`. IV : byte string - (*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`). - The initialization vector to use for encryption or decryption. - + It is ignored for `MODE_ECB` and `MODE_CTR`. For `MODE_OPENPGP`, IV must be `block_size` bytes long for encryption and `block_size` +2 bytes for decryption (in the latter case, it is actually the *encrypted* IV which was prefixed to the ciphertext). It is mandatory. - - For all other modes, it must be 16 bytes long. - nonce : byte string - (*Only* `MODE_CCM`, `MODE_EAX`, `MODE_GCM`, `MODE_SIV`). - - A mandatory value that must never be reused for any other encryption. - - For `MODE_CCM`, its length must be in the range ``[7..13]``. - 11 or 12 bytes are reasonable values in general. Bear in - mind that with CCM there is a trade-off between nonce length and - maximum message size. - - For the other modes, there are no restrictions on its length, - but it is recommended to use at least 16 bytes. + + For all other modes, it must be `block_size` bytes longs. It is optional and + when not present it will be given a default value of all zeroes. counter : callable (*Only* `MODE_CTR`). A stateful function that returns the next *counter block*, which is a byte string of `block_size` bytes. @@ -160,20 +89,6 @@ def new(key, *args, **kwargs): (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext are segmented in. It must be a multiple of 8. If 0 or not specified, it will be assumed to be 8. - mac_len : integer - (*Only* `MODE_CCM`). Length of the MAC, in bytes. It must be even and in - the range ``[4..16]``. The default is 16. - - (*Only* `MODE_EAX` and `MODE_GCM`). Length of the MAC, in bytes. It must be no - larger than 16 bytes (which is the default). - msg_len : integer - (*Only* `MODE_CCM`). Length of the message to (de)cipher. - If not specified, ``encrypt`` or ``decrypt`` may only be called once. - assoc_len : integer - (*Only* `MODE_CCM`). Length of the associated data. - If not specified, all data is internally buffered. - use_aesni : boolean - Use AES-NI if available. :Return: an `AESCipher` object """ @@ -193,14 +108,6 @@ def new(key, *args, **kwargs): MODE_CTR = 6 #: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`. MODE_OPENPGP = 7 -#: Counter with CBC-MAC (CCM) Mode. See `blockalgo.MODE_CCM`. -MODE_CCM = 8 -#: EAX Mode. See `blockalgo.MODE_EAX`. -MODE_EAX = 9 -#: Syntethic Initialization Vector (SIV). See `blockalgo.MODE_SIV`. -MODE_SIV = 10 -#: Galois Counter Mode (GCM). See `blockalgo.MODE_GCM`. -MODE_GCM = 11 #: Size of a data block (in bytes) block_size = 16 #: Size of a key (in bytes) diff --git a/lib/Crypto/Cipher/ARC2.py b/lib/Crypto/Cipher/ARC2.py index 1b3fa4e1..7b5f43aa 100644 --- a/lib/Crypto/Cipher/ARC2.py +++ b/lib/Crypto/Cipher/ARC2.py @@ -32,7 +32,7 @@ RC2 has a fixed data block size of 8 bytes. Length of its keys can vary from 8 to 128 bits. One particular property of RC2 is that the actual -cryptographic strength of the key (*effective key length*) can be reduced +cryptographic strength of the key (*effective key length*) can be reduced via a parameter. Even though RC2 is not cryptographically broken, it has not been analyzed as @@ -66,7 +66,7 @@ class RC2Cipher (blockalgo.BlockAlgo): def __init__(self, key, *args, **kwargs): """Initialize an ARC2 cipher object - + See also `new()` at the module level.""" blockalgo.BlockAlgo.__init__(self, _ARC2, key, *args, **kwargs) @@ -82,8 +82,6 @@ def new(key, *args, **kwargs): The chaining mode to use for encryption or decryption. Default is `MODE_ECB`. IV : byte string - (*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`). - The initialization vector to use for encryption or decryption. It is ignored for `MODE_ECB` and `MODE_CTR`. @@ -92,20 +90,13 @@ def new(key, *args, **kwargs): and `block_size` +2 bytes for decryption (in the latter case, it is actually the *encrypted* IV which was prefixed to the ciphertext). It is mandatory. - - For all other modes, it must be 8 bytes long. - nonce : byte string - (*Only* `MODE_EAX`). - A mandatory value that must never be reused for any other encryption. - There are no restrictions on its length, but it is recommended to - use at least 16 bytes. + + For all other modes, it must be `block_size` bytes longs. It is optional and + when not present it will be given a default value of all zeroes. counter : callable (*Only* `MODE_CTR`). A stateful function that returns the next *counter block*, which is a byte string of `block_size` bytes. For better performance, use `Crypto.Util.Counter`. - mac_len : integer - (*Only* `MODE_EAX`). Length of the MAC, in bytes. - It must be no larger than 8 (which is the default). segment_size : integer (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext are segmented in. @@ -132,8 +123,6 @@ def new(key, *args, **kwargs): MODE_CTR = 6 #: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`. MODE_OPENPGP = 7 -#: EAX Mode. See `blockalgo.MODE_EAX`. -MODE_EAX = 9 #: Size of a data block (in bytes) block_size = 8 #: Size of a key (in bytes) diff --git a/lib/Crypto/Cipher/ARC4.py b/lib/Crypto/Cipher/ARC4.py index 48d39f1c..b745e7ce 100644 --- a/lib/Crypto/Cipher/ARC4.py +++ b/lib/Crypto/Cipher/ARC4.py @@ -63,7 +63,6 @@ __revision__ = "$Id$" -from Crypto.Util.py3compat import * from Crypto.Cipher import _ARC4 class ARC4Cipher: @@ -75,18 +74,7 @@ def __init__(self, key, *args, **kwargs): See also `new()` at the module level.""" - if len(args)>0: - ndrop = args[0] - args = args[1:] - else: - ndrop = kwargs.get('drop', 0) - if ndrop: del kwargs['drop'] self._cipher = _ARC4.new(key, *args, **kwargs) - if ndrop: - # This is OK even if the cipher is used for decryption, since encrypt - # and decrypt are actually the same thing with ARC4. - self._cipher.encrypt(b('\x00')*ndrop) - self.block_size = self._cipher.block_size self.key_size = self._cipher.key_size @@ -120,17 +108,8 @@ def new(key, *args, **kwargs): The secret key to use in the symmetric cipher. It can have any length, with a minimum of 40 bytes. Its cryptograpic strength is always capped to 2048 bits (256 bytes). - :Keywords: - drop : integer - The amount of bytes to discard from the initial part of the keystream. - In fact, such part has been found to be distinguishable from random - data (while it shouldn't) and also correlated to key. - - The recommended value is 3072_ bytes. The default value is 0. :Return: an `ARC4Cipher` object - - .. _3072: http://eprint.iacr.org/2002/067.pdf """ return ARC4Cipher(key, *args, **kwargs) diff --git a/lib/Crypto/Cipher/Blowfish.py b/lib/Crypto/Cipher/Blowfish.py index 92fad7fe..3f12bea2 100644 --- a/lib/Crypto/Cipher/Blowfish.py +++ b/lib/Crypto/Cipher/Blowfish.py @@ -60,7 +60,7 @@ class BlowfishCipher (blockalgo.BlockAlgo): def __init__(self, key, *args, **kwargs): """Initialize a Blowfish cipher object - + See also `new()` at the module level.""" blockalgo.BlockAlgo.__init__(self, _Blowfish, key, *args, **kwargs) @@ -76,8 +76,6 @@ def new(key, *args, **kwargs): The chaining mode to use for encryption or decryption. Default is `MODE_ECB`. IV : byte string - (*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`). - The initialization vector to use for encryption or decryption. It is ignored for `MODE_ECB` and `MODE_CTR`. @@ -86,20 +84,13 @@ def new(key, *args, **kwargs): and `block_size` +2 bytes for decryption (in the latter case, it is actually the *encrypted* IV which was prefixed to the ciphertext). It is mandatory. - - For all other modes, it must be 8 bytes long. - nonce : byte string - (*Only* `MODE_EAX`). - A mandatory value that must never be reused for any other encryption. - There are no restrictions on its length, but it is recommended to - use at least 16 bytes. + + For all other modes, it must be `block_size` bytes longs. It is optional and + when not present it will be given a default value of all zeroes. counter : callable (*Only* `MODE_CTR`). A stateful function that returns the next *counter block*, which is a byte string of `block_size` bytes. For better performance, use `Crypto.Util.Counter`. - mac_len : integer - (*Only* `MODE_EAX`). Length of the MAC, in bytes. - It must be no larger than 8 (which is the default). segment_size : integer (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext are segmented in. @@ -123,8 +114,6 @@ def new(key, *args, **kwargs): MODE_CTR = 6 #: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`. MODE_OPENPGP = 7 -#: EAX Mode. See `blockalgo.MODE_EAX`. -MODE_EAX = 9 #: Size of a data block (in bytes) block_size = 8 #: Size of a key (in bytes) diff --git a/lib/Crypto/Cipher/CAST.py b/lib/Crypto/Cipher/CAST.py index 6e136a39..f08dab3e 100644 --- a/lib/Crypto/Cipher/CAST.py +++ b/lib/Crypto/Cipher/CAST.py @@ -63,7 +63,7 @@ class CAST128Cipher(blockalgo.BlockAlgo): def __init__(self, key, *args, **kwargs): """Initialize a CAST-128 cipher object - + See also `new()` at the module level.""" blockalgo.BlockAlgo.__init__(self, _CAST, key, *args, **kwargs) @@ -79,8 +79,6 @@ def new(key, *args, **kwargs): The chaining mode to use for encryption or decryption. Default is `MODE_ECB`. IV : byte string - (*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`). - The initialization vector to use for encryption or decryption. It is ignored for `MODE_ECB` and `MODE_CTR`. @@ -89,20 +87,13 @@ def new(key, *args, **kwargs): and `block_size` +2 bytes for decryption (in the latter case, it is actually the *encrypted* IV which was prefixed to the ciphertext). It is mandatory. - - For all other modes, it must be 8 bytes long. - nonce : byte string - (*Only* `MODE_EAX`). - A mandatory value that must never be reused for any other encryption. - There are no restrictions on its length, but it is recommended to - use at least 16 bytes. + + For all other modes, it must be `block_size` bytes longs. It is optional and + when not present it will be given a default value of all zeroes. counter : callable (*Only* `MODE_CTR`). A stateful function that returns the next *counter block*, which is a byte string of `block_size` bytes. For better performance, use `Crypto.Util.Counter`. - mac_len : integer - (*Only* `MODE_EAX`). Length of the MAC, in bytes. - It must be no larger than 8 (which is the default). segment_size : integer (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext are segmented in. @@ -126,8 +117,6 @@ def new(key, *args, **kwargs): MODE_CTR = 6 #: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`. MODE_OPENPGP = 7 -#: EAX Mode. See `blockalgo.MODE_EAX`. -MODE_EAX = 9 #: Size of a data block (in bytes) block_size = 8 #: Size of a key (in bytes) diff --git a/lib/Crypto/Cipher/DES.py b/lib/Crypto/Cipher/DES.py index 18a7bd13..2fae42fd 100644 --- a/lib/Crypto/Cipher/DES.py +++ b/lib/Crypto/Cipher/DES.py @@ -33,12 +33,12 @@ As an example, encryption can be done as follows: - >>> from Crypto.Cipher import DES + >>> from Crypto.Cipher import DES3 >>> from Crypto import Random >>> - >>> key = b'-8B key-' - >>> iv = Random.new().read(DES.block_size) - >>> cipher = DES.new(key, DES.MODE_OFB, iv) + >>> key = b'Sixteen byte key' + >>> iv = Random.new().read(DES3.block_size) + >>> cipher = DES3.new(key, DES3.MODE_OFB, iv) >>> plaintext = b'sona si latine loqueris ' >>> msg = iv + cipher.encrypt(plaintext) @@ -58,7 +58,7 @@ class DESCipher(blockalgo.BlockAlgo): def __init__(self, key, *args, **kwargs): """Initialize a DES cipher object - + See also `new()` at the module level.""" blockalgo.BlockAlgo.__init__(self, _DES, key, *args, **kwargs) @@ -74,8 +74,6 @@ def new(key, *args, **kwargs): The chaining mode to use for encryption or decryption. Default is `MODE_ECB`. IV : byte string - (*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`). - The initialization vector to use for encryption or decryption. It is ignored for `MODE_ECB` and `MODE_CTR`. @@ -84,20 +82,13 @@ def new(key, *args, **kwargs): and `block_size` +2 bytes for decryption (in the latter case, it is actually the *encrypted* IV which was prefixed to the ciphertext). It is mandatory. - - For all other modes, it must be 8 bytes long. - nonce : byte string - (*Only* `MODE_EAX`). - A mandatory value that must never be reused for any other encryption. - There are no restrictions on its length, but it is recommended to - use at least 16 bytes. + + For all other modes, it must be `block_size` bytes longs. It is optional and + when not present it will be given a default value of all zeroes. counter : callable (*Only* `MODE_CTR`). A stateful function that returns the next *counter block*, which is a byte string of `block_size` bytes. For better performance, use `Crypto.Util.Counter`. - mac_len : integer - (*Only* `MODE_EAX`). Length of the MAC, in bytes. - It must be no larger than 8 (which is the default). segment_size : integer (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext are segmented in. @@ -121,8 +112,6 @@ def new(key, *args, **kwargs): MODE_CTR = 6 #: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`. MODE_OPENPGP = 7 -#: EAX Mode. See `blockalgo.MODE_EAX`. -MODE_EAX = 9 #: Size of a data block (in bytes) block_size = 8 #: Size of a key (in bytes) diff --git a/lib/Crypto/Cipher/DES3.py b/lib/Crypto/Cipher/DES3.py index eae2dcc5..7fedac84 100644 --- a/lib/Crypto/Cipher/DES3.py +++ b/lib/Crypto/Cipher/DES3.py @@ -44,14 +44,14 @@ As an example, encryption can be done as follows: - >>> from Crypto.Cipher import DES3 + >>> from Crypto.Cipher import DES >>> from Crypto import Random >>> from Crypto.Util import Counter >>> - >>> key = b'Sixteen byte key' - >>> nonce = Random.new().read(DES3.block_size/2) - >>> ctr = Counter.new(DES3.block_size*8/2, prefix=nonce) - >>> cipher = DES3.new(key, DES3.MODE_CTR, counter=ctr) + >>> key = b'-8B key-' + >>> nonce = Random.new().read(DES.block_size/2) + >>> ctr = Counter.new(DES.block_size*8/2, prefix=nonce) + >>> cipher = DES.new(key, DES.MODE_CTR, counter=ctr) >>> plaintext = b'We are no longer the knights who say ni!' >>> msg = nonce + cipher.encrypt(plaintext) @@ -71,7 +71,7 @@ class DES3Cipher(blockalgo.BlockAlgo): def __init__(self, key, *args, **kwargs): """Initialize a TDES cipher object - + See also `new()` at the module level.""" blockalgo.BlockAlgo.__init__(self, _DES3, key, *args, **kwargs) @@ -87,8 +87,6 @@ def new(key, *args, **kwargs): The chaining mode to use for encryption or decryption. Default is `MODE_ECB`. IV : byte string - (*Only* `MODE_CBC`, `MODE_CFB`, `MODE_OFB`, `MODE_OPENPGP`). - The initialization vector to use for encryption or decryption. It is ignored for `MODE_ECB` and `MODE_CTR`. @@ -97,20 +95,13 @@ def new(key, *args, **kwargs): and `block_size` +2 bytes for decryption (in the latter case, it is actually the *encrypted* IV which was prefixed to the ciphertext). It is mandatory. - - For all other modes, it must be 8 bytes long. - nonce : byte string - (*Only* `MODE_EAX`). - A mandatory value that must never be reused for any other encryption. - There are no restrictions on its length, but it is recommended to - use at least 16 bytes. + + For all other modes, it must be `block_size` bytes longs. It is optional and + when not present it will be given a default value of all zeroes. counter : callable (*Only* `MODE_CTR`). A stateful function that returns the next - *counter block*, which is a byte string of 8 bytes. + *counter block*, which is a byte string of `block_size` bytes. For better performance, use `Crypto.Util.Counter`. - mac_len : integer - (*Only* `MODE_EAX`). Length of the MAC, in bytes. - It must be no larger than 8 (which is the default). segment_size : integer (*Only* `MODE_CFB`).The number of bits the plaintext and ciphertext are segmented in. @@ -136,8 +127,6 @@ def new(key, *args, **kwargs): MODE_CTR = 6 #: OpenPGP Mode. See `blockalgo.MODE_OPENPGP`. MODE_OPENPGP = 7 -#: EAX Mode. See `blockalgo.MODE_EAX`. -MODE_EAX = 9 #: Size of a data block (in bytes) block_size = 8 #: Size of a key (in bytes) diff --git a/lib/Crypto/Cipher/PKCS1_OAEP.py b/lib/Crypto/Cipher/PKCS1_OAEP.py index ff457190..9afe176f 100644 --- a/lib/Crypto/Cipher/PKCS1_OAEP.py +++ b/lib/Crypto/Cipher/PKCS1_OAEP.py @@ -31,7 +31,7 @@ >>> from Crypto.Cipher import PKCS1_OAEP >>> from Crypto.PublicKey import RSA >>> - >>> message = b'To be encrypted' + >>> message = 'To be encrypted' >>> key = RSA.importKey(open('pubkey.der').read()) >>> cipher = PKCS1_OAEP.new(key) >>> ciphertext = cipher.encrypt(message) @@ -55,7 +55,7 @@ __all__ = [ 'new', 'PKCS1OAEP_Cipher' ] import Crypto.Signature.PKCS1_PSS -import Crypto.Hash.SHA1 +import Crypto.Hash.SHA from Crypto.Util.py3compat import * import Crypto.Util.number @@ -70,17 +70,17 @@ def __init__(self, key, hashAlgo, mgfunc, label): :Parameters: key : an RSA key object - If a private half is given, both encryption and decryption are possible. - If a public half is given, only encryption is possible. + If a private half is given, both encryption and decryption are possible. + If a public half is given, only encryption is possible. hashAlgo : hash object The hash function to use. This can be a module under `Crypto.Hash` or an existing hash object created from any of such modules. If not specified, - `Crypto.Hash.SHA1` is used. + `Crypto.Hash.SHA` (that is, SHA-1) is used. mgfunc : callable A mask generation function that accepts two parameters: a string to use as seed, and the lenth of the mask to generate, in bytes. If not specified, the standard MGF1 is used (a safe choice). - label : byte string + label : string A label to apply to this particular encryption. If not specified, an empty string is used. Specifying a label does not improve security. @@ -93,7 +93,7 @@ def __init__(self, key, hashAlgo, mgfunc, label): if hashAlgo: self._hashObj = hashAlgo else: - self._hashObj = Crypto.Hash.SHA1 + self._hashObj = Crypto.Hash.SHA if mgfunc: self._mgf = mgfunc @@ -117,12 +117,12 @@ def encrypt(self, message): section 7.1.1 of RFC3447. :Parameters: - message : byte string + message : string The message to encrypt, also known as plaintext. It can be of variable length, but not longer than the RSA modulus (in bytes) minus 2, minus twice the hash output size. - :Return: A byte string, the ciphertext in which the message is encrypted. + :Return: A string, the ciphertext in which the message is encrypted. It is as long as the RSA modulus (in bytes). :Raise ValueError: If the RSA key length is not sufficiently long to deal with the given @@ -173,10 +173,10 @@ def decrypt(self, ct): section 7.1.2 of RFC3447. :Parameters: - ct : byte string + ct : string The ciphertext that contains the message to recover. - :Return: A byte string, the original message. + :Return: A string, the original message. :Raise ValueError: If the ciphertext length is incorrect, or if the decryption does not succeed. @@ -238,12 +238,12 @@ def new(key, hashAlgo=None, mgfunc=None, label=b('')): hashAlgo : hash object The hash function to use. This can be a module under `Crypto.Hash` or an existing hash object created from any of such modules. If not specified, - `Crypto.Hash.SHA1` is used. + `Crypto.Hash.SHA` (that is, SHA-1) is used. mgfunc : callable A mask generation function that accepts two parameters: a string to use as seed, and the lenth of the mask to generate, in bytes. If not specified, the standard MGF1 is used (a safe choice). - label : byte string + label : string A label to apply to this particular encryption. If not specified, an empty string is used. Specifying a label does not improve security. diff --git a/lib/Crypto/Cipher/PKCS1_v1_5.py b/lib/Crypto/Cipher/PKCS1_v1_5.py index 345ffc23..c89035d7 100644 --- a/lib/Crypto/Cipher/PKCS1_v1_5.py +++ b/lib/Crypto/Cipher/PKCS1_v1_5.py @@ -34,7 +34,7 @@ >>> from Crypto.PublicKey import RSA >>> from Crypto.Hash import SHA >>> - >>> message = b'To be encrypted' + >>> message = 'To be encrypted' >>> h = SHA.new(message) >>> >>> key = RSA.importKey(open('pubkey.der').read()) diff --git a/lib/Crypto/Cipher/blockalgo.py b/lib/Crypto/Cipher/blockalgo.py index 002726c3..dd183dcb 100644 --- a/lib/Crypto/Cipher/blockalgo.py +++ b/lib/Crypto/Cipher/blockalgo.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Cipher/blockalgo.py +# Cipher/blockalgo.py # # =================================================================== # The contents of this file are dedicated to the public domain. To @@ -24,21 +24,8 @@ import sys if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * - from Crypto.Util.py3compat import * -from binascii import unhexlify - -from Crypto.Util import Counter -from Crypto.Util.strxor import strxor -from Crypto.Util.number import long_to_bytes, bytes_to_long -import Crypto.Util.Counter -from Crypto.Hash import CMAC -from Crypto.Hash.CMAC import _SmoothMAC -from Crypto.Protocol.KDF import _S2V - -from Crypto.Util import _galois - #: *Electronic Code Book (ECB)*. #: This is the simplest encryption mode. Each of the plaintext blocks #: is directly encrypted into a ciphertext block, independently of @@ -55,8 +42,8 @@ #: (*IV*) is required. #: #: The *IV* is a data block to be transmitted to the receiver. -#: The *IV* can be made public, but it must be authenticated by the receiver -#: and it should be picked randomly. +#: The *IV* can be made public, but it must be authenticated by the receiver and +#: it should be picked randomly. #: #: See `NIST SP800-38A`_ , Section 6.2 . #: @@ -86,8 +73,7 @@ #: *Output FeedBack (OFB)*. This mode is very similar to CBC, but it #: transforms the underlying block cipher into a stream cipher. -#: The keystream is the iterated block encryption of an -#: Initialization Vector (*IV*). +#: The keystream is the iterated block encryption of an Initialization Vector (*IV*). #: #: The *IV* is a data block to be transmitted to the receiver. #: The *IV* can be made public, but it should be picked randomly. @@ -114,7 +100,7 @@ #: to the *IV* for the other modes) and increment its lowest **m** bits by #: one (modulo *2^m*) for each block. In most cases, **m** is chosen to be half #: the block size. -#: +#: #: Reusing the same *initial counter block* for encryptions done with the same #: key lead to catastrophic cryptograhic failures. #: @@ -124,571 +110,105 @@ #: .. _`NIST SP800-38A` : http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf MODE_CTR = 6 -#: *OpenPGP CFB*. This mode is a variant of CFB, and it is only used in PGP and -#: OpenPGP_ applications. An Initialization Vector (*IV*) is required. -#: -#: Unlike CFB, the IV is not transmitted to the receiver. -#: Instead, the *encrypted* IV is. -#: The IV is a random data block. Two of its bytes are duplicated to act -#: as a checksum for the correctness of the key. The encrypted IV is -#: therefore 2 bytes longer than the clean IV. +#: OpenPGP. This mode is a variant of CFB, and it is only used in PGP and OpenPGP_ applications. +#: An Initialization Vector (*IV*) is required. +#: +#: Unlike CFB, the IV is not transmitted to the receiver. Instead, the *encrypted* IV is. +#: The IV is a random data block. Two of its bytes are duplicated to act as a checksum +#: for the correctness of the key. The encrypted IV is therefore 2 bytes longer than +#: the clean IV. #: #: .. _OpenPGP: http://tools.ietf.org/html/rfc4880 MODE_OPENPGP = 7 -#: *Counter with CBC-MAC (CCM)*. This is an Authenticated Encryption with -#: Associated Data (`AEAD`_) mode. It provides both confidentiality and -#: authenticity. -#: The header of the message may be left in the clear, if needed, and it will -#: still be subject to authentication. The decryption step tells the receiver -#: if the message comes from a source that really knowns the secret key. -#: Additionally, decryption detects if any part of the message - including the -#: header - has been modified or corrupted. -#: -#: This mode requires a nonce. The nonce shall never repeat for two -#: different messages encrypted with the same key, but it does not need -#: to be random. -#: Note that there is a trade-off between the size of the nonce and the -#: maximum size of a single message you can encrypt. -#: -#: It is important to use a large nonce if the key is reused across several -#: messages and the nonce is chosen randomly. -#: -#: It is acceptable to us a short nonce if the key is only used a few times or -#: if the nonce is taken from a counter. -#: -#: The following table shows the trade-off when the nonce is chosen at -#: random. The column on the left shows how many messages it takes -#: for the keystream to repeat **on average**. In practice, you will want to -#: stop using the key way before that. -#: -#: +--------------------+---------------+-------------------+ -#: | Avg. # of messages | nonce | Max. message | -#: | before keystream | size | size | -#: | repeats | (bytes) | (bytes) | -#: +====================+===============+===================+ -#: | 2**52 | 13 | 64K | -#: +--------------------+---------------+-------------------+ -#: | 2**48 | 12 | 16M | -#: +--------------------+---------------+-------------------+ -#: | 2**44 | 11 | 4G | -#: +--------------------+---------------+-------------------+ -#: | 2**40 | 10 | 1T | -#: +--------------------+---------------+-------------------+ -#: | 2**36 | 9 | 64P | -#: +--------------------+---------------+-------------------+ -#: | 2**32 | 8 | 16E | -#: +--------------------+---------------+-------------------+ -#: -#: This mode is only available for ciphers that operate on 128 bits blocks -#: (e.g. AES but not TDES). -#: -#: See `NIST SP800-38C`_ or RFC3610_ . -#: -#: .. _`NIST SP800-38C`: http://csrc.nist.gov/publications/nistpubs/800-38C/SP800-38C.pdf -#: .. _RFC3610: https://tools.ietf.org/html/rfc3610 -#: .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html -MODE_CCM = 8 - -#: *EAX*. This is an Authenticated Encryption with Associated Data -#: (`AEAD`_) mode. It provides both confidentiality and authenticity. -#: -#: The header of the message may be left in the clear, if needed, and it will -#: still be subject to authentication. -#: -#: The decryption step tells the receiver if the message comes from a source -#: that really knowns the secret key. -#: Additionally, decryption detects if any part of the message - including the -#: header - has been modified or corrupted. -#: -#: This mode requires a nonce. The nonce shall never repeat for two -#: different messages encrypted with the same key, but it does not need to -#: be random. -# -#: This mode is only available for ciphers that operate on 64 or -#: 128 bits blocks. -#: -#: There are no official standards defining EAX. The implementation is based on -#: `a proposal`__ that was presented to NIST. -#: -#: .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html -#: .. __: http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/eax/eax-spec.pdf -MODE_EAX = 9 - -#: *Synthetic Initialization Vector*. This is an Authenticated Encryption with -#: Associated Data (`AEAD`_) mode. It provides both confidentiality and -#: authenticity. -#: The header of the message may be left in the clear, if needed, and it will -#: still be subject to authentication. The decryption step tells the receiver -#: if the message comes from a source that really knowns the secret key. -#: Additionally, decryption detects if any part of the message - including the -#: header - has been modified or corrupted. -#: -#: If the data being encrypted is completely unpredictable to an adversary -#: (e.g. a secret key, for key wrapping purposes) a nonce is not strictly -#: required. -#: -#: Otherwise, a nonce has to be provided; the nonce shall never repeat -#: for two different messages encrypted with the same key, but it does not -#: need to be random. -#: -#: Unlike other AEAD modes such as CCM, EAX or GCM, accidental reuse of a -#: nonce is not catastrophic for the confidentiality of the message. The only -#: effect is that an attacker can tell when the same plaintext (and same -#: associated data) is protected with the same key. -#: -#: The length of the MAC is fixed to the block size of the underlying cipher. -#: The key size is twice the length of the key of the underlying cipher. -#: -#: This mode is only available for AES ciphers. -#: -#: +--------------------+---------------+-------------------+ -#: | Cipher | SIV MAC size | SIV key length | -#: | | (bytes) | (bytes) | -#: +====================+===============+===================+ -#: | AES-128 | 16 | 32 | -#: +--------------------+---------------+-------------------+ -#: | AES-192 | 16 | 48 | -#: +--------------------+---------------+-------------------+ -#: | AES-256 | 16 | 64 | -#: +--------------------+---------------+-------------------+ -#: -#: See `RFC5297`_ and the `original paper`__. -#: -#: .. _RFC5297: https://tools.ietf.org/html/rfc5297 -#: .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html -#: .. __: http://www.cs.ucdavis.edu/~rogaway/papers/keywrap.pdf -MODE_SIV = 10 - -#: *Galois/Counter Mode (GCM)*. This is an Authenticated Encryption with -#: Associated Data (`AEAD`_) mode. It provides both confidentiality and -#: authenticity. -#: The header of the message may be left in the clear, if needed, and it will -#: still be subject to authentication. The decryption step tells the receiver -#: if the message comes from a source that really knowns the secret key. -#: Additionally, decryption detects if any part of the message - including the -#: header - has been modified or corrupted. -#: -#: This mode requires a nonce. The nonce shall never repeat for two -#: different messages encrypted with the same key, but it does not need to -#: be random. -#: -#: This mode is only available for ciphers that operate on 128 bits blocks -#: (e.g. AES but not TDES). -#: -#: See `NIST SP800-38D`_ . -#: -#: .. _`NIST SP800-38D`: http://csrc.nist.gov/publications/nistpubs/800-38D/SP-800-38D.pdf -#: .. _AEAD: http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html -MODE_GCM = 11 - - def _getParameter(name, index, args, kwargs, default=None): """Find a parameter in tuple and dictionary arguments a function receives""" - param = kwargs.get(name) - if len(args) > index: + if len(args)>index: if param: - raise TypeError("Parameter '%s' is specified twice" % name) + raise ValueError("Parameter '%s' is specified twice" % name) param = args[index] return param or default - - -class _CBCMAC(_SmoothMAC): - - def __init__(self, key, ciphermod): - _SmoothMAC.__init__(self, ciphermod.block_size, None, 0) - self._key = key - self._factory = ciphermod - - def _ignite(self, data): - if self._mac: - raise TypeError("_ignite() cannot be called twice") - - self._buffer.insert(0, data) - self._buffer_len += len(data) - self._mac = self._factory.new(self._key, MODE_CBC, bchr(0) * 16) - self.update(b("")) - - def _update(self, block_data): - self._t = self._mac.encrypt(block_data)[-16:] - - def _digest(self, left_data): - return self._t - - -class _GHASH(_SmoothMAC): - """GHASH function defined in NIST SP 800-38D, Algorithm 2. - - If X_1, X_2, .. X_m are the blocks of input data, the function - computes: - - X_1*H^{m} + X_2*H^{m-1} + ... + X_m*H - - in the Galois field GF(2^256) using the reducing polynomial - (x^128 + x^7 + x^2 + x + 1). - """ - - def __init__(self, hash_subkey, block_size): - _SmoothMAC.__init__(self, block_size, None, 0) - self._hash_subkey = _galois.ghash_expand(hash_subkey) - self._last_y = bchr(0) * 16 - self._mac = _galois.ghash - - def copy(self): - clone = _GHASH(self._hash_subkey, self._bs) - _SmoothMAC._deep_copy(self, clone) - clone._last_y = self._last_y - return clone - - def _update(self, block_data): - self._last_y = _galois.ghash(block_data, self._last_y, - self._hash_subkey) - - def _digest(self, left_data): - return self._last_y - - + class BlockAlgo: """Class modelling an abstract block cipher.""" def __init__(self, factory, key, *args, **kwargs): self.mode = _getParameter('mode', 0, args, kwargs, default=MODE_ECB) self.block_size = factory.block_size - self._factory = factory - self._tag = None - - if self.mode == MODE_CCM: - if self.block_size != 16: - raise TypeError("CCM mode is only available for ciphers that operate on 128 bits blocks") - - self._mac_len = kwargs.get('mac_len', 16) # t - if self._mac_len not in (4, 6, 8, 10, 12, 14, 16): - raise ValueError("Parameter 'mac_len' must be even and in the range 4..16") - - self.nonce = _getParameter('nonce', 1, args, kwargs) # N - if not (self.nonce and 7 <= len(self.nonce) <= 13): - raise ValueError("Length of parameter 'nonce' must be" - " in the range 7..13 bytes") - - self._key = key - self._msg_len = kwargs.get('msg_len', None) # p - self._assoc_len = kwargs.get('assoc_len', None) # a - - self._cipherMAC = _CBCMAC(key, factory) - self._done_assoc_data = False # True when all associated data - # has been processed - - # Allowed transitions after initialization - self._next = [self.update, self.encrypt, self.decrypt, - self.digest, self.verify] - - # Try to start CCM - self._start_ccm() - - elif self.mode == MODE_OPENPGP: - self._start_PGP(factory, key, *args, **kwargs) - elif self.mode == MODE_EAX: - self._start_eax(factory, key, *args, **kwargs) - elif self.mode == MODE_SIV: - self._start_siv(factory, key, *args, **kwargs) - elif self.mode == MODE_GCM: - self._start_gcm(factory, key, *args, **kwargs) - else: + + if self.mode != MODE_OPENPGP: self._cipher = factory.new(key, *args, **kwargs) self.IV = self._cipher.IV - - def _start_gcm(self, factory, key, *args, **kwargs): - - if self.block_size != 16: - raise TypeError("GCM mode is only available for ciphers that operate on 128 bits blocks") - - self.nonce = _getParameter('nonce', 1, args, kwargs) - if not self.nonce: - raise TypeError("MODE_GCM requires a nonce") - - self._mac_len = kwargs.get('mac_len', 16) - if not (self._mac_len and 4 <= self._mac_len <= 16): - raise ValueError("Parameter 'mac_len' must not be larger than 16 bytes") - - # Allowed transitions after initialization - self._next = [self.update, self.encrypt, self.decrypt, - self.digest, self.verify] - - self._done_assoc_data = False - - # Length of the ciphertext or plaintext - self._msg_len = 0 - - # Step 1 in SP800-38D, Algorithm 4 (encryption) - Compute H - # See also Algorithm 5 (decryption) - hash_subkey = factory.new(key).encrypt(bchr(0) * 16) - - # Step 2 - Compute J0 (integer, not byte string!) - if len(self.nonce) == 12: - self._j0 = bytes_to_long(self.nonce + b("\x00\x00\x00\x01")) else: - fill = (16 - (len(self.nonce) % 16)) % 16 + 8 - ghash_in = (self.nonce + - bchr(0) * fill + - long_to_bytes(8 * len(self.nonce), 8)) - - mac = _GHASH(hash_subkey, factory.block_size) - mac.update(ghash_in) - self._j0 = bytes_to_long(mac.digest()) - - # Step 3 - Prepare GCTR cipher for encryption/decryption - ctr = Counter.new(128, initial_value=self._j0 + 1, - allow_wraparound=True) - self._cipher = self._factory.new(key, MODE_CTR, counter=ctr) - - # Step 5 - Bootstrat GHASH - self._cipherMAC = _GHASH(hash_subkey, factory.block_size) - - # Step 6 - Prepare GCTR cipher for GMAC - ctr = Counter.new(128, initial_value=self._j0, allow_wraparound=True) - self._tag_cipher = self._factory.new(key, MODE_CTR, counter=ctr) - - def _start_siv(self, factory, key, *args, **kwargs): - - subkey_size, rem = divmod(len(key), 2) - if rem: - raise ValueError("MODE_SIV requires a key twice as long as for the underlying cipher") - - # IV is optional - self.nonce = _getParameter('nonce', 1, args, kwargs) - - self._cipherMAC = _S2V(key[:subkey_size], ciphermod=factory) - self._subkey_ctr = key[subkey_size:] - self._mac_len = factory.block_size - - self._cipherMAC = self._cipherMAC - - # Allowed transitions after initialization - self._next = [self.update, self.encrypt, self.decrypt, - self.digest, self.verify] - - def _siv_ctr_cipher(self, tag): - """Create a new CTR cipher from the MAC in SIV mode""" - - tag_int = bytes_to_long(tag) - init_counter = tag_int ^ (tag_int & 0x8000000080000000L) - ctr = Counter.new(self._factory.block_size * 8, - initial_value=init_counter, - allow_wraparound=True) - - return self._factory.new(self._subkey_ctr, MODE_CTR, counter=ctr) - - def _start_eax(self, factory, key, *args, **kwargs): - - self.nonce = _getParameter('nonce', 1, args, kwargs) - if not self.nonce: - raise TypeError("MODE_EAX requires a nonce") - - # Allowed transitions after initialization - self._next = [self.update, self.encrypt, self.decrypt, - self.digest, self.verify] - - self._mac_len = kwargs.get('mac_len', self.block_size) - if not (self._mac_len and 4 <= self._mac_len <= self.block_size): - raise ValueError("Parameter 'mac_len' must not be larger than %d" - % self.block_size) - - self._omac = [ - CMAC.new(key, bchr(0) * (self.block_size - 1) + bchr(i), - ciphermod=factory) - for i in xrange(0, 3) - ] - - # Compute MAC of nonce - self._omac[0].update(self.nonce) - - self._cipherMAC = self._omac[1] - - # MAC of the nonce is also the initial counter for CTR encryption - counter_int = bytes_to_long(self._omac[0].digest()) - counter_obj = Crypto.Util.Counter.new( - self.block_size * 8, - initial_value=counter_int, - allow_wraparound=True) - self._cipher = factory.new(key, MODE_CTR, counter=counter_obj) - - def _start_PGP(self, factory, key, *args, **kwargs): - # OPENPGP mode. For details, see 13.9 in RCC4880. - # - # A few members are specifically created for this mode: - # - _encrypted_iv, set in this constructor - # - _done_first_block, set to True after the first encryption - # - _done_last_block, set to True after a partial block is processed - - self._done_first_block = False - self._done_last_block = False - self.IV = _getParameter('IV', 1, args, kwargs) - if self.IV is None: - # TODO: Decide whether 'IV' or 'iv' should be used going forward, - # and deprecate the other. 'IV' is consistent with the rest of - # PyCrypto, but 'iv' is more common in Python generally. For now, - # we'll support both here. When in doubt, use a positional - # parameter for now. + # OPENPGP mode. For details, see 13.9 in RCC4880. + # + # A few members are specifically created for this mode: + # - _encrypted_iv, set in this constructor + # - _done_first_block, set to True after the first encryption + # - _done_last_block, set to True after a partial block is processed + + self._done_first_block = False + self._done_last_block = False self.IV = _getParameter('iv', 1, args, kwargs) - if not self.IV: - raise ValueError("MODE_OPENPGP requires an IV") - - # Instantiate a temporary cipher to process the IV - IV_cipher = factory.new( - key, - MODE_CFB, - b('\x00') * self.block_size, # IV for CFB - segment_size=self.block_size * 8) - - # The cipher will be used for... - if len(self.IV) == self.block_size: - # ... encryption - self._encrypted_IV = IV_cipher.encrypt( - self.IV + self.IV[-2:] + # Plaintext - b('\x00') * (self.block_size - 2) # Padding - )[:self.block_size + 2] - elif len(self.IV) == self.block_size + 2: - # ... decryption - self._encrypted_IV = self.IV - self.IV = IV_cipher.decrypt( - self.IV + # Ciphertext - b('\x00') * (self.block_size - 2) # Padding - )[:self.block_size + 2] - if self.IV[-2:] != self.IV[-4:-2]: - raise ValueError("Failed integrity check for OPENPGP IV") - self.IV = self.IV[:-2] - else: - raise ValueError("Length of IV must be %d or %d bytes for MODE_OPENPGP" - % (self.block_size, self.block_size+2)) - - # Instantiate the cipher for the real PGP data - self._cipher = factory.new( - key, - MODE_CFB, - self._encrypted_IV[-self.block_size:], - segment_size=self.block_size * 8 - ) - - def _start_ccm(self, assoc_len=None, msg_len=None): - # CCM mode. This method creates the 2 ciphers used for the MAC - # (self._cipherMAC) and for the encryption/decryption (self._cipher). - # - # Member _assoc_buffer may already contain user data that needs to be - # authenticated. - - if self._cipherMAC.can_reduce(): - # Already started - return - if assoc_len is not None: - self._assoc_len = assoc_len - if msg_len is not None: - self._msg_len = msg_len - if None in (self._assoc_len, self._msg_len): - return - - # q is the length of Q, the encoding of the message length - q = 15 - len(self.nonce) - - ## Compute B_0 - flags = ( - 64 * (self._assoc_len > 0) + - 8 * divmod(self._mac_len - 2, 2)[0] + - (q - 1) - ) - b_0 = bchr(flags) + self.nonce + long_to_bytes(self._msg_len, q) - - # Start CBC MAC with zero IV - assoc_len_encoded = b('') - if self._assoc_len > 0: - if self._assoc_len < (2 ** 16 - 2 ** 8): - enc_size = 2 - elif self._assoc_len < (2L ** 32): - assoc_len_encoded = b('\xFF\xFE') - enc_size = 4 + if not self.IV: + raise ValueError("MODE_OPENPGP requires an IV") + + # Instantiate a temporary cipher to process the IV + IV_cipher = factory.new(key, MODE_CFB, + b('\x00')*self.block_size, # IV for CFB + segment_size=self.block_size*8) + + # The cipher will be used for... + if len(self.IV) == self.block_size: + # ... encryption + self._encrypted_IV = IV_cipher.encrypt( + self.IV + self.IV[-2:] + # Plaintext + b('\x00')*(self.block_size-2) # Padding + )[:self.block_size+2] + elif len(self.IV) == self.block_size+2: + # ... decryption + self._encrypted_IV = self.IV + self.IV = IV_cipher.decrypt(self.IV + # Ciphertext + b('\x00')*(self.block_size-2) # Padding + )[:self.block_size+2] + if self.IV[-2:] != self.IV[-4:-2]: + raise ValueError("Failed integrity check for OPENPGP IV") + self.IV = self.IV[:-2] else: - assoc_len_encoded = b('\xFF\xFF') - enc_size = 8 - assoc_len_encoded += long_to_bytes(self._assoc_len, enc_size) - self._cipherMAC._ignite(b_0 + assoc_len_encoded) - - # Start CTR cipher - prefix = bchr(q - 1) + self.nonce - ctr = Counter.new(128 - len(prefix) * 8, prefix, initial_value=0) - self._cipher = self._factory.new(self._key, MODE_CTR, counter=ctr) - # Will XOR against CBC MAC - self._s_0 = self._cipher.encrypt(bchr(0) * 16) - - def update(self, assoc_data): - """Protect associated data - - When using an AEAD mode like CCM, EAX, GCM or SIV, and - if there is any associated data, the caller has to invoke - this function one or more times, before using - ``decrypt`` or ``encrypt``. - - By *associated data* it is meant any data (e.g. packet headers) that - will not be encrypted and will be transmitted in the clear. - However, the receiver is still able to detect any modification to it. - In CCM and GCM, the *associated data* is also called - *additional authenticated data* (AAD). - In EAX, the *associated data* is called *header*. - - If there is no associated data, this method must not be called. - - The caller may split associated data in segments of any size, and - invoke this method multiple times, each time with the next segment. + raise ValueError("Length of IV must be %d or %d bytes for MODE_OPENPGP" + % (self.block_size, self.block_size+2)) - :Parameters: - assoc_data : byte string - A piece of associated data. There are no restrictions on its size. - """ - - if self.mode not in (MODE_CCM, MODE_EAX, MODE_SIV, MODE_GCM): - raise TypeError("update() not supported by this mode of operation") - - if self.update not in self._next: - raise TypeError("update() can only be called immediately after initialization") - - self._next = [self.update, self.encrypt, self.decrypt, - self.digest, self.verify] - - return self._cipherMAC.update(assoc_data) + # Instantiate the cipher for the real PGP data + self._cipher = factory.new(key, MODE_CFB, + self._encrypted_IV[-self.block_size:], + segment_size=self.block_size*8) def encrypt(self, plaintext): """Encrypt data with the key and the parameters set at initialization. - - A cipher object is stateful: once you have encrypted a message - you cannot encrypt (or decrypt) another message using the same - object. - - For `MODE_SIV` (always) and `MODE_CCM` (when ``msg_len`` was not - passed at initialization), this method can be called only **once**. - - For all other modes, the data to encrypt can be broken up in two or - more pieces and `encrypt` can be called multiple times. - + + The cipher object is stateful; encryption of a long block + of data can be broken up in two or more calls to `encrypt()`. That is, the statement: - + >>> c.encrypt(a) + c.encrypt(b) - is equivalent to: + is always equivalent to: >>> c.encrypt(a+b) That also means that you cannot reuse an object for encrypting or decrypting other data with the same key. - This function does not add any padding to the plaintext. - - - For `MODE_ECB` and `MODE_CBC`, *plaintext* length (in bytes) must be - a multiple of *block_size*. + This function does not perform any padding. + + - For `MODE_ECB`, `MODE_CBC`, and `MODE_OFB`, *plaintext* length + (in bytes) must be a multiple of *block_size*. - For `MODE_CFB`, *plaintext* length (in bytes) must be a multiple of *segment_size*/8. - - For `MODE_OFB`, `MODE_CTR` and all AEAD modes - *plaintext* can be of any length. + - For `MODE_CTR`, *plaintext* can be of any length. - For `MODE_OPENPGP`, *plaintext* must be a multiple of *block_size*, unless it is the last chunk of the message. @@ -705,15 +225,14 @@ def encrypt(self, plaintext): if self.mode == MODE_OPENPGP: padding_length = (self.block_size - len(plaintext) % self.block_size) % self.block_size - if padding_length > 0: - # CFB mode requires ciphertext to have length multiple - # of block size, + if padding_length>0: + # CFB mode requires ciphertext to have length multiple of block size, # but PGP mode allows the last block to be shorter if self._done_last_block: raise ValueError("Only the last chunk is allowed to have length not multiple of %d bytes", self.block_size) self._done_last_block = True - padded = plaintext + b('\x00') * padding_length + padded = plaintext + b('\x00')*padding_length res = self._cipher.encrypt(padded)[:len(plaintext)] else: res = self._cipher.encrypt(plaintext) @@ -722,312 +241,56 @@ def encrypt(self, plaintext): self._done_first_block = True return res - if self.mode in (MODE_CCM, MODE_EAX, MODE_SIV, MODE_GCM): - if self.encrypt not in self._next: - raise TypeError("encrypt() can only be called after initialization or an update()") - self._next = [self.encrypt, self.digest] - - if self.mode == MODE_CCM: - if self._assoc_len is None: - self._start_ccm(assoc_len=self._cipherMAC.get_len()) - if self._msg_len is None: - self._start_ccm(msg_len=len(plaintext)) - self._next = [self.digest] - if not self._done_assoc_data: - self._cipherMAC.zero_pad() - self._done_assoc_data = True - - self._cipherMAC.update(plaintext) - - if self.mode == MODE_SIV: - self._next = [self.digest] - - if self.nonce: - self._cipherMAC.update(self.nonce) - - self._cipherMAC.update(plaintext) - self._cipher = self._siv_ctr_cipher(self._cipherMAC.derive()) - - ct = self._cipher.encrypt(plaintext) - - if self.mode == MODE_EAX: - self._omac[2].update(ct) - - if self.mode == MODE_GCM: - if not self._done_assoc_data: - self._cipherMAC.zero_pad() - self._done_assoc_data = True - self._cipherMAC.update(ct) - self._msg_len += len(plaintext) - - return ct + return self._cipher.encrypt(plaintext) def decrypt(self, ciphertext): """Decrypt data with the key and the parameters set at initialization. - - A cipher object is stateful: once you have decrypted a message - you cannot decrypt (or encrypt) another message with the same - object. - - For `MODE_SIV` (always) and `MODE_CCM` (when ``msg_len`` was not - passed at initialization), this method can be called only **once**. - - For all other modes, the data to decrypt can be broken up in two or - more pieces and `decrypt` can be called multiple times. - + + The cipher object is stateful; decryption of a long block + of data can be broken up in two or more calls to `decrypt()`. That is, the statement: - + >>> c.decrypt(a) + c.decrypt(b) - is equivalent to: + is always equivalent to: >>> c.decrypt(a+b) That also means that you cannot reuse an object for encrypting or decrypting other data with the same key. - This function does not remove any padding from the plaintext. - - - For `MODE_ECB` and `MODE_CBC`, *ciphertext* length (in bytes) must - be a multiple of *block_size*. + This function does not perform any padding. + + - For `MODE_ECB`, `MODE_CBC`, and `MODE_OFB`, *ciphertext* length + (in bytes) must be a multiple of *block_size*. - For `MODE_CFB`, *ciphertext* length (in bytes) must be a multiple of *segment_size*/8. - - For `MODE_OFB`, `MODE_CTR` and all AEAD modes - *ciphertext* can be of any length. + - For `MODE_CTR`, *ciphertext* can be of any length. - For `MODE_OPENPGP`, *plaintext* must be a multiple of *block_size*, unless it is the last chunk of the message. - - For `MODE_SIV`, *ciphertext* can be of any length, but it must also - include the MAC (concatenated at the end). - :Parameters: ciphertext : byte string - The piece of data to decrypt (plus the MAC, for `MODE_SIV` only). - - :Return: the decrypted data (byte string). + The piece of data to decrypt. + :Return: the decrypted data (byte string, as long as *ciphertext*). """ - if self.mode == MODE_OPENPGP: padding_length = (self.block_size - len(ciphertext) % self.block_size) % self.block_size - if padding_length > 0: - # CFB mode requires ciphertext to have length multiple - # of block size, + if padding_length>0: + # CFB mode requires ciphertext to have length multiple of block size, # but PGP mode allows the last block to be shorter if self._done_last_block: raise ValueError("Only the last chunk is allowed to have length not multiple of %d bytes", self.block_size) self._done_last_block = True - padded = ciphertext + b('\x00') * padding_length + padded = ciphertext + b('\x00')*padding_length res = self._cipher.decrypt(padded)[:len(ciphertext)] else: res = self._cipher.decrypt(ciphertext) return res - if self.mode == MODE_SIV: - raise TypeError("decrypt() not allowed for SIV mode." - " Use decrypt_and_verify() instead.") - - if self.mode in (MODE_CCM, MODE_EAX, MODE_GCM): - - if self.decrypt not in self._next: - raise TypeError("decrypt() can only be called after initialization or an update()") - self._next = [self.decrypt, self.verify] - - if self.mode == MODE_CCM: - if self._assoc_len is None: - self._start_ccm(assoc_len=self._cipherMAC.get_len()) - if self._msg_len is None: - self._start_ccm(msg_len=len(ciphertext)) - self._next = [self.verify] - if not self._done_assoc_data: - self._cipherMAC.zero_pad() - self._done_assoc_data = True - - if self.mode == MODE_GCM: - if not self._done_assoc_data: - self._cipherMAC.zero_pad() - self._done_assoc_data = True - - self._cipherMAC.update(ciphertext) - self._msg_len += len(ciphertext) - - if self.mode == MODE_EAX: - self._omac[2].update(ciphertext) - - pt = self._cipher.decrypt(ciphertext) - - if self.mode == MODE_CCM: - self._cipherMAC.update(pt) - - return pt - - def digest(self): - """Compute the *binary* MAC tag in an AEAD mode. - - When using an AEAD mode like CCM or EAX, the caller invokes - this function at the very end. - - This method returns the MAC that shall be sent to the receiver, - together with the ciphertext. - - :Return: the MAC, as a byte string. - """ - - if self.mode not in (MODE_CCM, MODE_EAX, MODE_SIV, MODE_GCM): - raise TypeError("digest() not supported by this mode of operation") - - if self.digest not in self._next: - raise TypeError("digest() cannot be called when decrypting or validating a message") - self._next = [self.digest] - - return self._compute_mac() - - def _compute_mac(self): - """Compute MAC without any FSM checks.""" - - if self._tag: - return self._tag - - if self.mode == MODE_CCM: - - if self._assoc_len is None: - self._start_ccm(assoc_len=self._cipherMAC.get_len()) - if self._msg_len is None: - self._start_ccm(msg_len=0) - self._cipherMAC.zero_pad() - self._tag = strxor(self._cipherMAC.digest(), - self._s_0)[:self._mac_len] - - if self.mode == MODE_GCM: - - # Step 5 in NIST SP 800-38D, Algorithm 4 - Compute S - self._cipherMAC.zero_pad() - auth_len = self._cipherMAC.get_len() - self._msg_len - for tlen in (auth_len, self._msg_len): - self._cipherMAC.update(long_to_bytes(8 * tlen, 8)) - s_tag = self._cipherMAC.digest() - - # Step 6 - Compute T - self._tag = self._tag_cipher.encrypt(s_tag)[:self._mac_len] - - if self.mode == MODE_EAX: - tag = bchr(0) * self.block_size - for i in xrange(3): - tag = strxor(tag, self._omac[i].digest()) - self._tag = tag[:self._mac_len] - - if self.mode == MODE_SIV: - self._tag = self._cipherMAC.derive() - - return self._tag - - def hexdigest(self): - """Compute the *printable* MAC tag in an AEAD mode. - - This method is like `digest`. - - :Return: the MAC, as a hexadecimal string. - """ - return "".join(["%02x" % bord(x) for x in self.digest()]) - - def verify(self, mac_tag): - """Validate the *binary* MAC tag in an AEAD mode. - - When using an AEAD mode like CCM or EAX, the caller invokes - this function at the very end. - - This method checks if the decrypted message is indeed valid - (that is, if the key is correct) and it has not been - tampered with while in transit. - - :Parameters: - mac_tag : byte string - This is the *binary* MAC, as received from the sender. - :Raises ValueError: - if the MAC does not match. The message has been tampered with - or the key is incorrect. - """ - - if self.mode not in (MODE_CCM, MODE_EAX, MODE_SIV, MODE_GCM): - raise TypeError("verify() not supported by this mode of operation") - - if self.verify not in self._next: - raise TypeError("verify() cannot be called when encrypting a message") - self._next = [self.verify] - - res = 0 - # Constant-time comparison - for x, y in zip(self._compute_mac(), mac_tag): - res |= bord(x) ^ bord(y) - if res or len(mac_tag) != self._mac_len: - raise ValueError("MAC check failed") - - def hexverify(self, hex_mac_tag): - """Validate the *printable* MAC tag in an AEAD mode. - - This method is like `verify`. - - :Parameters: - hex_mac_tag : string - This is the *printable* MAC, as received from the sender. - :Raises ValueError: - if the MAC does not match. The message has been tampered with - or the key is incorrect. - """ - - self.verify(unhexlify(hex_mac_tag)) - - def encrypt_and_digest(self, plaintext): - """Perform encrypt() and digest() in one step. - - :Parameters: - plaintext : byte string - The piece of data to encrypt. - :Return: - a tuple with two byte strings: - - - the encrypted data - - the MAC - """ - - return self.encrypt(plaintext), self.digest() - - def decrypt_and_verify(self, ciphertext, mac_tag): - """Perform decrypt() and verify() in one step. - - :Parameters: - ciphertext : byte string - The piece of data to decrypt. - mac_tag : byte string - This is the *binary* MAC, as received from the sender. - - :Return: the decrypted data (byte string). - :Raises ValueError: - if the MAC does not match. The message has been tampered with - or the key is incorrect. - """ - - if self.mode == MODE_SIV: - if self.decrypt not in self._next: - raise TypeError("decrypt() can only be called" - " after initialization or an update()") - self._next = [self.verify] - - # Take the MAC and start the cipher for decryption - self._mac = mac_tag - self._cipher = self._siv_ctr_cipher(self._mac) - - pt = self._cipher.decrypt(ciphertext) - - if self.nonce: - self._cipherMAC.update(self.nonce) - if pt: - self._cipherMAC.update(pt) - else: - pt = self.decrypt(ciphertext) + return self._cipher.decrypt(ciphertext) - self.verify(mac_tag) - return pt diff --git a/lib/Crypto/Hash/CMAC.py b/lib/Crypto/Hash/CMAC.py deleted file mode 100644 index 63050549..00000000 --- a/lib/Crypto/Hash/CMAC.py +++ /dev/null @@ -1,343 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Hash/CMAC.py - Implements the CMAC algorithm -# -# =================================================================== -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# =================================================================== - -"""CMAC (Cipher-based Message Authentication Code) algorithm - -CMAC is a MAC defined in `NIST SP 800-38B`_ and in RFC4493_ (for AES only) -and constructed using a block cipher. It was originally known as `OMAC1`_. - -The algorithm is sometimes named *X-CMAC* where *X* is the name -of the cipher (e.g. AES-CMAC). - -This is an example showing how to *create* an AES-CMAC: - - >>> from Crypto.Hash import CMAC - >>> from Crypto.Cipher import AES - >>> - >>> secret = b'Sixteen byte key' - >>> cobj = CMAC.new(secret, ciphermod=AES) - >>> cobj.update(b'Hello') - >>> print cobj.hexdigest() - -And this is an example showing how to *check* an AES-CMAC: - - >>> from Crypto.Hash import CMAC - >>> from Crypto.Cipher import AES - >>> - >>> # We have received a message 'msg' together - >>> # with its MAC 'mac' - >>> - >>> secret = b'Sixteen byte key' - >>> cobj = CMAC.new(secret, ciphermod=AES) - >>> cobj.update(msg) - >>> try: - >>> cobj.verify(mac) - >>> print "The message '%s' is authentic" % msg - >>> except ValueError: - >>> print "The message or the key is wrong" - -.. _`NIST SP 800-38B`: http://csrc.nist.gov/publications/nistpubs/800-38B/SP_800-38B.pdf -.. _RFC4493: http://www.ietf.org/rfc/rfc4493.txt -.. _OMAC1: http://www.nuee.nagoya-u.ac.jp/labs/tiwata/omac/omac.html -""" - -__all__ = ['new', 'digest_size', 'CMAC' ] - -import sys -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * -from Crypto.Util.py3compat import * - -from binascii import unhexlify - -from Crypto.Util.strxor import strxor -from Crypto.Util.number import long_to_bytes, bytes_to_long - -#: The size of the authentication tag produced by the MAC. -digest_size = None - -def _shift_bytes(bs, xor_lsb=0): - num = (bytes_to_long(bs)<<1) ^ xor_lsb - return long_to_bytes(num, len(bs))[-len(bs):] - -class _SmoothMAC(object): - """Turn a MAC that only operates on aligned blocks of data - into a MAC with granularity of 1 byte.""" - - def __init__(self, block_size, msg=b(""), min_digest=0): - self._bs = block_size - #: Data waiting to be MAC-ed - self._buffer = [] - self._buffer_len = 0 - #: Data received via update() - self._total_len = 0 - #: Minimum amount of bytes required by the final digest step - self._min_digest = min_digest - #: Block MAC object - self._mac = None - #: Cached digest - self._tag = None - if msg: - self.update(msg) - - def can_reduce(self): - return (self._mac is not None) - - def get_len(self): - return self._total_len - - def zero_pad(self): - if self._buffer_len & (self._bs-1): - npad = self._bs - self._buffer_len & (self._bs-1) - self._buffer.append(bchr(0)*npad) - self._buffer_len += npad - - def update(self, data): - # Optimization (try not to copy data if possible) - if self._buffer_len==0 and self.can_reduce() and\ - self._min_digest==0 and len(data)%self._bs==0: - self._update(data) - self._total_len += len(data) - return - - self._buffer.append(data) - self._buffer_len += len(data) - self._total_len += len(data) - - # Feed data into MAC - blocks, rem = divmod(self._buffer_len, self._bs) - if rem0 and self.can_reduce(): - aligned_data = blocks*self._bs - buf = b("").join(self._buffer) - self._update(buf[:aligned_data]) - self._buffer = [ buf[aligned_data:] ] - self._buffer_len -= aligned_data - - def _deep_copy(self, target): - # Copy everything by self._mac, since we don't know how to - target._buffer = self._buffer[:] - for m in [ '_bs', '_buffer_len', '_total_len', '_min_digest', '_tag' ]: - setattr(target, m, getattr(self, m)) - - def _update(self, data_block): - """Delegate to the implementation the update - of the MAC state given some new *block aligned* data.""" - raise NotImplementedError("_update() must be still implemented") - - def _digest(self, left_data): - """Delegate to the implementation the computation - of the final MAC given the current MAC state - and the last piece of data (not block aligned).""" - raise NotImplementedError("_digest() must be still implemented") - - def digest(self): - if self._tag: - return self._tag - if self._buffer_len>0: - self.update(b("")) - left_data = b("").join(self._buffer) - self._tag = self._digest(left_data) - return self._tag - -class CMAC(_SmoothMAC): - """Class that implements CMAC""" - - #: The size of the authentication tag produced by the MAC. - digest_size = None - - def __init__(self, key, msg = None, ciphermod = None): - """Create a new CMAC object. - - :Parameters: - key : byte string - secret key for the CMAC object. - The key must be valid for the underlying cipher algorithm. - For instance, it must be 16 bytes long for AES-128. - msg : byte string - The very first chunk of the message to authenticate. - It is equivalent to an early call to `update`. Optional. - ciphermod : module - A cipher module from `Crypto.Cipher`. - The cipher's block size must be 64 or 128 bits. - It is recommended to use `Crypto.Cipher.AES`. - """ - - if ciphermod is None: - raise TypeError("ciphermod must be specified (try AES)") - - _SmoothMAC.__init__(self, ciphermod.block_size, msg, 1) - - self._key = key - self._factory = ciphermod - - # Section 5.3 of NIST SP 800 38B - if ciphermod.block_size==8: - const_Rb = 0x1B - elif ciphermod.block_size==16: - const_Rb = 0x87 - else: - raise TypeError("CMAC requires a cipher with a block size of 8 or 16 bytes, not %d" % - (ciphermod.block_size,)) - self.digest_size = ciphermod.block_size - - # Compute sub-keys - cipher = ciphermod.new(key, ciphermod.MODE_ECB) - l = cipher.encrypt(bchr(0)*ciphermod.block_size) - if bord(l[0]) & 0x80: - self._k1 = _shift_bytes(l, const_Rb) - else: - self._k1 = _shift_bytes(l) - if bord(self._k1[0]) & 0x80: - self._k2 = _shift_bytes(self._k1, const_Rb) - else: - self._k2 = _shift_bytes(self._k1) - - # Initialize CBC cipher with zero IV - self._IV = bchr(0)*ciphermod.block_size - self._mac = ciphermod.new(key, ciphermod.MODE_CBC, self._IV) - - def update(self, msg): - """Continue authentication of a message by consuming the next chunk of data. - - Repeated calls are equivalent to a single call with the concatenation - of all the arguments. In other words: - - >>> m.update(a); m.update(b) - - is equivalent to: - - >>> m.update(a+b) - - :Parameters: - msg : byte string - The next chunk of the message being authenticated - """ - - _SmoothMAC.update(self, msg) - - def _update(self, data_block): - self._IV = self._mac.encrypt(data_block)[-self._mac.block_size:] - - def copy(self): - """Return a copy ("clone") of the MAC object. - - The copy will have the same internal state as the original MAC - object. - This can be used to efficiently compute the MAC of strings that - share a common initial substring. - - :Returns: A `CMAC` object - """ - obj = CMAC(self._key, ciphermod=self._factory) - - _SmoothMAC._deep_copy(self, obj) - obj._mac = self._factory.new(self._key, self._factory.MODE_CBC, self._IV) - for m in [ '_tag', '_k1', '_k2', '_IV']: - setattr(obj, m, getattr(self, m)) - return obj - - def digest(self): - """Return the **binary** (non-printable) MAC of the message that has - been authenticated so far. - - This method does not change the state of the MAC object. - You can continue updating the object after calling this function. - - :Return: A byte string of `digest_size` bytes. It may contain non-ASCII - characters, including null bytes. - """ - return _SmoothMAC.digest(self) - - def _digest(self, last_data): - if len(last_data)==self._bs: - last_block = strxor(last_data, self._k1) - else: - last_block = strxor(last_data+bchr(128)+ - bchr(0)*(self._bs-1-len(last_data)), self._k2) - tag = self._mac.encrypt(last_block) - return tag - - def hexdigest(self): - """Return the **printable** MAC of the message that has been - authenticated so far. - - This method does not change the state of the MAC object. - - :Return: A string of 2* `digest_size` bytes. It contains only - hexadecimal ASCII digits. - """ - return "".join(["%02x" % bord(x) - for x in tuple(self.digest())]) - - def verify(self, mac_tag): - """Verify that a given **binary** MAC (computed by another party) is valid. - - :Parameters: - mac_tag : byte string - The expected MAC of the message. - :Raises ValueError: - if the MAC does not match. It means that the message - has been tampered with or that the MAC key is incorrect. - """ - - mac = self.digest() - res = 0 - # Constant-time comparison - for x,y in zip(mac, mac_tag): - res |= bord(x) ^ bord(y) - if res or len(mac_tag)!=self.digest_size: - raise ValueError("MAC check failed") - - def hexverify(self, hex_mac_tag): - """Verify that a given **printable** MAC (computed by another party) is valid. - - :Parameters: - hex_mac_tag : string - The expected MAC of the message, as a hexadecimal string. - :Raises ValueError: - if the MAC does not match. It means that the message - has been tampered with or that the MAC key is incorrect. - """ - - self.verify(unhexlify(tobytes(hex_mac_tag))) - -def new(key, msg = None, ciphermod = None): - """Create a new CMAC object. - - :Parameters: - key : byte string - secret key for the CMAC object. - The key must be valid for the underlying cipher algorithm. - For instance, it must be 16 bytes long for AES-128. - msg : byte string - The very first chunk of the message to authenticate. - It is equivalent to an early call to `CMAC.update`. Optional. - ciphermod : module - A cipher module from `Crypto.Cipher`. - The cipher's block size must be 64 or 128 bits. - Default is `Crypto.Cipher.AES`. - - :Returns: A `CMAC` object - """ - return CMAC(key, msg, ciphermod) diff --git a/lib/Crypto/Hash/HMAC.py b/lib/Crypto/Hash/HMAC.py index 88654117..6244db46 100644 --- a/lib/Crypto/Hash/HMAC.py +++ b/lib/Crypto/Hash/HMAC.py @@ -43,7 +43,7 @@ - the strength of the hash algorithm - the length and entropy of the secret key -This is an example showing how to *create* a MAC: +An example of possible usage is the following: >>> from Crypto.Hash import HMAC >>> @@ -52,22 +52,6 @@ >>> h.update(b'Hello') >>> print h.hexdigest() -This is an example showing how to *check* a MAC: - - >>> from Crypto.Hash import HMAC - >>> - >>> # We have received a message 'msg' together - >>> # with its MAC 'mac' - >>> - >>> secret = b'Swordfish' - >>> h = HMAC.new(secret) - >>> h.update(msg) - >>> try: - >>> h.verify(mac) - >>> print "The message '%s' is authentic" % msg - >>> except ValueError: - >>> print "The message or the key is wrong" - .. _RFC2104: http://www.ietf.org/rfc/rfc2104.txt .. _FIPS-198: http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf """ @@ -79,8 +63,6 @@ __all__ = ['new', 'digest_size', 'HMAC' ] -from binascii import unhexlify - from Crypto.Util.strxor import strxor_c from Crypto.Util.py3compat import * @@ -189,32 +171,12 @@ def digest(self): You can continue updating the object after calling this function. :Return: A byte string of `digest_size` bytes. It may contain non-ASCII - characters, including null bytes. + characters, including null bytes. """ - h = self.outer.copy() h.update(self.inner.digest()) return h.digest() - def verify(self, mac_tag): - """Verify that a given **binary** MAC (computed by another party) is valid. - - :Parameters: - mac_tag : byte string - The expected MAC of the message. - :Raises ValueError: - if the MAC does not match. It means that the message - has been tampered with or that the MAC key is incorrect. - """ - - mac = self.digest() - res = 0 - # Constant-time comparison - for x,y in zip(mac, mac_tag): - res |= bord(x) ^ bord(y) - if res or len(mac_tag)!=self.digest_size: - raise ValueError("MAC check failed") - def hexdigest(self): """Return the **printable** MAC of the message that has been authenticated so far. @@ -227,19 +189,6 @@ def hexdigest(self): return "".join(["%02x" % bord(x) for x in tuple(self.digest())]) - def hexverify(self, hex_mac_tag): - """Verify that a given **printable** MAC (computed by another party) is valid. - - :Parameters: - hex_mac_tag : string - The expected MAC of the message, as a hexadecimal string. - :Raises ValueError: - if the MAC does not match. It means that the message - has been tampered with or that the MAC key is incorrect. - """ - - self.verify(unhexlify(tobytes(hex_mac_tag))) - def new(key, msg = None, digestmod = None): """Create a new HMAC object. diff --git a/lib/Crypto/Hash/MD2.py b/lib/Crypto/Hash/MD2.py new file mode 100644 index 00000000..dac959e4 --- /dev/null +++ b/lib/Crypto/Hash/MD2.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""MD2 cryptographic hash algorithm. + +MD2 is specified in RFC1319_ and it produces the 128 bit digest of a message. + + >>> from Crypto.Hash import MD2 + >>> + >>> h = MD2.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +MD2 stand for Message Digest version 2, and it was invented by Rivest in 1989. + +This algorithm is both slow and insecure. Do not use it for new designs. + +.. _RFC1319: http://tools.ietf.org/html/rfc1319 +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'MD2Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +import Crypto.Hash._MD2 as _MD2 +hashFactory = _MD2 + +class MD2Hash(HashAlgo): + """Class that implements an MD2 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-md2 OBJECT IDENTIFIER ::= { + #: iso(1) member-body(2) us(840) rsadsi(113549) + #: digestAlgorithm(2) 2 + #: } + #: + #: This value uniquely identifies the MD2 algorithm. + oid = b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02') + + digest_size = 16 + block_size = 16 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return MD2Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `MD2Hash.update()`. + Optional. + + :Return: An `MD2Hash` object + """ + return MD2Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = MD2Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = MD2Hash.block_size + diff --git a/lib/Crypto/Hash/MD4.py b/lib/Crypto/Hash/MD4.py new file mode 100644 index 00000000..e28a2011 --- /dev/null +++ b/lib/Crypto/Hash/MD4.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""MD4 cryptographic hash algorithm. + +MD4 is specified in RFC1320_ and produces the 128 bit digest of a message. + + >>> from Crypto.Hash import MD4 + >>> + >>> h = MD4.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +MD4 stand for Message Digest version 4, and it was invented by Rivest in 1990. + +This algorithm is insecure. Do not use it for new designs. + +.. _RFC1320: http://tools.ietf.org/html/rfc1320 +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'MD4Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +import Crypto.Hash._MD4 as _MD4 +hashFactory = _MD4 + +class MD4Hash(HashAlgo): + """Class that implements an MD4 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-md2 OBJECT IDENTIFIER ::= { + #: iso(1) member-body(2) us(840) rsadsi(113549) + #: digestAlgorithm(2) 4 + #: } + #: + #: This value uniquely identifies the MD4 algorithm. + oid = b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x04') + + digest_size = 16 + block_size = 64 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return MD4Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `MD4Hash.update()`. + Optional. + + :Return: A `MD4Hash` object + """ + return MD4Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = MD4Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = MD4Hash.block_size + diff --git a/lib/Crypto/Hash/MD5.py b/lib/Crypto/Hash/MD5.py index c5df793b..18e9e7bf 100644 --- a/lib/Crypto/Hash/MD5.py +++ b/lib/Crypto/Hash/MD5.py @@ -35,58 +35,63 @@ .. _RFC1321: http://tools.ietf.org/html/rfc1321 """ -from __future__ import nested_scopes - _revision__ = "$Id$" -__all__ = ['new', 'block_size', 'digest_size'] +__all__ = ['new', 'digest_size', 'MD5Hash' ] from Crypto.Util.py3compat import * -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * - -def __make_constructor(): - try: - # The md5 module is deprecated in Python 2.6, so use hashlib when possible. - from hashlib import md5 as _hash_new - except ImportError: - from md5 import new as _hash_new - - h = _hash_new() - if hasattr(h, 'new') and hasattr(h, 'name') and hasattr(h, 'digest_size') and hasattr(h, 'block_size'): - # The module from stdlib has the API that we need. Just use it. - return _hash_new - else: - # Wrap the hash object in something that gives us the expected API. - _copy_sentinel = object() - class _MD5(object): - digest_size = 16 - block_size = 64 - name = "md5" - def __init__(self, *args): - if args and args[0] is _copy_sentinel: - self._h = args[1] - else: - self._h = _hash_new(*args) - def copy(self): - return _MD5(_copy_sentinel, self._h.copy()) - def update(self, *args): - f = self.update = self._h.update - f(*args) - def digest(self): - f = self.digest = self._h.digest - return f() - def hexdigest(self): - f = self.hexdigest = self._h.hexdigest - return f() - _MD5.new = _MD5 - return _MD5 - -new = __make_constructor() -del __make_constructor +from Crypto.Hash.hashalgo import HashAlgo + +try: + # The md5 module is deprecated in Python 2.6, so use hashlib when possible. + import hashlib + hashFactory = hashlib.md5 + +except ImportError: + import md5 + hashFactory = md5 + +class MD5Hash(HashAlgo): + """Class that implements an MD5 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-md5 OBJECT IDENTIFIER ::= { + #: iso(1) member-body(2) us(840) rsadsi(113549) + #: digestAlgorithm(2) 5 + #: } + #: + #: This value uniquely identifies the MD5 algorithm. + oid = b('\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05') + + digest_size = 16 + block_size = 64 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return MD5Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `MD5Hash.update()`. + Optional. + + :Return: A `MD5Hash` object + """ + return MD5Hash().new(data) #: The size of the resulting hash in bytes. -digest_size = new().digest_size +digest_size = MD5Hash.digest_size #: The internal block size of the hash algorithm in bytes. -block_size = new().block_size +block_size = MD5Hash.block_size + diff --git a/lib/Crypto/Hash/RIPEMD.py b/lib/Crypto/Hash/RIPEMD.py index 4e802358..33099cb8 100644 --- a/lib/Crypto/Hash/RIPEMD.py +++ b/lib/Crypto/Hash/RIPEMD.py @@ -18,9 +18,77 @@ # SOFTWARE. # =================================================================== -# This file exists for backward compatibility with old code that refers to -# Crypto.Hash.RIPEMD +"""RIPEMD-160 cryptographic hash algorithm. -"""Deprecated alias for `Crypto.Hash.RIPEMD160`""" +RIPEMD-160_ produces the 160 bit digest of a message. + + >>> from Crypto.Hash import RIPEMD + >>> + >>> h = RIPEMD.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +RIPEMD-160 stands for RACE Integrity Primitives Evaluation Message Digest +with a 160 bit digest. It was invented by Dobbertin, Bosselaers, and Preneel. + +This algorithm is considered secure, although it has not been scrutinized as +extensively as SHA-1. Moreover, it provides an informal security level of just +80bits. + +.. _RIPEMD-160: http://homes.esat.kuleuven.be/~bosselae/ripemd160.html +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'RIPEMD160Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +import Crypto.Hash._RIPEMD160 as _RIPEMD160 +hashFactory = _RIPEMD160 + +class RIPEMD160Hash(HashAlgo): + """Class that implements a RIPMD-160 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-ripemd160 OBJECT IDENTIFIER ::= { + #: iso(1) identified-organization(3) teletrust(36) + #: algorithm(3) hashAlgorithm(2) ripemd160(1) + #: } + #: + #: This value uniquely identifies the RIPMD-160 algorithm. + oid = b("\x06\x05\x2b\x24\x03\x02\x01") + + digest_size = 20 + block_size = 64 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return RIPEMD160Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `RIPEMD160Hash.update()`. + Optional. + + :Return: A `RIPEMD160Hash` object + """ + return RIPEMD160Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = RIPEMD160Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = RIPEMD160Hash.block_size -from Crypto.Hash.RIPEMD160 import new, block_size, digest_size diff --git a/lib/Crypto/Hash/SHA.py b/lib/Crypto/Hash/SHA.py index 0cc141c9..0bc59170 100644 --- a/lib/Crypto/Hash/SHA.py +++ b/lib/Crypto/Hash/SHA.py @@ -18,7 +18,81 @@ # SOFTWARE. # =================================================================== -# This file exists for backward compatibility with old code that refers to -# Crypto.Hash.SHA +"""SHA-1 cryptographic hash algorithm. + +SHA-1_ produces the 160 bit digest of a message. + + >>> from Crypto.Hash import SHA + >>> + >>> h = SHA.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +*SHA* stands for Secure Hash Algorithm. + +This algorithm is not considered secure. Do not use it for new designs. + +.. _SHA-1: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'SHA1Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +try: + # The sha module is deprecated in Python 2.6, so use hashlib when possible. + import hashlib + hashFactory = hashlib.sha1 + +except ImportError: + import sha + hashFactory = sha + +class SHA1Hash(HashAlgo): + """Class that implements a SHA-1 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-sha1 OBJECT IDENTIFIER ::= { + #: iso(1) identified-organization(3) oiw(14) secsig(3) + #: algorithms(2) 26 + #: } + #: + #: This value uniquely identifies the SHA-1 algorithm. + oid = b('\x06\x05\x2b\x0e\x03\x02\x1a') + + digest_size = 20 + block_size = 64 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return SHA1Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `SHA1Hash.update()`. + Optional. + + :Return: A `SHA1Hash` object + """ + return SHA1Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = SHA1Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = SHA1Hash.block_size + -from Crypto.Hash.SHA1 import __doc__, new, block_size, digest_size diff --git a/lib/Crypto/Hash/SHA1.py b/lib/Crypto/Hash/SHA1.py deleted file mode 100644 index 9ad9f1e7..00000000 --- a/lib/Crypto/Hash/SHA1.py +++ /dev/null @@ -1,92 +0,0 @@ -# -*- coding: utf-8 -*- -# -# =================================================================== -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# =================================================================== - -"""SHA-1 cryptographic hash algorithm. - -SHA-1_ produces the 160 bit digest of a message. - - >>> from Crypto.Hash import SHA1 - >>> - >>> h = SHA1.new() - >>> h.update(b'Hello') - >>> print h.hexdigest() - -*SHA* stands for Secure Hash Algorithm. - -This algorithm is not considered secure. Do not use it for new designs. - -.. _SHA-1: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf -""" - -from __future__ import nested_scopes - -_revision__ = "$Id$" - -__all__ = ['new', 'block_size', 'digest_size'] - -from Crypto.Util.py3compat import * -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * - -def __make_constructor(): - try: - # The sha module is deprecated in Python 2.6, so use hashlib when possible. - from hashlib import sha1 as _hash_new - except ImportError: - from sha import new as _hash_new - - h = _hash_new() - if hasattr(h, 'new') and hasattr(h, 'name') and hasattr(h, 'digest_size') and hasattr(h, 'block_size'): - # The module from stdlib has the API that we need. Just use it. - return _hash_new - else: - # Wrap the hash object in something that gives us the expected API. - _copy_sentinel = object() - class _SHA1(object): - digest_size = 20 - block_size = 64 - name = "sha1" - def __init__(self, *args): - if args and args[0] is _copy_sentinel: - self._h = args[1] - else: - self._h = _hash_new(*args) - def copy(self): - return _SHA1(_copy_sentinel, self._h.copy()) - def update(self, *args): - f = self.update = self._h.update - f(*args) - def digest(self): - f = self.digest = self._h.digest - return f() - def hexdigest(self): - f = self.hexdigest = self._h.hexdigest - return f() - _SHA1.new = _SHA1 - return _SHA1 - -new = __make_constructor() -del __make_constructor - -#: The size of the resulting hash in bytes. -digest_size = new().digest_size - -#: The internal block size of the hash algorithm in bytes. -block_size = new().block_size diff --git a/lib/Crypto/Hash/SHA224.py b/lib/Crypto/Hash/SHA224.py new file mode 100644 index 00000000..959b56da --- /dev/null +++ b/lib/Crypto/Hash/SHA224.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""SHA-224 cryptographic hash algorithm. + +SHA-224 belongs to the SHA-2_ family of cryptographic hashes. +It produces the 224 bit digest of a message. + + >>> from Crypto.Hash import SHA224 + >>> + >>> h = SHA224.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +*SHA* stands for Secure Hash Algorithm. + +.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'SHA224Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +try: + import hashlib + hashFactory = hashlib.sha224 + +except ImportError: + from Crypto.Hash import _SHA224 + hashFactory = _SHA224 + +class SHA224Hash(HashAlgo): + """Class that implements a SHA-224 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-sha224 OBJECT IDENTIFIER ::= { + #: joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) + #: nistalgorithm(4) hashalgs(2) 4 + #: } + #: + #: This value uniquely identifies the SHA-224 algorithm. + oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04') + + digest_size = 28 + block_size = 64 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return SHA224Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `SHA224Hash.update()`. + Optional. + + :Return: A `SHA224Hash` object + """ + return SHA224Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = SHA224Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = SHA224Hash.block_size + diff --git a/lib/Crypto/Hash/SHA256.py b/lib/Crypto/Hash/SHA256.py new file mode 100644 index 00000000..b0a99b31 --- /dev/null +++ b/lib/Crypto/Hash/SHA256.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""SHA-256 cryptographic hash algorithm. + +SHA-256 belongs to the SHA-2_ family of cryptographic hashes. +It produces the 256 bit digest of a message. + + >>> from Crypto.Hash import SHA256 + >>> + >>> h = SHA256.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +*SHA* stands for Secure Hash Algorithm. + +.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'SHA256Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +try: + import hashlib + hashFactory = hashlib.sha256 + +except ImportError: + from Crypto.Hash import _SHA256 + hashFactory = _SHA256 + +class SHA256Hash(HashAlgo): + """Class that implements a SHA-256 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-sha256 OBJECT IDENTIFIER ::= { + #: joint-iso-itu-t(2) country(16) us(840) organization(1) + #: gov(101) csor(3) nistalgorithm(4) hashalgs(2) 1 + #: } + #: + #: This value uniquely identifies the SHA-256 algorithm. + oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01') + + digest_size = 32 + block_size = 64 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return SHA256Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `SHA256Hash.update()`. + Optional. + + :Return: A `SHA256Hash` object + """ + return SHA256Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = SHA256Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = SHA256Hash.block_size + diff --git a/lib/Crypto/Hash/SHA384.py b/lib/Crypto/Hash/SHA384.py new file mode 100644 index 00000000..3490b021 --- /dev/null +++ b/lib/Crypto/Hash/SHA384.py @@ -0,0 +1,96 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""SHA-384 cryptographic hash algorithm. + +SHA-384 belongs to the SHA-2_ family of cryptographic hashes. +It produces the 384 bit digest of a message. + + >>> from Crypto.Hash import SHA384 + >>> + >>> h = SHA384.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +*SHA* stands for Secure Hash Algorithm. + +.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'SHA384Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +try: + import hashlib + hashFactory = hashlib.sha384 + +except ImportError: + from Crypto.Hash import _SHA384 + hashFactory = _SHA384 + +class SHA384Hash(HashAlgo): + """Class that implements a SHA-384 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-sha384 OBJECT IDENTIFIER ::= { + #: joint-iso-itu-t(2) country(16) us(840) organization(1) gov(101) csor(3) + #: nistalgorithm(4) hashalgs(2) 2 + #: } + #: + #: This value uniquely identifies the SHA-384 algorithm. + oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02') + + digest_size = 48 + block_size = 128 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return SHA384Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `SHA384Hash.update()`. + Optional. + + :Return: A `SHA384Hash` object + """ + return SHA384Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = SHA384Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = SHA384Hash.block_size + + diff --git a/lib/Crypto/Hash/SHA512.py b/lib/Crypto/Hash/SHA512.py new file mode 100644 index 00000000..d57548d3 --- /dev/null +++ b/lib/Crypto/Hash/SHA512.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +"""SHA-512 cryptographic hash algorithm. + +SHA-512 belongs to the SHA-2_ family of cryptographic hashes. +It produces the 512 bit digest of a message. + + >>> from Crypto.Hash import SHA512 + >>> + >>> h = SHA512.new() + >>> h.update(b'Hello') + >>> print h.hexdigest() + +*SHA* stands for Secure Hash Algorithm. + +.. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-2/fips180-2.pdf +""" + +_revision__ = "$Id$" + +__all__ = ['new', 'digest_size', 'SHA512Hash' ] + +from Crypto.Util.py3compat import * +from Crypto.Hash.hashalgo import HashAlgo + +try: + import hashlib + hashFactory = hashlib.sha512 + +except ImportError: + from Crypto.Hash import _SHA512 + hashFactory = _SHA512 + +class SHA512Hash(HashAlgo): + """Class that implements a SHA-512 hash + + :undocumented: block_size + """ + + #: ASN.1 Object identifier (OID):: + #: + #: id-sha512 OBJECT IDENTIFIER ::= { + #: joint-iso-itu-t(2) + #: country(16) us(840) organization(1) gov(101) csor(3) nistalgorithm(4) hashalgs(2) 3 + #: } + #: + #: This value uniquely identifies the SHA-512 algorithm. + oid = b('\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03') + + digest_size = 64 + block_size = 128 + + def __init__(self, data=None): + HashAlgo.__init__(self, hashFactory, data) + + def new(self, data=None): + return SHA512Hash(data) + +def new(data=None): + """Return a fresh instance of the hash object. + + :Parameters: + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `SHA512Hash.update()`. + Optional. + + :Return: A `SHA512Hash` object + """ + return SHA512Hash().new(data) + +#: The size of the resulting hash in bytes. +digest_size = SHA512Hash.digest_size + +#: The internal block size of the hash algorithm in bytes. +block_size = SHA512Hash.block_size + diff --git a/lib/Crypto/Hash/__init__.py b/lib/Crypto/Hash/__init__.py index f16e2534..4582c663 100644 --- a/lib/Crypto/Hash/__init__.py +++ b/lib/Crypto/Hash/__init__.py @@ -49,128 +49,8 @@ :undocumented: _MD2, _MD4, _RIPEMD160, _SHA224, _SHA256, _SHA384, _SHA512 """ -__all__ = ['HMAC', 'MD2', 'MD4', 'MD5', 'RIPEMD160', 'SHA1', - 'SHA224', 'SHA256', 'SHA384', 'SHA512', 'CMAC'] - +__all__ = ['HMAC', 'MD2', 'MD4', 'MD5', 'RIPEMD', 'SHA', + 'SHA224', 'SHA256', 'SHA384', 'SHA512'] __revision__ = "$Id$" -import sys -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * -from Crypto.Util.py3compat import * - -def new(algo, *args): - """Initialize a new hash object. - - The first argument to this function may be an algorithm name or another - hash object. - - This function has significant overhead. It's recommended that you instead - import and use the individual hash modules directly. - """ - - # Try just invoking algo.new() - # We do this first so that this is the fastest. - try: - new_func = algo.new - except AttributeError: - pass - else: - return new_func(*args) - - # Try getting the algorithm name. - if isinstance(algo, str): - name = algo - else: - try: - name = algo.name - except AttributeError: - raise ValueError("unsupported hash type %r" % (algo,)) - - # Got the name. Let's see if we have a PyCrypto implementation. - try: - new_func = _new_funcs[name] - except KeyError: - # No PyCrypto implementation. Try hashlib. - try: - import hashlib - except ImportError: - # There is no hashlib. - raise ValueError("unsupported hash type %s" % (name,)) - return hashlib.new(name, *args) - else: - # We have a PyCrypto implementation. Instantiate it. - return new_func(*args) - -# This dict originally gets the following _*_new methods, but its members get -# replaced with the real new() methods of the various hash modules as they are -# used. We do it without locks to improve performance, which is safe in -# CPython because dict access is atomic in CPython. This might break PyPI. -_new_funcs = {} - -def _md2_new(*args): - from Crypto.Hash import MD2 - _new_funcs['MD2'] = _new_funcs['md2'] = MD2.new - return MD2.new(*args) -_new_funcs['MD2'] = _new_funcs['md2'] = _md2_new -del _md2_new - -def _md4_new(*args): - from Crypto.Hash import MD4 - _new_funcs['MD4'] = _new_funcs['md4'] = MD4.new - return MD4.new(*args) -_new_funcs['MD4'] = _new_funcs['md4'] = _md4_new -del _md4_new - -def _md5_new(*args): - from Crypto.Hash import MD5 - _new_funcs['MD5'] = _new_funcs['md5'] = MD5.new - return MD5.new(*args) -_new_funcs['MD5'] = _new_funcs['md5'] = _md5_new -del _md5_new - -def _ripemd160_new(*args): - from Crypto.Hash import RIPEMD160 - _new_funcs['RIPEMD160'] = _new_funcs['ripemd160'] = \ - _new_funcs['RIPEMD'] = _new_funcs['ripemd'] = RIPEMD160.new - return RIPEMD160.new(*args) -_new_funcs['RIPEMD160'] = _new_funcs['ripemd160'] = \ - _new_funcs['RIPEMD'] = _new_funcs['ripemd'] = _ripemd160_new -del _ripemd160_new - -def _sha1_new(*args): - from Crypto.Hash import SHA1 - _new_funcs['SHA1'] = _new_funcs['sha1'] = \ - _new_funcs['SHA'] = _new_funcs['sha'] = SHA1.new - return SHA1.new(*args) -_new_funcs['SHA1'] = _new_funcs['sha1'] = \ - _new_funcs['SHA'] = _new_funcs['sha'] = _sha1_new -del _sha1_new - -def _sha224_new(*args): - from Crypto.Hash import SHA224 - _new_funcs['SHA224'] = _new_funcs['sha224'] = SHA224.new - return SHA224.new(*args) -_new_funcs['SHA224'] = _new_funcs['sha224'] = _sha224_new -del _sha224_new - -def _sha256_new(*args): - from Crypto.Hash import SHA256 - _new_funcs['SHA256'] = _new_funcs['sha256'] = SHA256.new - return SHA256.new(*args) -_new_funcs['SHA256'] = _new_funcs['sha256'] = _sha256_new -del _sha256_new - -def _sha384_new(*args): - from Crypto.Hash import SHA384 - _new_funcs['SHA384'] = _new_funcs['sha384'] = SHA384.new - return SHA384.new(*args) -_new_funcs['SHA384'] = _new_funcs['sha384'] = _sha384_new -del _sha384_new -def _sha512_new(*args): - from Crypto.Hash import SHA512 - _new_funcs['SHA512'] = _new_funcs['sha512'] = SHA512.new - return SHA512.new(*args) -_new_funcs['SHA512'] = _new_funcs['sha512'] = _sha512_new -del _sha512_new diff --git a/lib/Crypto/Hash/hashalgo.py b/lib/Crypto/Hash/hashalgo.py new file mode 100644 index 00000000..b38b3a6c --- /dev/null +++ b/lib/Crypto/Hash/hashalgo.py @@ -0,0 +1,116 @@ +# -*- coding: utf-8 -*- +# +# =================================================================== +# The contents of this file are dedicated to the public domain. To +# the extent that dedication to the public domain is not available, +# everyone is granted a worldwide, perpetual, royalty-free, +# non-exclusive license to exercise all rights associated with the +# contents of this file for any purpose whatsoever. +# No rights are reserved. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +# =================================================================== + +from binascii import hexlify + +class HashAlgo: + """A generic class for an abstract cryptographic hash algorithm. + + :undocumented: block_size + """ + + #: The size of the resulting hash in bytes. + digest_size = None + #: The internal block size of the hash algorithm in bytes. + block_size = None + + def __init__(self, hashFactory, data=None): + """Initialize the hash object. + + :Parameters: + hashFactory : callable + An object that will generate the actual hash implementation. + *hashFactory* must have a *new()* method, or must be directly + callable. + data : byte string + The very first chunk of the message to hash. + It is equivalent to an early call to `update()`. + """ + if hasattr(hashFactory, 'new'): + self._hash = hashFactory.new() + else: + self._hash = hashFactory() + if data: + self.update(data) + + def update(self, data): + """Continue hashing of a message by consuming the next chunk of data. + + Repeated calls are equivalent to a single call with the concatenation + of all the arguments. In other words: + + >>> m.update(a); m.update(b) + + is equivalent to: + + >>> m.update(a+b) + + :Parameters: + data : byte string + The next chunk of the message being hashed. + """ + return self._hash.update(data) + + def digest(self): + """Return the **binary** (non-printable) digest of the message that has been hashed so far. + + This method does not change the state of the hash object. + You can continue updating the object after calling this function. + + :Return: A byte string of `digest_size` bytes. It may contain non-ASCII + characters, including null bytes. + """ + return self._hash.digest() + + def hexdigest(self): + """Return the **printable** digest of the message that has been hashed so far. + + This method does not change the state of the hash object. + + :Return: A string of 2* `digest_size` characters. It contains only + hexadecimal ASCII digits. + """ + return self._hash.hexdigest() + + def copy(self): + """Return a copy ("clone") of the hash object. + + The copy will have the same internal state as the original hash + object. + This can be used to efficiently compute the digests of strings that + share a common initial substring. + + :Return: A hash object of the same type + """ + return self._hash.copy() + + def new(self, data=None): + """Return a fresh instance of the hash object. + + Unlike the `copy` method, the internal state of the object is empty. + + :Parameters: + data : byte string + The next chunk of the message being hashed. + + :Return: A hash object of the same type + """ + pass + diff --git a/lib/Crypto/IO/PEM.py b/lib/Crypto/IO/PEM.py deleted file mode 100644 index 89a56899..00000000 --- a/lib/Crypto/IO/PEM.py +++ /dev/null @@ -1,163 +0,0 @@ -# -*- coding: ascii -*- -# -# Util/PEM.py : Privacy Enhanced Mail utilities -# -# =================================================================== -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# =================================================================== -"""Set of functions for encapsulating data according to the PEM format. - -PEM (Privacy Enhanced Mail) was an IETF standard for securing emails via a -Public Key Infrastructure. It is specified in RFC 1421-1424. - -Even though it has been abandoned, the simple message encapsulation it defined -is still widely used today for encoding *binary* cryptographic objects like -keys and certificates into text. -""" - -__all__ = ['encode', 'decode'] - -import sys -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * -from Crypto.Util.py3compat import * - -import re -from binascii import hexlify, unhexlify, a2b_base64, b2a_base64 - -from Crypto.Hash import MD5 -from Crypto.Util.Padding import pad, unpad -from Crypto.Cipher import DES, DES3, AES -from Crypto.Protocol.KDF import PBKDF1 -from Crypto.Random import get_random_bytes - - -def encode(data, marker, passphrase=None, randfunc=None): - """Encode a piece of binary data into PEM format. - - :Parameters: - data : byte string - The piece of binary data to encode. - marker : string - The marker for the PEM block (e.g. "PUBLIC KEY"). - Note that there is no official master list for all allowed markers. - Still, you can refer to the OpenSSL_ source code. - passphrase : byte string - If given, the PEM block will be encrypted. The key is derived from - the passphrase. - randfunc : callable - Random number generation function; it accepts an integer N and returns - a byte string of random data, N bytes long. If not given, a new one is - instantiated. - :Returns: - The PEM block, as a string. - - .. _OpenSSL: http://cvs.openssl.org/fileview?f=openssl/crypto/pem/pem.h&v=1.66.2.1.4.2 - """ - - if randfunc is None: - randfunc = get_random_bytes - - out = "-----BEGIN %s-----\n" % marker - if passphrase: - # We only support 3DES for encryption - salt = randfunc(8) - key = PBKDF1(passphrase, salt, 16, 1, MD5) - key += PBKDF1(key + passphrase, salt, 8, 1, MD5) - objenc = DES3.new(key, DES3.MODE_CBC, salt) - out += "Proc-Type: 4,ENCRYPTED\nDEK-Info: DES-EDE3-CBC,%s\n\n" %\ - tostr(hexlify(salt).upper()) - # Encrypt with PKCS#7 padding - data = objenc.encrypt(pad(data, objenc.block_size)) - - # Each BASE64 line can take up to 64 characters (=48 bytes of data) - # b2a_base64 adds a new line character! - chunks = [tostr(b2a_base64(data[i:i + 48])) - for i in range(0, len(data), 48)] - out += "".join(chunks) - out += "-----END %s-----" % marker - return out - - -def decode(pem_data, passphrase=None): - """Decode a PEM block into binary. - - :Parameters: - pem_data : string - The PEM block. - passphrase : byte string - If given and the PEM block is encrypted, - the key will be derived from the passphrase. - :Returns: - A tuple with the binary data, the marker string, and a boolean to - indicate if decryption was performed. - :Raises ValueError: - If decoding fails, if the PEM file is encrypted and no passphrase has - been provided or if the passphrase is incorrect. - """ - - # Verify Pre-Encapsulation Boundary - r = re.compile("\s*-----BEGIN (.*)-----\n") - m = r.match(pem_data) - if not m: - raise ValueError("Not a valid PEM pre boundary") - marker = m.group(1) - - # Verify Post-Encapsulation Boundary - r = re.compile("-----END (.*)-----\s*$") - m = r.search(pem_data) - if not m or m.group(1) != marker: - raise ValueError("Not a valid PEM post boundary") - - # Removes spaces and slit on lines - lines = pem_data.replace(" ", '').split() - - # Decrypts, if necessary - if lines[1].startswith('Proc-Type:4,ENCRYPTED'): - if not passphrase: - raise ValueError("PEM is encrypted, but no passphrase available") - DEK = lines[2].split(':') - if len(DEK) != 2 or DEK[0] != 'DEK-Info': - raise ValueError("PEM encryption format not supported.") - algo, salt = DEK[1].split(',') - salt = unhexlify(tobytes(salt)) - if algo == "DES-CBC": - # This is EVP_BytesToKey in OpenSSL - key = PBKDF1(passphrase, salt, 8, 1, MD5) - objdec = DES.new(key, DES.MODE_CBC, salt) - elif algo == "DES-EDE3-CBC": - # Note that EVP_BytesToKey is note exactly the same as PBKDF1 - key = PBKDF1(passphrase, salt, 16, 1, MD5) - key += PBKDF1(key + passphrase, salt, 8, 1, MD5) - objdec = DES3.new(key, DES3.MODE_CBC, salt) - elif algo == "AES-128-CBC": - key = PBKDF1(passphrase, salt[:8], 16, 1, MD5) - objdec = AES.new(key, AES.MODE_CBC, salt) - else: - raise ValueError("Unsupport PEM encryption algorithm.") - lines = lines[2:] - else: - objdec = None - - # Decode body - data = a2b_base64(b(''.join(lines[1:-1]))) - enc_flag = False - if objdec: - data = unpad(objdec.decrypt(data), objdec.block_size) - enc_flag = True - - return (data, marker, enc_flag) diff --git a/lib/Crypto/IO/PKCS8.py b/lib/Crypto/IO/PKCS8.py deleted file mode 100644 index ceb0f5a4..00000000 --- a/lib/Crypto/IO/PKCS8.py +++ /dev/null @@ -1,209 +0,0 @@ -# -*- coding: utf-8 -*- -# -# PublicKey/PKCS8.py : PKCS#8 functions -# -# =================================================================== -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# =================================================================== -""" -Module for handling private keys wrapped according to `PKCS#8`_. - -PKCS8 is a standard for storing and transferring private key information. -The wrapped key can either be clear or encrypted. - -All encryption algorithms are based on passphrase-based key derivation. -The following mechanisms are fully supported: - -* *PBKDF2WithHMAC-SHA1AndAES128-CBC* -* *PBKDF2WithHMAC-SHA1AndAES192-CBC* -* *PBKDF2WithHMAC-SHA1AndAES256-CBC* -* *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC* - -The following mechanisms are only supported for importing keys. -They are much weaker than the ones listed above, and they are provided -for backward compatibility only: - -* *pbeWithMD5AndRC2-CBC* -* *pbeWithMD5AndDES-CBC* -* *pbeWithSHA1AndRC2-CBC* -* *pbeWithSHA1AndDES-CBC* - -.. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt - -""" - -import sys - -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * -from Crypto.Util.py3compat import * - -from Crypto.Util.asn1 import * - -from Crypto.IO._PBES import PBES1, PBES2 - -__all__ = ['wrap', 'unwrap'] - - -def decode_der(obj_class, binstr): - """Instantiate a DER object class, decode a DER binary string in it, and - return the object.""" - der = obj_class() - der.decode(binstr) - return der - - -def wrap(private_key, key_oid, passphrase=None, protection=None, - prot_params=None, key_params=None, randfunc=None): - """Wrap a private key into a PKCS#8 blob (clear or encrypted). - - :Parameters: - - private_key : byte string - The private key encoded in binary form. The actual encoding is - algorithm specific. In most cases, it is DER. - - key_oid : string - The object identifier (OID) of the private key to wrap. - It is a dotted string, like "``1.2.840.113549.1.1.1``" (for RSA keys). - - passphrase : (binary) string - The secret passphrase from which the wrapping key is derived. - Set it only if encryption is required. - - protection : string - The identifier of the algorithm to use for securely wrapping the key. - The default value is '``PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC``'. - - prot_params : dictionary - Parameters for the protection algorithm. - - +------------------+-----------------------------------------------+ - | Key | Description | - +==================+===============================================+ - | iteration_count | The KDF algorithm is repeated several times to| - | | slow down brute force attacks on passwords. | - | | The default value is 1 000. | - +------------------+-----------------------------------------------+ - | salt_size | Salt is used to thwart dictionary and rainbow | - | | attacks on passwords. The default value is 8 | - | | bytes. | - +------------------+-----------------------------------------------+ - - key_params : DER object - The algorithm parameters associated to the private key. - It is required for algorithms like DSA, but not for others like RSA. - - randfunc : callable - Random number generation function; it should accept a single integer - N and return a string of random data, N bytes long. - If not specified, a new RNG will be instantiated - from ``Crypto.Random``. - - :Return: - The PKCS#8-wrapped private key (possibly encrypted), - as a binary string. - """ - - if key_params is None: - key_params = DerNull() - - # - # PrivateKeyInfo ::= SEQUENCE { - # version Version, - # privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - # privateKey PrivateKey, - # attributes [0] IMPLICIT Attributes OPTIONAL - # } - # - pk_info = newDerSequence( - 0, - newDerSequence( - DerObjectId(key_oid), - key_params - ), - newDerOctetString(private_key) - ) - pk_info_der = pk_info.encode() - - if not passphrase: - return pk_info_der - - # Encryption with PBES2 - passphrase = tobytes(passphrase) - if protection is None: - protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC' - return PBES2.encrypt(pk_info_der, passphrase, - protection, prot_params, randfunc) - - -def unwrap(p8_private_key, passphrase=None): - """Unwrap a private key from a PKCS#8 blob (clear or encrypted). - - :Parameters: - p8_private_key : byte string - The private key wrapped into a PKCS#8 blob - passphrase : (byte) string - The passphrase to use to decrypt the blob (if it is encrypted). - :Return: - A tuple containing: - - #. the algorithm identifier of the wrapped key (OID, dotted string) - #. the private key (byte string, DER encoded) - #. the associated parameters (byte string, DER encoded) or ``None`` - - :Raises ValueError: - If decoding fails - """ - - if passphrase: - passphrase = tobytes(passphrase) - found = False - for pbes in PBES1, PBES2: - try: - p8_private_key = pbes.decrypt(p8_private_key, passphrase) - except ValueError: - pass - else: - found = True - break - if not found: - raise ValueError("Unsupported PKCS#5 Object ID ") - - pk_info = decode_der(DerSequence, p8_private_key) - if len(pk_info) == 2 and not passphrase: - raise ValueError("Not a valid clear PKCS#8 structure " - "(maybe it is encrypted?)") - if not 3 <= len(pk_info) <= 4 or pk_info[0] != 0: - raise ValueError("Not a valid PrivateKeyInfo SEQUENCE") - - # - # AlgorithmIdentifier ::= SEQUENCE { - # algorithm OBJECT IDENTIFIER, - # parameters ANY DEFINED BY algorithm OPTIONAL - # } - # - algo_id = decode_der(DerSequence, pk_info[1]) - if not 1 <= len(algo_id) <= 2: - raise ValueError("Not a valid AlgorithmIdentifier SEQUENCE") - algo = decode_der(DerObjectId, algo_id[0]).value - private_key = decode_der(DerOctetString, pk_info[2]).payload - if len(algo_id) == 2 and algo_id[1] != b('\x05\x00'): - params = algo_id[1] - else: - params = None - return (algo, private_key, params) diff --git a/lib/Crypto/IO/_PBES.py b/lib/Crypto/IO/_PBES.py deleted file mode 100644 index 42d5dbc7..00000000 --- a/lib/Crypto/IO/_PBES.py +++ /dev/null @@ -1,348 +0,0 @@ -# -# PublicKey/_PBES.py : Password-Based Encryption functions -# -# =================================================================== -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# =================================================================== - -import sys -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * -from Crypto.Util.py3compat import * - -from Crypto import Random -from Crypto.Util.asn1 import * - -from Crypto.Util.Padding import pad, unpad -from Crypto.Hash import MD5, SHA1 -from Crypto.Cipher import DES, ARC2, DES3, AES -from Crypto.Protocol.KDF import PBKDF1, PBKDF2 - - -# These are the ASN.1 definitions used by the PBES1/2 logic: -# -# EncryptedPrivateKeyInfo ::= SEQUENCE { -# encryptionAlgorithm EncryptionAlgorithmIdentifier, -# encryptedData EncryptedData -# } -# -# EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier -# -# EncryptedData ::= OCTET STRING -# -# AlgorithmIdentifier ::= SEQUENCE { -# algorithm OBJECT IDENTIFIER, -# parameters ANY DEFINED BY algorithm OPTIONAL -# } -# -# PBEParameter ::= SEQUENCE { -# salt OCTET STRING (SIZE(8)), -# iterationCount INTEGER -# } -# -# PBES2-params ::= SEQUENCE { -# keyDerivationFunc AlgorithmIdentifier {{PBES2-KDFs}}, -# encryptionScheme AlgorithmIdentifier {{PBES2-Encs}} -# } -# -# PBKDF2-params ::= SEQUENCE { -# salt CHOICE { -# specified OCTET STRING, -# otherSource AlgorithmIdentifier {{PBKDF2-SaltSources}} -# }, -# iterationCount INTEGER (1..MAX), -# keyLength INTEGER (1..MAX) OPTIONAL, -# prf AlgorithmIdentifier {{PBKDF2-PRFs}} DEFAULT algid-hmacWithSHA1 -# } -# - - -def decode_der(obj_class, binstr): - """Instantiate a DER object class, decode a DER binary string in it, and - return the object.""" - der = obj_class() - der.decode(binstr) - return der - - -class PBES1(object): - """Deprecated encryption scheme with password-based key derivation - (originally defined in PKCS#5 v1.5, but still present in `v2.0`__). - - .. __: http://www.ietf.org/rfc/rfc2898.txt - """ - - def decrypt(data, passphrase): - """Decrypt a piece of data using a passphrase and *PBES1*. - - The algorithm to use is automatically detected. - - :Parameters: - data : byte string - The piece of data to decrypt. - passphrase : byte string - The passphrase to use for decrypting the data. - :Returns: - The decrypted data, as a binary string. - """ - - encrypted_private_key_info = decode_der(DerSequence, data) - encrypted_algorithm = decode_der( - DerSequence, - encrypted_private_key_info[0] - ) - encrypted_data = decode_der( - DerOctetString, - encrypted_private_key_info[1] - ).payload - - pbe_oid = decode_der(DerObjectId, encrypted_algorithm[0]).value - cipher_params = {} - if pbe_oid == "1.2.840.113549.1.5.3": - # PBE_MD5_DES_CBC - hashmod = MD5 - ciphermod = DES - elif pbe_oid == "1.2.840.113549.1.5.6": - # PBE_MD5_RC2_CBC - hashmod = MD5 - ciphermod = ARC2 - cipher_params['effective_keylen'] = 64 - elif pbe_oid == "1.2.840.113549.1.5.10": - # PBE_SHA1_DES_CBC - hashmod = SHA1 - ciphermod = DES - elif pbe_oid == "1.2.840.113549.1.5.11": - # PBE_SHA1_RC2_CBC - hashmod = SHA1 - ciphermod = ARC2 - cipher_params['effective_keylen'] = 64 - else: - raise ValueError("Unknown OID") - - pbe_params = decode_der(DerSequence, encrypted_algorithm[1]) - salt = decode_der(DerOctetString, pbe_params[0]).payload - iterations = pbe_params[1] - - key_iv = PBKDF1(passphrase, salt, 16, iterations, hashmod) - key, iv = key_iv[:8], key_iv[8:] - - cipher = ciphermod.new(key, ciphermod.MODE_CBC, iv, **cipher_params) - pt = cipher.decrypt(encrypted_data) - return unpad(pt, cipher.block_size) - decrypt = staticmethod(decrypt) - - -class PBES2(object): - """Encryption scheme with password-based key derivation - (defined in `PKCS#5 v2.0`__). - - .. __: http://www.ietf.org/rfc/rfc2898.txt.""" - - def encrypt(data, passphrase, protection, prot_params=None, randfunc=None): - """Encrypt a piece of data using a passphrase and *PBES2*. - - :Parameters: - data : byte string - The piece of data to encrypt. - passphrase : byte string - The passphrase to use for encrypting the data. - protection : string - The identifier of the encryption algorithm to use. - The default value is '``PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC``'. - prot_params : dictionary - Parameters of the protection algorithm. - - +------------------+-----------------------------------------------+ - | Key | Description | - +==================+===============================================+ - | iteration_count | The KDF algorithm is repeated several times to| - | | slow down brute force attacks on passwords. | - | | The default value is 1 000. | - +------------------+-----------------------------------------------+ - | salt_size | Salt is used to thwart dictionary and rainbow | - | | attacks on passwords. The default value is 8 | - | | bytes. | - +------------------+-----------------------------------------------+ - - randfunc : callable - Random number generation function; it should accept - a single integer N and return a string of random data, - N bytes long. If not specified, a new RNG will be - instantiated from ``Crypto.Random``. - - :Returns: - The encrypted data, as a binary string. - """ - - if prot_params is None: - prot_params = {} - - if randfunc is None: - randfunc = Random.new().read - - if protection == 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC': - key_size = 24 - module = DES3 - protection = DES3.MODE_CBC - enc_oid = "1.2.840.113549.3.7" - elif protection == 'PBKDF2WithHMAC-SHA1AndAES128-CBC': - key_size = 16 - module = AES - protection = AES.MODE_CBC - enc_oid = "2.16.840.1.101.3.4.1.2" - elif protection == 'PBKDF2WithHMAC-SHA1AndAES192-CBC': - key_size = 24 - module = AES - protection = AES.MODE_CBC - enc_oid = "2.16.840.1.101.3.4.1.22" - elif protection == 'PBKDF2WithHMAC-SHA1AndAES256-CBC': - key_size = 32 - module = AES - protection = AES.MODE_CBC - enc_oid = "2.16.840.1.101.3.4.1.42" - else: - raise ValueError("Unknown mode") - - # Get random data - iv = randfunc(module.block_size) - salt = randfunc(prot_params.get("salt_size", 8)) - - # Derive key from password - count = prot_params.get("iteration_count", 1000) - key = PBKDF2(passphrase, salt, key_size, count) - key_derivation_func = newDerSequence( - DerObjectId("1.2.840.113549.1.5.12"), # PBKDF2 - newDerSequence( - DerOctetString(salt), - DerInteger(count) - ) - ) - - # Create cipher and use it - cipher = module.new(key, protection, iv) - encrypted_data = cipher.encrypt(pad(data, cipher.block_size)) - encryption_scheme = newDerSequence( - DerObjectId(enc_oid), - DerOctetString(iv) - ) - - # Result - encrypted_private_key_info = newDerSequence( - # encryptionAlgorithm - newDerSequence( - DerObjectId("1.2.840.113549.1.5.13"), # PBES2 - newDerSequence( - key_derivation_func, - encryption_scheme - ), - ), - DerOctetString(encrypted_data) - ) - return encrypted_private_key_info.encode() - encrypt = staticmethod(encrypt) - - def decrypt(data, passphrase): - """Decrypt a piece of data using a passphrase and *PBES2*. - - The algorithm to use is automatically detected. - - :Parameters: - data : byte string - The piece of data to decrypt. - passphrase : byte string - The passphrase to use for decrypting the data. - :Returns: - The decrypted data, as a binary string. - """ - - encrypted_private_key_info = decode_der(DerSequence, data) - encryption_algorithm = decode_der( - DerSequence, - encrypted_private_key_info[0] - ) - encrypted_data = decode_der( - DerOctetString, - encrypted_private_key_info[1] - ).payload - - pbe_oid = decode_der(DerObjectId, encryption_algorithm[0]).value - if pbe_oid != "1.2.840.113549.1.5.13": - raise ValueError("Not a PBES2 object") - - pbes2_params = decode_der(DerSequence, encryption_algorithm[1]) - - ### Key Derivation Function selection - key_derivation_func = decode_der(DerSequence, pbes2_params[0]) - key_derivation_oid = decode_der( - DerObjectId, - key_derivation_func[0] - ).value - - # For now, we only support PBKDF2 - if key_derivation_oid != "1.2.840.113549.1.5.12": - raise ValueError("Unknown KDF") - - pbkdf2_params = decode_der(DerSequence, key_derivation_func[1]) - salt = decode_der(DerOctetString, pbkdf2_params[0]).payload - iteration_count = pbkdf2_params[1] - if len(pbkdf2_params) > 2: - pbkdf2_key_length = pbkdf2_params[2] - else: - pbkdf2_key_length = None - if len(pbkdf2_params) > 3: - raise ValueError("Unsupported PRF for PBKDF2") - - ### Cipher selection - encryption_scheme = decode_der(DerSequence, pbes2_params[1]) - encryption_oid = decode_der( - DerObjectId, - encryption_scheme[0] - ).value - - if encryption_oid == "1.2.840.113549.3.7": - # DES_EDE3_CBC - ciphermod = DES3 - key_size = 24 - elif encryption_oid == "2.16.840.1.101.3.4.1.2": - # AES128_CBC - ciphermod = AES - key_size = 16 - elif encryption_oid == "2.16.840.1.101.3.4.1.22": - # AES192_CBC - ciphermod = AES - key_size = 24 - elif encryption_oid == "2.16.840.1.101.3.4.1.42": - # AES256_CBC - ciphermod = AES - key_size = 32 - else: - raise ValueError("Unsupported cipher") - - if pbkdf2_key_length and pbkdf2_key_length != key_size: - raise ValueError("Mismatch between PBKDF2 parameters" - " and selected cipher") - - IV = decode_der(DerOctetString, encryption_scheme[1]).payload - - # Create cipher - key = PBKDF2(passphrase, salt, key_size, iteration_count) - cipher = ciphermod.new(key, ciphermod.MODE_CBC, IV) - - # Decrypt data - pt = cipher.decrypt(encrypted_data) - return unpad(pt, cipher.block_size) - decrypt = staticmethod(decrypt) diff --git a/lib/Crypto/IO/__init__.py b/lib/Crypto/IO/__init__.py deleted file mode 100644 index 86776c49..00000000 --- a/lib/Crypto/IO/__init__.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# -# =================================================================== -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# =================================================================== - -""" -Modules for reading and writing cryptographic data. - -======================== ============================================= -Module Description -======================== ============================================= -Crypto.Util.PEM Set of functions for encapsulating data according to the PEM format. -Crypto.Util.PKCS8 Set of functions for wrapping/unwrapping private keys. -======================== ============================================= -""" - -__all__ = ['PEM', 'PKCS8'] diff --git a/lib/Crypto/Protocol/KDF.py b/lib/Crypto/Protocol/KDF.py index c5967e4d..973b7aff 100644 --- a/lib/Crypto/Protocol/KDF.py +++ b/lib/Crypto/Protocol/KDF.py @@ -38,21 +38,16 @@ import math import struct -import sys -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * - -from Crypto.Hash import SHA1, HMAC, CMAC +from Crypto.Hash import SHA as SHA1, HMAC from Crypto.Util.strxor import strxor -from Crypto.Util.number import long_to_bytes, bytes_to_long def PBKDF1(password, salt, dkLen, count=1000, hashAlgo=None): """Derive one key from a password (or passphrase). This function performs key derivation according an old version of the PKCS#5 standard (v1.5). - + This algorithm is called ``PBKDF1``. Even though it is still described in the latest version of the PKCS#5 standard (version 2, or RFC2898), newer applications should use the more secure and versatile `PBKDF2` instead. @@ -81,7 +76,7 @@ def PBKDF1(password, salt, dkLen, count=1000, hashAlgo=None): pHash = hashAlgo.new(password+salt) digest = pHash.digest_size if dkLen>digest: - raise TypeError("Selected hash algorithm has a too short digest (%d bytes)." % digest) + raise ValueError("Selected hash algorithm has a too short digest (%d bytes)." % digest) if len(salt)!=8: raise ValueError("Salt is not 8 bytes long.") for i in xrange(count-1): @@ -126,84 +121,3 @@ def PBKDF2(password, salt, dkLen=16, count=1000, prf=None): i = i + 1 return key[:dkLen] -class _S2V(object): - """String-to-vector PRF as defined in `RFC5297`_. - - This class implements a pseudorandom function family - based on CMAC that takes as input a vector of strings. - - .. _RFC5297: http://tools.ietf.org/html/rfc5297 - """ - - def __init__(self, key, ciphermod): - """Initialize the S2V PRF. - - :Parameters: - key : byte string - A secret that can be used as key for CMACs - based on ciphers from ``ciphermod``. - ciphermod : module - A block cipher module from `Crypto.Cipher`. - """ - - self._key = key - self._ciphermod = ciphermod - self._last_string = self._cache = bchr(0)*ciphermod.block_size - self._n_updates = ciphermod.block_size*8-1 - - def new(key, ciphermod): - """Create a new S2V PRF. - - :Parameters: - key : byte string - A secret that can be used as key for CMACs - based on ciphers from ``ciphermod``. - ciphermod : module - A block cipher module from `Crypto.Cipher`. - """ - return _S2V(key, ciphermod) - new = staticmethod(new) - - def _double(self, bs): - doubled = bytes_to_long(bs)<<1 - if bord(bs[0]) & 0x80: - doubled ^= 0x87 - return long_to_bytes(doubled, len(bs))[-len(bs):] - - def update(self, item): - """Pass the next component of the vector. - - The maximum number of components you can pass is equal to the block - length of the cipher (in bits) minus 1. - - :Parameters: - item : byte string - The next component of the vector. - :Raise TypeError: when the limit on the number of components has been reached. - :Raise ValueError: when the component is empty - """ - - if not item: - raise ValueError("A component cannot be empty") - - if self._n_updates==0: - raise TypeError("Too many components passed to S2V") - self._n_updates -= 1 - - mac = CMAC.new(self._key, msg=self._last_string, ciphermod=self._ciphermod) - self._cache = strxor(self._double(self._cache), mac.digest()) - self._last_string = item - - def derive(self): - """"Derive a secret from the vector of components. - - :Return: a byte string, as long as the block length of the cipher. - """ - - if len(self._last_string)>=16: - final = self._last_string[:-16] + strxor(self._last_string[-16:], self._cache) - else: - padded = (self._last_string + bchr(0x80)+ bchr(0)*15)[:16] - final = strxor(padded, self._double(self._cache)) - mac = CMAC.new(self._key, msg=final, ciphermod=self._ciphermod) - return mac.digest() diff --git a/lib/Crypto/PublicKey/DSA.py b/lib/Crypto/PublicKey/DSA.py index a5d6f118..d6bffd67 100644 --- a/lib/Crypto/PublicKey/DSA.py +++ b/lib/Crypto/PublicKey/DSA.py @@ -59,20 +59,14 @@ >>> from Crypto.Random import random >>> from Crypto.PublicKey import DSA - >>> from Crypto.Hash import SHA256 + >>> from Crypto.Hash import SHA >>> >>> message = "Hello" - >>> key = DSA.generate(2048) - >>> f = open("public_key.pem", "w") - >>> f.write(key.publickey().exportKey(key)) - >>> h = SHA256.new(message).digest() + >>> key = DSA.generate(1024) + >>> h = SHA.new(message).digest() >>> k = random.StrongRandom().randint(1,key.q-1) >>> sig = key.sign(h,k) >>> ... - >>> ... - >>> f = open("public_key.pem", "r") - >>> h = SHA256.new(message).digest() - >>> key = DSA.importKey(f.read()) >>> if key.verify(h,sig): >>> print "OK" >>> else: @@ -85,64 +79,20 @@ __revision__ = "$Id$" -__all__ = ['generate', 'construct', 'error', 'DSAImplementation', - '_DSAobj', 'importKey'] - -import binascii -import struct +__all__ = ['generate', 'construct', 'error', 'DSAImplementation', '_DSAobj'] import sys if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * -from Crypto.Util.py3compat import * -from Crypto import Random -from Crypto.IO import PKCS8, PEM -from Crypto.Util.number import bytes_to_long, long_to_bytes, getRandomRange from Crypto.PublicKey import _DSA, _slowmath, pubkey -from Crypto.Util.asn1 import DerObject, DerSequence,\ - DerInteger, DerObjectId, DerBitString, newDerSequence, newDerBitString +from Crypto import Random try: from Crypto.PublicKey import _fastmath except ImportError: _fastmath = None -def decode_der(obj_class, binstr): - """Instantiate a DER object class, decode a DER binary string in it, - and return the object.""" - der = obj_class() - der.decode(binstr) - return der - -# ; The following ASN.1 types are relevant for DSA -# -# SubjectPublicKeyInfo ::= SEQUENCE { -# algorithm AlgorithmIdentifier, -# subjectPublicKey BIT STRING -# } -# -# id-dsa ID ::= { iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 1 } -# -# ; See RFC3279 -# Dss-Parms ::= SEQUENCE { -# p INTEGER, -# q INTEGER, -# g INTEGER -# } -# -# DSAPublicKey ::= INTEGER -# -# DSSPrivatKey_OpenSSL ::= SEQUENCE -# version INTEGER, -# p INTEGER, -# q INTEGER, -# g INTEGER, -# y INTEGER, -# x INTEGER -# } -# - class _DSAobj(pubkey.pubkey): """Class defining an actual DSA key. @@ -162,12 +112,9 @@ class _DSAobj(pubkey.pubkey): #: - **x**, the private key. keydata = ['y', 'g', 'p', 'q', 'x'] - def __init__(self, implementation, key, randfunc=None): + def __init__(self, implementation, key): self.implementation = implementation self.key = key - if randfunc is None: - randfunc = Random.new().read - self._randfunc = randfunc def __getattr__(self, attrname): if attrname in self.keydata: @@ -234,8 +181,7 @@ def _unblind(self, m, r): raise TypeError("DSA cannot unblind") def _sign(self, m, k): - blind_factor = getRandomRange(1, self.key.q, self._randfunc) - return self.key._sign(m, k, blind_factor) + return self.key._sign(m, k) def _verify(self, m, sig): (r, s) = sig @@ -271,8 +217,6 @@ def __getstate__(self): def __setstate__(self, d): if not hasattr(self, 'implementation'): self.implementation = DSAImplementation() - if not hasattr(self, '_randfunc'): - self._randfunc = Random.new().read t = [] for k in self.keydata: if not d.has_key(k): @@ -292,124 +236,6 @@ def __repr__(self): # PY3K: This is meant to be text, do not change to bytes (data) return "<%s @0x%x %s>" % (self.__class__.__name__, id(self), ",".join(attrs)) - def exportKey(self, format='PEM', pkcs8=None, passphrase=None, - protection=None): - """Export this DSA key. - - :Parameters: - format : string - The format to use for wrapping the key: - - - *'DER'*. Binary encoding. - - *'PEM'*. Textual encoding, done according to `RFC1421`_/ - `RFC1423`_ (default). - - *'OpenSSH'*. Textual encoding, one line of text, see `RFC4253`_. - Only suitable for public keys, not private keys. - - passphrase : string - For private keys only. The pass phrase to use for deriving - the encryption key. - - pkcs8 : boolean - For private keys only. If ``True`` (default), the key is arranged - according to `PKCS#8`_ and if `False`, according to the custom - OpenSSL/OpenSSH encoding. - - protection : string - The encryption scheme to use for protecting the private key. - It is only meaningful when a pass phrase is present too. - - If ``pkcs8`` takes value ``True``, ``protection`` is the PKCS#8 - algorithm to use for deriving the secret and encrypting - the private DSA key. - For a complete list of algorithms, see `Crypto.IO.PKCS8`. - The default is *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC*. - - If ``pkcs8`` is ``False``, the obsolete PEM encryption scheme is - used. It is based on MD5 for key derivation, and Triple DES for - encryption. Parameter ``protection`` is ignored. - - The combination ``format='DER'`` and ``pkcs8=False`` is not allowed - if a passphrase is present. - - :Return: A byte string with the encoded public or private half - of the key. - :Raise ValueError: - When the format is unknown or when you try to encrypt a private - key with *DER* format and OpenSSL/OpenSSH. - :attention: - If you don't provide a pass phrase, the private key will be - exported in the clear! - - .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt - .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt - .. _RFC4253: http://www.ietf.org/rfc/rfc4253.txt - .. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt - """ - if passphrase is not None: - passphrase = tobytes(passphrase) - if format == 'OpenSSH': - tup1 = [long_to_bytes(x) for x in (self.p, self.q, self.g, self.y)] - - def func(x): - if (bord(x[0]) & 0x80): - return bchr(0) + x - else: - return x - - tup2 = map(func, tup1) - keyparts = [b('ssh-dss')] + tup2 - keystring = b('').join( - [struct.pack(">I", len(kp)) + kp for kp in keyparts] - ) - return b('ssh-dss ') + binascii.b2a_base64(keystring)[:-1] - - # DER format is always used, even in case of PEM, which simply - # encodes it into BASE64. - params = newDerSequence(self.p, self.q, self.g) - if self.has_private(): - if pkcs8 is None: - pkcs8 = True - if pkcs8: - if not protection: - protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC' - private_key = DerInteger(self.x).encode() - binary_key = PKCS8.wrap( - private_key, oid, passphrase, - protection, key_params=params, - randfunc=self._randfunc - ) - if passphrase: - key_type = 'ENCRYPTED PRIVATE' - else: - key_type = 'PRIVATE' - passphrase = None - else: - if format != 'PEM' and passphrase: - raise ValueError("DSA private key cannot be encrypted") - ints = [0, self.p, self.q, self.g, self.y, self.x] - binary_key = newDerSequence(*ints).encode() - key_type = "DSA PRIVATE" - else: - if pkcs8: - raise ValueError("PKCS#8 is only meaningful for private keys") - binary_key = newDerSequence( - newDerSequence(DerObjectId(oid), params), - newDerBitString(DerInteger(self.y)) - ).encode() - key_type = "DSA PUBLIC" - - if format == 'DER': - return binary_key - if format == 'PEM': - pem_str = PEM.encode( - binary_key, key_type + " KEY", - passphrase, self._randfunc - ) - return tobytes(pem_str) - raise ValueError("Unknown key format '%s'. Cannot export the DSA key." % format) - - class DSAImplementation(object): """ A DSA key factory. @@ -417,7 +243,7 @@ class DSAImplementation(object): This class is only internally used to implement the methods of the `Crypto.PublicKey.DSA` module. """ - + def __init__(self, **kwargs): """Create a new DSA key factory. @@ -497,7 +323,7 @@ def generate(self, bits, randfunc=None, progress_func=None): :Raise ValueError: When **bits** is too little, too big, or not a multiple of 64. """ - + # Check against FIPS 186-2, which says that the size of the prime p # must be a multiple of 64 bits between 512 and 1024 for i in (0, 1, 2, 3, 4, 5, 6, 7, 8): @@ -544,139 +370,9 @@ def construct(self, tup): key = self._math.dsa_construct(*tup) return _DSAobj(self, key) - def _importKeyDER(self, key_data, passphrase=None, params=None): - """Import a DSA key (public or private half), encoded in DER form.""" - - try: - # - # Dss-Parms ::= SEQUENCE { - # p OCTET STRING, - # q OCTET STRING, - # g OCTET STRING - # } - # - - # Try a simple private key first - if params: - x = decode_der(DerInteger, key_data).value - params = decode_der(DerSequence, params) # Dss-Parms - p, q, g = list(params) - y = pow(g, x, p) - tup = (y, g, p, q, x) - return self.construct(tup) - - der = decode_der(DerSequence, key_data) - - # Try OpenSSL format for private keys - if len(der) == 6 and der.hasOnlyInts() and der[0] == 0: - tup = [der[comp] for comp in (4, 3, 1, 2, 5)] - return self.construct(tup) - - # Try SubjectPublicKeyInfo - if len(der) == 2: - try: - algo = decode_der(DerSequence, der[0]) - algo_oid = decode_der(DerObjectId, algo[0]).value - params = decode_der(DerSequence, algo[1]) # Dss-Parms - - if algo_oid == oid and len(params) == 3 and\ - params.hasOnlyInts(): - bitmap = decode_der(DerBitString, der[1]) - pub_key = decode_der(DerInteger, bitmap.value) - tup = [pub_key.value] - tup += [params[comp] for comp in (2, 0, 1)] - return self.construct(tup) - except (ValueError, EOFError): - pass - - # Try unencrypted PKCS#8 - p8_pair = PKCS8.unwrap(key_data, passphrase) - if p8_pair[0] == oid: - return self._importKeyDER(p8_pair[1], passphrase, p8_pair[2]) - - except (ValueError, EOFError): - pass - - raise ValueError("DSA key format is not supported") - - def importKey(self, extern_key, passphrase=None): - """Import a DSA key (public or private). - - :Parameters: - extern_key : (byte) string - The DSA key to import. - - An DSA *public* key can be in any of the following formats: - - - X.509 ``subjectPublicKeyInfo`` (binary or PEM) - - OpenSSH (one line of text, see `RFC4253`_) - - A DSA *private* key can be in any of the following formats: - - - `PKCS#8`_ ``PrivateKeyInfo`` or ``EncryptedPrivateKeyInfo`` - DER SEQUENCE (binary or PEM encoding) - - OpenSSL/OpenSSH (binary or PEM) - - For details about the PEM encoding, see `RFC1421`_/`RFC1423`_. - - The private key may be encrypted by means of a certain pass phrase - either at the PEM level or at the PKCS#8 level. - - passphrase : string - In case of an encrypted private key, this is the pass phrase - from which the decryption key is derived. - - :Return: A DSA key object (`_DSAobj`). - :Raise ValueError: - When the given key cannot be parsed (possibly because - the pass phrase is wrong). - - .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt - .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt - .. _RFC4253: http://www.ietf.org/rfc/rfc4253.txt - .. _PKCS#8: http://www.ietf.org/rfc/rfc5208.txt - """ - - extern_key = tobytes(extern_key) - if passphrase is not None: - passphrase = tobytes(passphrase) - - if extern_key.startswith(b('-----')): - # This is probably a PEM encoded key - (der, marker, enc_flag) = PEM.decode(tostr(extern_key), passphrase) - if enc_flag: - passphrase = None - return self._importKeyDER(der, passphrase) - - if extern_key.startswith(b('ssh-dss ')): - # This is probably a public OpenSSH key - keystring = binascii.a2b_base64(extern_key.split(b(' '))[1]) - keyparts = [] - while len(keystring) > 4: - length = struct.unpack(">I", keystring[:4])[0] - keyparts.append(keystring[4:4 + length]) - keystring = keystring[4 + length:] - if keyparts[0] == b("ssh-dss"): - tup = [bytes_to_long(keyparts[x]) for x in (4, 3, 1, 2)] - return self.construct(tup) - - if bord(extern_key[0]) == 0x30: - # This is probably a DER encoded key - return self._importKeyDER(extern_key, passphrase) - - raise ValueError("DSA key format is not supported") - -#: `Object ID`_ for a DSA key. -#: -#: id-dsa ID ::= { iso(1) member-body(2) us(840) x9-57(10040) x9cm(4) 1 } -#: -#: .. _`Object ID`: http://www.alvestrand.no/objectid/1.2.840.10040.4.1.html -oid = "1.2.840.10040.4.1" - _impl = DSAImplementation() generate = _impl.generate construct = _impl.construct -importKey = _impl.importKey error = _impl.error # vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/lib/Crypto/PublicKey/ElGamal.py b/lib/Crypto/PublicKey/ElGamal.py index 0ab07fc8..99af71c4 100644 --- a/lib/Crypto/PublicKey/ElGamal.py +++ b/lib/Crypto/PublicKey/ElGamal.py @@ -111,7 +111,6 @@ from Crypto.PublicKey.pubkey import * from Crypto.Util import number -from Crypto import Random class error (Exception): pass @@ -243,11 +242,6 @@ class ElGamalobj(pubkey): #: - **x**, the private key. keydata=['p', 'g', 'y', 'x'] - def __init__(self, randfunc=None): - if randfunc is None: - randfunc = Random.new().read - self._randfunc = randfunc - def encrypt(self, plaintext, K): """Encrypt a piece of data with ElGamal. @@ -337,11 +331,8 @@ def _encrypt(self, M, K): def _decrypt(self, M): if (not hasattr(self, 'x')): raise TypeError('Private key not available in this object') - r = number.getRandomRange(2, self.p-1, self._randfunc) - a_blind = (M[0] * pow(self.g, r, self.p)) % self.p - ax=pow(a_blind, self.x, self.p) - plaintext_blind = (M[1] * inverse(ax, self.p ) ) % self.p - plaintext = (plaintext_blind * pow(self.y, r, self.p)) % self.p + ax=pow(M[0], self.x, self.p) + plaintext=(M[1] * inverse(ax, self.p ) ) % self.p return plaintext def _sign(self, M, K): diff --git a/lib/Crypto/PublicKey/RSA.py b/lib/Crypto/PublicKey/RSA.py index c323295b..99d851dd 100644 --- a/lib/Crypto/PublicKey/RSA.py +++ b/lib/Crypto/PublicKey/RSA.py @@ -46,7 +46,7 @@ >>> >>> key = RSA.generate(2048) >>> f = open('mykey.pem','w') - >>> f.write(key.exportKey('PEM')) + >>> f.write(RSA.exportKey('PEM')) >>> f.close() ... >>> f = open('mykey.pem','r') @@ -65,39 +65,31 @@ __revision__ = "$Id$" -__all__ = ['generate', 'construct', 'error', 'importKey', 'RSAImplementation', - '_RSAobj', 'oid' , 'algorithmIdentifier' ] +__all__ = ['generate', 'construct', 'error', 'importKey', 'RSAImplementation', '_RSAobj'] import sys if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * - +#from Crypto.Util.python_compat import * from Crypto.Util.number import getRandomRange, bytes_to_long, long_to_bytes from Crypto.PublicKey import _RSA, _slowmath, pubkey -from Crypto.IO import PKCS8, PEM from Crypto import Random -from Crypto.Util.asn1 import * - +from Crypto.Util.asn1 import DerObject, DerSequence, DerNull import binascii import struct from Crypto.Util.number import inverse +from Crypto.Util.number import inverse + try: from Crypto.PublicKey import _fastmath except ImportError: _fastmath = None -def decode_der(obj_class, binstr): - """Instantiate a DER object class, decode a DER binary string in it, and - return the object.""" - der = obj_class() - der.decode(binstr) - return der - class _RSAobj(pubkey.pubkey): """Class defining an actual RSA key. @@ -229,8 +221,6 @@ def verify(self, M, signature): return pubkey.pubkey.verify(self, M, signature) def _encrypt(self, c, K): - if not 0 < c < self.n: - raise ValueError("Plaintext too large") return (self.key._encrypt(c),) def _decrypt(self, c): @@ -240,9 +230,6 @@ def _decrypt(self, c): # going to replace the Crypto.PublicKey API soon # anyway. - if not 0 < ciphertext < self.n: - raise ValueError("Ciphertext too large") - # Blinded RSA decryption (to prevent timing attacks): # Step 1: Generate random secret blinding factor r, such that 0 < r < n-1 r = getRandomRange(1, self.key.n-1, randfunc=self._randfunc) @@ -299,8 +286,6 @@ def __getstate__(self): def __setstate__(self, d): if not hasattr(self, 'implementation'): self.implementation = RSAImplementation() - if not hasattr(self, '_randfunc'): - self._randfunc = Random.new().read t = [] for k in self.keydata: if not d.has_key(k): @@ -320,66 +305,36 @@ def __repr__(self): # PY3K: This is meant to be text, do not change to bytes (data) return "<%s @0x%x %s>" % (self.__class__.__name__, id(self), ",".join(attrs)) - def exportKey(self, format='PEM', passphrase=None, pkcs=1, protection=None): + def exportKey(self, format='PEM', passphrase=None, pkcs=1): """Export this RSA key. - :Parameters: - format : string - The format to use for wrapping the key: + :Parameter format: The format to use for wrapping the key. - - *'DER'*. Binary encoding. + - *'DER'*. Binary encoding, always unencrypted. - *'PEM'*. Textual encoding, done according to `RFC1421`_/`RFC1423`_. + Unencrypted (default) or encrypted. - *'OpenSSH'*. Textual encoding, done according to OpenSSH specification. Only suitable for public keys (not private keys). + :Type format: string - passphrase : string - For private keys only. The pass phrase used for deriving the encryption - key. - - pkcs : integer - For *DER* and *PEM* format only. - The PKCS standard to follow for assembling the components of the key. - You have two choices: - - - **1** (default): the public key is embedded into - an X.509 ``SubjectPublicKeyInfo`` DER SEQUENCE. - The private key is embedded into a `PKCS#1`_ - ``RSAPrivateKey`` DER SEQUENCE. - - **8**: the private key is embedded into a `PKCS#8`_ - ``PrivateKeyInfo`` DER SEQUENCE. This value cannot be used - for public keys. - - protection : string - The encryption scheme to use for protecting the private key. - - If ``None`` (default), the behavior depends on ``format``: - - - For *DER*, the *PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC* - scheme is used. The following operations are performed: + :Parameter passphrase: In case of PEM, the pass phrase to derive the encryption key from. + :Type passphrase: string - 1. A 16 byte Triple DES key is derived from the passphrase - using `Crypto.Protocol.KDF.PBKDF2` with 8 bytes salt, - and 1 000 iterations of `Crypto.Hash.HMAC`. - 2. The private key is encrypted using CBC. - 3. The encrypted key is encoded according to PKCS#8. + :Parameter pkcs: The PKCS standard to follow for assembling the key. + You have two choices: - - For *PEM*, the obsolete PEM encryption scheme is used. - It is based on MD5 for key derivation, and Triple DES for encryption. + - with **1**, the public key is embedded into an X.509 `SubjectPublicKeyInfo` DER SEQUENCE. + The private key is embedded into a `PKCS#1`_ `RSAPrivateKey` DER SEQUENCE. + This mode is the default. + - with **8**, the private key is embedded into a `PKCS#8`_ `PrivateKeyInfo` DER SEQUENCE. + This mode is not available for public keys. - Specifying a value for ``protection`` is only meaningful for PKCS#8 - (that is, ``pkcs=8``) and only if a pass phrase is present too. + PKCS standards are not relevant for the *OpenSSH* format. + :Type pkcs: integer - The supported schemes for PKCS#8 are listed in the - `Crypto.IO.PKCS8` module (see ``wrap_algo`` parameter). - - :Return: A byte string with the encoded public or private half - of the key. + :Return: A byte string with the encoded public or private half. :Raise ValueError: - When the format is unknown or when you try to encrypt a private - key with *DER* format and PKCS#1. - :attention: - If you don't provide a pass phrase, the private key will be - exported in the clear! + When the format is unknown. .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt @@ -393,52 +348,59 @@ def exportKey(self, format='PEM', passphrase=None, pkcs=1, protection=None): nb = long_to_bytes(self.n) if bord(eb[0]) & 0x80: eb=bchr(0x00)+eb if bord(nb[0]) & 0x80: nb=bchr(0x00)+nb - keyparts = [ b('ssh-rsa'), eb, nb ] - keystring = b('').join([ struct.pack(">I",len(kp))+kp for kp in keyparts]) - return b('ssh-rsa ')+binascii.b2a_base64(keystring)[:-1] + keyparts = [ 'ssh-rsa', eb, nb ] + keystring = ''.join([ struct.pack(">I",len(kp))+kp for kp in keyparts]) + return 'ssh-rsa '+binascii.b2a_base64(keystring)[:-1] # DER format is always used, even in case of PEM, which simply # encodes it into BASE64. + der = DerSequence() if self.has_private(): - binary_key = newDerSequence( - 0, - self.n, - self.e, - self.d, - self.p, - self.q, - self.d % (self.p-1), - self.d % (self.q-1), - inverse(self.q, self.p) - ).encode() - if pkcs==1: - keyType = 'RSA PRIVATE' - if format=='DER' and passphrase: - raise ValueError("PKCS#1 private key cannot be encrypted") - else: # PKCS#8 - if format=='PEM' and protection is None: - keyType = 'PRIVATE' - binary_key = PKCS8.wrap(binary_key, oid, None) - else: - keyType = 'ENCRYPTED PRIVATE' - if not protection: - protection = 'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC' - binary_key = PKCS8.wrap(binary_key, oid, passphrase, protection) - passphrase = None + keyType= { 1: 'RSA PRIVATE', 8: 'PRIVATE' }[pkcs] + der[:] = [ 0, self.n, self.e, self.d, self.p, self.q, + self.d % (self.p-1), self.d % (self.q-1), + inverse(self.q, self.p) ] + if pkcs==8: + derkey = der.encode() + der = DerSequence([0]) + der.append(algorithmIdentifier) + der.append(DerObject('OCTET STRING', derkey).encode()) else: - keyType = "RSA PUBLIC" - binary_key = newDerSequence( - algorithmIdentifier, - newDerBitString( - newDerSequence( self.n, self.e ) - ) - ).encode() + keyType = "PUBLIC" + der.append(algorithmIdentifier) + bitmap = DerObject('BIT STRING') + derPK = DerSequence( [ self.n, self.e ] ) + bitmap.payload = bchr(0x00) + derPK.encode() + der.append(bitmap.encode()) if format=='DER': - return binary_key + return der.encode() if format=='PEM': - pem_str = PEM.encode(binary_key, keyType+" KEY", passphrase, self._randfunc) - return tobytes(pem_str) - raise ValueError("Unknown key format '%s'. Cannot export the RSA key." % format) + pem = b("-----BEGIN " + keyType + " KEY-----\n") + objenc = None + if passphrase and keyType.endswith('PRIVATE'): + # We only support 3DES for encryption + import Crypto.Hash.MD5 + from Crypto.Cipher import DES3 + from Crypto.Protocol.KDF import PBKDF1 + salt = self._randfunc(8) + key = PBKDF1(passphrase, salt, 16, 1, Crypto.Hash.MD5) + key += PBKDF1(key+passphrase, salt, 8, 1, Crypto.Hash.MD5) + objenc = DES3.new(key, Crypto.Cipher.DES3.MODE_CBC, salt) + pem += b('Proc-Type: 4,ENCRYPTED\n') + pem += b('DEK-Info: DES-EDE3-CBC,') + binascii.b2a_hex(salt).upper() + b('\n\n') + + binaryKey = der.encode() + if objenc: + # Add PKCS#7-like padding + padding = objenc.block_size-len(binaryKey)%objenc.block_size + binaryKey = objenc.encrypt(binaryKey+bchr(padding)*padding) + + # Each BASE64 line can take up to 64 characters (=48 bytes of data) + chunks = [ binascii.b2a_base64(binaryKey[i:i+48]) for i in range(0, len(binaryKey), 48) ] + pem += b('').join(chunks) + pem += b("-----END " + keyType + " KEY-----") + return pem + return ValueError("Unknown key format '%s'. Cannot export the RSA key." % format) class RSAImplementation(object): """ @@ -577,139 +539,159 @@ def construct(self, tup): key = self._math.rsa_construct(*tup) return _RSAobj(self, key) - def _importKeyDER(self, extern_key, passphrase=None): + def _importKeyDER(self, externKey): """Import an RSA key (public or private half), encoded in DER form.""" try: - der = decode_der(DerSequence, extern_key) + der = DerSequence() + der.decode(externKey, True) # Try PKCS#1 first, for a private key - if len(der) == 9 and der.hasOnlyInts() and der[0] == 0: + if len(der)==9 and der.hasOnlyInts() and der[0]==0: # ASN.1 RSAPrivateKey element - del der[6:] # Remove d mod (p-1), - # d mod (q-1), and - # q^{-1} mod p - der.append(inverse(der[4], der[5])) # Add p^{-1} mod q + del der[6:] # Remove d mod (p-1), d mod (q-1), and q^{-1} mod p + der.append(inverse(der[4],der[5])) # Add p^{-1} mod q del der[0] # Remove version return self.construct(der[:]) # Keep on trying PKCS#1, but now for a public key - if len(der) == 2: - try: - # The DER object is an RSAPublicKey SEQUENCE with - # two elements - if der.hasOnlyInts(): - return self.construct(der[:]) - # The DER object is a SubjectPublicKeyInfo SEQUENCE - # with two elements: an 'algorithmIdentifier' and a - # 'subjectPublicKey'BIT STRING. - # 'algorithmIdentifier' takes the value given at the - # module level. - # 'subjectPublicKey' encapsulates the actual ASN.1 - # RSAPublicKey element. - if der[0] == algorithmIdentifier: - bitmap = decode_der(DerBitString, der[1]) - rsaPub = decode_der(DerSequence, bitmap.value) - if len(rsaPub) == 2 and rsaPub.hasOnlyInts(): - return self.construct(rsaPub[:]) - except (ValueError, EOFError): - pass - - # Try PKCS#8 (possibly encrypted) - k = PKCS8.unwrap(extern_key, passphrase) - if k[0] == oid: - return self._importKeyDER(k[1], passphrase) - - except (ValueError, EOFError): + if len(der)==2: + # The DER object is an RSAPublicKey SEQUENCE with two elements + if der.hasOnlyInts(): + return self.construct(der[:]) + # The DER object is a SubjectPublicKeyInfo SEQUENCE with two elements: + # an 'algorithm' (or 'algorithmIdentifier') SEQUENCE and a 'subjectPublicKey' BIT STRING. + # 'algorithm' takes the value given a few lines above. + # 'subjectPublicKey' encapsulates the actual ASN.1 RSAPublicKey element. + if der[0]==algorithmIdentifier: + bitmap = DerObject() + bitmap.decode(der[1], True) + if bitmap.isType('BIT STRING') and bord(bitmap.payload[0])==0x00: + der.decode(bitmap.payload[1:], True) + if len(der)==2 and der.hasOnlyInts(): + return self.construct(der[:]) + + # Try unencrypted PKCS#8 + if der[0]==0: + # The second element in the SEQUENCE is algorithmIdentifier. + # It must say RSA (see above for description). + if der[1]==algorithmIdentifier: + privateKey = DerObject() + privateKey.decode(der[2], True) + if privateKey.isType('OCTET STRING'): + return self._importKeyDER(privateKey.payload) + + except ValueError, IndexError: pass raise ValueError("RSA key format is not supported") - def importKey(self, extern_key, passphrase=None): - """Import an RSA key (public or private half), encoded in standard - form. + def importKey(self, externKey, passphrase=None): + """Import an RSA key (public or private half), encoded in standard form. - :Parameter extern_key: + :Parameter externKey: The RSA key to import, encoded as a string. An RSA public key can be in any of the following formats: - - X.509 ``subjectPublicKeyInfo`` DER SEQUENCE (binary or PEM - encoding) - - `PKCS#1`_ ``RSAPublicKey`` DER SEQUENCE (binary or PEM encoding) + - X.509 `subjectPublicKeyInfo` DER SEQUENCE (binary or PEM encoding) + - `PKCS#1`_ `RSAPublicKey` DER SEQUENCE (binary or PEM encoding) - OpenSSH (textual public key only) An RSA private key can be in any of the following formats: - - PKCS#1 ``RSAPrivateKey`` DER SEQUENCE (binary or PEM encoding) - - `PKCS#8`_ ``PrivateKeyInfo`` or ``EncryptedPrivateKeyInfo`` - DER SEQUENCE (binary or PEM encoding) + - PKCS#1 `RSAPrivateKey` DER SEQUENCE (binary or PEM encoding) + - `PKCS#8`_ `PrivateKeyInfo` DER SEQUENCE (binary or PEM encoding) - OpenSSH (textual public key only) For details about the PEM encoding, see `RFC1421`_/`RFC1423`_. - - The private key may be encrypted by means of a certain pass phrase - either at the PEM level or at the PKCS#8 level. - :Type extern_key: string + + In case of PEM encoding, the private key can be encrypted with DES or 3TDES according to a certain ``pass phrase``. + Only OpenSSL-compatible pass phrases are supported. + :Type externKey: string :Parameter passphrase: - In case of an encrypted private key, this is the pass phrase from - which the decryption key is derived. + In case of an encrypted PEM key, this is the pass phrase from which the encryption key is derived. :Type passphrase: string - + :Return: An RSA key object (`_RSAobj`). :Raise ValueError/IndexError/TypeError: - When the given key cannot be parsed (possibly because the pass - phrase is wrong). + When the given key cannot be parsed (possibly because the pass phrase is wrong). .. _RFC1421: http://www.ietf.org/rfc/rfc1421.txt .. _RFC1423: http://www.ietf.org/rfc/rfc1423.txt .. _`PKCS#1`: http://www.ietf.org/rfc/rfc3447.txt .. _`PKCS#8`: http://www.ietf.org/rfc/rfc5208.txt """ - extern_key = tobytes(extern_key) + externKey = tobytes(externKey) if passphrase is not None: passphrase = tobytes(passphrase) - if extern_key.startswith(b('-----')): - # This is probably a PEM encoded key. - (der, marker, enc_flag) = PEM.decode(tostr(extern_key), passphrase) - if enc_flag: - passphrase = None - return self._importKeyDER(der, passphrase) - - if extern_key.startswith(b('ssh-rsa ')): + if externKey.startswith(b('-----')): + # This is probably a PEM encoded key + lines = externKey.replace(b(" "),b('')).split() + keyobj = None + + # The encrypted PEM format + if lines[1].startswith(b('Proc-Type:4,ENCRYPTED')): + DEK = lines[2].split(b(':')) + if len(DEK)!=2 or DEK[0]!=b('DEK-Info') or not passphrase: + raise ValueError("PEM encryption format not supported.") + algo, salt = DEK[1].split(b(',')) + salt = binascii.a2b_hex(salt) + import Crypto.Hash.MD5 + from Crypto.Cipher import DES, DES3 + from Crypto.Protocol.KDF import PBKDF1 + if algo==b("DES-CBC"): + # This is EVP_BytesToKey in OpenSSL + key = PBKDF1(passphrase, salt, 8, 1, Crypto.Hash.MD5) + keyobj = DES.new(key, Crypto.Cipher.DES.MODE_CBC, salt) + elif algo==b("DES-EDE3-CBC"): + # Note that EVP_BytesToKey is note exactly the same as PBKDF1 + key = PBKDF1(passphrase, salt, 16, 1, Crypto.Hash.MD5) + key += PBKDF1(key+passphrase, salt, 8, 1, Crypto.Hash.MD5) + keyobj = DES3.new(key, Crypto.Cipher.DES3.MODE_CBC, salt) + else: + raise ValueError("Unsupport PEM encryption algorithm.") + lines = lines[2:] + + der = binascii.a2b_base64(b('').join(lines[1:-1])) + if keyobj: + der = keyobj.decrypt(der) + padding = bord(der[-1]) + der = der[:-padding] + return self._importKeyDER(der) + + if externKey.startswith(b('ssh-rsa ')): # This is probably an OpenSSH key - keystring = binascii.a2b_base64(extern_key.split(b(' '))[1]) + keystring = binascii.a2b_base64(externKey.split(b(' '))[1]) keyparts = [] - while len(keystring) > 4: - l = struct.unpack(">I", keystring[:4])[0] - keyparts.append(keystring[4:4 + l]) - keystring = keystring[4 + l:] + while len(keystring)>4: + l = struct.unpack(">I",keystring[:4])[0] + keyparts.append(keystring[4:4+l]) + keystring = keystring[4+l:] e = bytes_to_long(keyparts[1]) n = bytes_to_long(keyparts[2]) return self.construct([n, e]) - - if bord(extern_key[0]) == 0x30: + if bord(externKey[0])==0x30: # This is probably a DER encoded key - return self._importKeyDER(extern_key, passphrase) - + return self._importKeyDER(externKey) + raise ValueError("RSA key format is not supported") -#: `Object ID`_ for the RSA encryption algorithm. This OID often indicates -#: a generic RSA key, even when such key will be actually used for digital -#: signatures. -#: -#: .. _`Object ID`: http://www.alvestrand.no/objectid/1.2.840.113549.1.1.1.html -oid = "1.2.840.113549.1.1.1" - -#: This is the standard DER object that qualifies a cryptographic algorithm -#: in ASN.1-based data structures (e.g. X.509 certificates). +#: This is the ASN.1 DER object that qualifies an algorithm as +#: compliant to PKCS#1 (that is, the standard RSA). +# It is found in all 'algorithm' fields (also called 'algorithmIdentifier'). +# It is a SEQUENCE with the oid assigned to RSA and with its parameters (none). +# 0x06 0x09 OBJECT IDENTIFIER, 9 bytes of payload +# 0x2A 0x86 0x48 0x86 0xF7 0x0D 0x01 0x01 0x01 +# rsaEncryption (1 2 840 113549 1 1 1) (PKCS #1) +# 0x05 0x00 NULL algorithmIdentifier = DerSequence( - [DerObjectId(oid).encode(), # algorithm field - DerNull().encode()] # parameters field + [ b('\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01'), + DerNull().encode() ] ).encode() _impl = RSAImplementation() diff --git a/lib/Crypto/PublicKey/_DSA.py b/lib/Crypto/PublicKey/_DSA.py index f027d920..6b7a9649 100644 --- a/lib/Crypto/PublicKey/_DSA.py +++ b/lib/Crypto/PublicKey/_DSA.py @@ -30,7 +30,7 @@ from Crypto.PublicKey.pubkey import * from Crypto.Util import number from Crypto.Util.number import bytes_to_long, long_to_bytes -from Crypto.Hash import SHA1 +from Crypto.Hash import SHA from Crypto.Util.py3compat import * class error (Exception): @@ -38,8 +38,8 @@ class error (Exception): def generateQ(randfunc): S=randfunc(20) - hash1=SHA1.new(S).digest() - hash2=SHA1.new(long_to_bytes(bytes_to_long(S)+1)).digest() + hash1=SHA.new(S).digest() + hash2=SHA.new(long_to_bytes(bytes_to_long(S)+1)).digest() q = bignum(0) for i in range(0,20): c=bord(hash1[i])^bord(hash2[i]) @@ -77,7 +77,7 @@ def generate_py(bits, randfunc, progress_func=None): powL1=pow(bignum(2), bits-1) while C<4096: for k in range(0, n+1): - V[k]=bytes_to_long(SHA1.new(S+bstr(N)+bstr(k)).digest()) + V[k]=bytes_to_long(SHA.new(S+bstr(N)+bstr(k)).digest()) W=V[n] % powb for k in range(n-1, -1, -1): W=(W<<160L)+V[k] diff --git a/lib/Crypto/PublicKey/_slowmath.py b/lib/Crypto/PublicKey/_slowmath.py index 1350773e..d926596e 100644 --- a/lib/Crypto/PublicKey/_slowmath.py +++ b/lib/Crypto/PublicKey/_slowmath.py @@ -40,7 +40,7 @@ class error(Exception): class _RSAKey(object): def _blind(self, m, r): # compute r**e * m (mod n) - return (m * pow(r, self.e, self.n)) % self.n + return m * pow(r, self.e, self.n) def _unblind(self, m, r): # compute m / r (mod n) @@ -113,7 +113,7 @@ def rsa_construct(n, e, d=None, p=None, q=None, u=None): # as Factorization", M. Rabin, 1979 spotted = 0 a = 2 - while not spotted and a<1000: + while not spotted and a<100: k = t # Cycle through all values a^{t*2^i}=a^k while k current_time): # Avoid float comparison to None to make Py3k happy warnings.warn("Clock rewind detected. Resetting last_reseed.", ClockRewindWarning) self.last_reseed = None @@ -152,7 +149,7 @@ def random_data(self, bytes): def _reseed(self, current_time=None): if current_time is None: - current_time = maybe_monotonic_time() + current_time = time.time() seed = [] self.reseed_count += 1 self.last_reseed = current_time diff --git a/lib/Crypto/Random/Fortuna/FortunaGenerator.py b/lib/Crypto/Random/Fortuna/FortunaGenerator.py index 09351fcb..723fa630 100644 --- a/lib/Crypto/Random/Fortuna/FortunaGenerator.py +++ b/lib/Crypto/Random/Fortuna/FortunaGenerator.py @@ -25,7 +25,7 @@ __revision__ = "$Id$" import sys -if sys.version_info[0] == 2 and sys.version_info[1] == 1: +if sys.version_info[0] is 2 and sys.version_info[1] is 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * diff --git a/lib/Crypto/Random/OSRNG/nt.py b/lib/Crypto/Random/OSRNG/nt.py index 40aa495d..c1c2f44e 100644 --- a/lib/Crypto/Random/OSRNG/nt.py +++ b/lib/Crypto/Random/OSRNG/nt.py @@ -25,7 +25,7 @@ __revision__ = "$Id$" __all__ = ['WindowsRNG'] -from Crypto.Random.OSRNG import winrandom +import winrandom from rng_base import BaseRNG class WindowsRNG(BaseRNG): diff --git a/lib/Crypto/Random/random.py b/lib/Crypto/Random/random.py index 6b1c57ab..bef02e65 100644 --- a/lib/Crypto/Random/random.py +++ b/lib/Crypto/Random/random.py @@ -103,13 +103,13 @@ def choice(self, seq): def shuffle(self, x): """Shuffle the sequence in place.""" - # Fisher-Yates shuffle. O(n) - # See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle - # Working backwards from the end of the array, we choose a random item - # from the remaining items until all items have been chosen. - for i in xrange(len(x)-1, 0, -1): # iterate from len(x)-1 downto 1 - j = self.randrange(0, i+1) # choose random j such that 0 <= j <= i - x[i], x[j] = x[j], x[i] # exchange x[i] and x[j] + # Make a (copy) of the list of objects we want to shuffle + items = list(x) + + # Choose a random item (without replacement) until all the items have been + # chosen. + for i in xrange(len(x)): + x[i] = items.pop(self.randrange(len(items))) def sample(self, population, k): """Return a k-length list of unique elements chosen from the population sequence.""" diff --git a/lib/Crypto/SelfTest/Cipher/common.py b/lib/Crypto/SelfTest/Cipher/common.py index a5f8a885..8bebed9c 100644 --- a/lib/Crypto/SelfTest/Cipher/common.py +++ b/lib/Crypto/SelfTest/Cipher/common.py @@ -24,19 +24,12 @@ """Self-testing for PyCrypto hash modules""" -from __future__ import nested_scopes - __revision__ = "$Id$" import sys -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * - import unittest -from binascii import a2b_hex, b2a_hex, hexlify - +from binascii import a2b_hex, b2a_hex from Crypto.Util.py3compat import * -from Crypto.Util.strxor import strxor_c # For compatibility with Python 2.1 and Python 2.2 if sys.hexversion < 0x02030000: @@ -73,22 +66,14 @@ def __init__(self, module, params): self.plaintext = b(_extract(params, 'plaintext')) self.ciphertext = b(_extract(params, 'ciphertext')) self.module_name = _extract(params, 'module_name', None) - self.assoc_data = _extract(params, 'assoc_data', None) - self.mac = _extract(params, 'mac', None) - if self.assoc_data: - self.mac = b(self.mac) mode = _extract(params, 'mode', None) self.mode_name = str(mode) if mode is not None: # Block cipher self.mode = getattr(self.module, "MODE_" + mode) - self.iv = _extract(params, 'iv', None) - if self.iv is None: - self.iv = _extract(params, 'nonce', None) - if self.iv is not None: - self.iv = b(self.iv) + if self.iv is not None: self.iv = b(self.iv) # Only relevant for OPENPGP mode self.encrypted_iv = _extract(params, 'encrypted_iv', None) @@ -132,60 +117,29 @@ def _new(self, do_decryption=0): else: return self.module.new(a2b_hex(self.key), self.mode, a2b_hex(self.iv), **params) - def isMode(self, name): - if not hasattr(self.module, "MODE_"+name): - return False - return self.mode == getattr(self.module, "MODE_"+name) - def runTest(self): plaintext = a2b_hex(self.plaintext) ciphertext = a2b_hex(self.ciphertext) - assoc_data = [] - if self.assoc_data: - assoc_data = [ a2b_hex(b(x)) for x in self.assoc_data] - - ct = None - pt = None - - # - # Repeat the same encryption or decryption twice and verify - # that the result is always the same - # - for i in xrange(2): - cipher = self._new() - decipher = self._new(1) - - # Only AEAD modes - for comp in assoc_data: - cipher.update(comp) - decipher.update(comp) - - ctX = b2a_hex(cipher.encrypt(plaintext)) - if self.isMode("SIV"): - ptX = b2a_hex(decipher.decrypt_and_verify(ciphertext, a2b_hex(self.mac))) - else: - ptX = b2a_hex(decipher.decrypt(ciphertext)) - if ct: - self.assertEqual(ct, ctX) - self.assertEqual(pt, ptX) - ct, pt = ctX, ptX + ct1 = b2a_hex(self._new().encrypt(plaintext)) + pt1 = b2a_hex(self._new(1).decrypt(ciphertext)) + ct2 = b2a_hex(self._new().encrypt(plaintext)) + pt2 = b2a_hex(self._new(1).decrypt(ciphertext)) - if self.isMode("OPENPGP"): + if hasattr(self.module, "MODE_OPENPGP") and self.mode == self.module.MODE_OPENPGP: # In PGP mode, data returned by the first encrypt() # is prefixed with the encrypted IV. # Here we check it and then remove it from the ciphertexts. eilen = len(self.encrypted_iv) - self.assertEqual(self.encrypted_iv, ct[:eilen]) - ct = ct[eilen:] - - self.assertEqual(self.ciphertext, ct) # encrypt - self.assertEqual(self.plaintext, pt) # decrypt + self.assertEqual(self.encrypted_iv, ct1[:eilen]) + self.assertEqual(self.encrypted_iv, ct2[:eilen]) + ct1 = ct1[eilen:] + ct2 = ct2[eilen:] - if self.mac: - mac = b2a_hex(cipher.digest()) - self.assertEqual(self.mac, mac) - decipher.verify(a2b_hex(self.mac)) + self.assertEqual(self.ciphertext, ct1) # encrypt + self.assertEqual(self.ciphertext, ct2) # encrypt (second time) + self.assertEqual(self.plaintext, pt1) # decrypt + self.assertEqual(self.plaintext, pt2) # decrypt (second time) class CipherStreamingSelfTest(CipherSelfTest): @@ -241,43 +195,18 @@ def __init__(self, module, params): self.module_name = params.get('module_name', None) def shortDescription(self): - return """Regression test: %s with MODE_CTR raising OverflowError on wraparound""" % (self.module_name,) + return """Regression test: %s with MODE_CTR should raise OverflowError on wraparound when shortcut used""" % (self.module_name,) def runTest(self): from Crypto.Util import Counter - def pythonCounter(): - state = [0] - def ctr(): - # First block succeeds; Second and subsequent blocks raise OverflowError - if state[0] == 0: - state[0] = 1 - return b("\xff") * self.module.block_size - else: - raise OverflowError - return ctr - - for little_endian in (0, 1): # (False, True) Test both endiannesses - block = b("\x00") * self.module.block_size - - # Test PyObject_CallObject code path: if the counter raises OverflowError - cipher = self.module.new(a2b_hex(self.key), self.module.MODE_CTR, counter=pythonCounter()) - cipher.encrypt(block) - self.assertRaises(OverflowError, cipher.encrypt, block) - self.assertRaises(OverflowError, cipher.encrypt, block) - - # Test PyObject_CallObject code path: counter object should raise OverflowError - ctr = Counter.new(8*self.module.block_size, initial_value=2L**(8*self.module.block_size)-1, little_endian=little_endian) - ctr() - self.assertRaises(OverflowError, ctr) - self.assertRaises(OverflowError, ctr) - - # Test the CTR-mode shortcut - ctr = Counter.new(8*self.module.block_size, initial_value=2L**(8*self.module.block_size)-1, little_endian=little_endian) - cipher = self.module.new(a2b_hex(self.key), self.module.MODE_CTR, counter=ctr) - cipher.encrypt(block) - self.assertRaises(OverflowError, cipher.encrypt, block) - self.assertRaises(OverflowError, cipher.encrypt, block) + for disable_shortcut in (0, 1): # (False, True) Test CTR-mode shortcut and PyObject_CallObject code paths + for little_endian in (0, 1): # (False, True) Test both endiannesses + ctr = Counter.new(8*self.module.block_size, initial_value=2L**(8*self.module.block_size)-1, little_endian=little_endian, disable_shortcut=disable_shortcut) + cipher = self.module.new(a2b_hex(self.key), self.module.MODE_CTR, counter=ctr) + block = b("\x00") * self.module.block_size + cipher.encrypt(block) + self.assertRaises(OverflowError, cipher.encrypt, block) class CFBSegmentSizeTest(unittest.TestCase): @@ -296,301 +225,6 @@ def runTest(self): self.assertRaises(ValueError, self.module.new, a2b_hex(self.key), self.module.MODE_CFB, segment_size=i) self.module.new(a2b_hex(self.key), self.module.MODE_CFB, "\0"*self.module.block_size, segment_size=8) # should succeed -class CCMMACLengthTest(unittest.TestCase): - """CCM specific tests about MAC""" - - def __init__(self, module): - unittest.TestCase.__init__(self) - self.module = module - self.key = b('\xFF')*16 - self.iv = b('\x00')*10 - - def shortDescription(self): - return self.description - - def runTest(self): - """Verify that MAC can only be 4,6,8,..,16 bytes long.""" - for i in range(3,16,2): - self.description = "CCM MAC length check (%d bytes)" % i - self.assertRaises(ValueError, self.module.new, self.key, - self.module.MODE_CCM, self.iv, msg_len=10, mac_len=i) - - """Verify that default MAC length is 16.""" - self.description = "CCM default MAC length check" - cipher = self.module.new(self.key, self.module.MODE_CCM, - self.iv, msg_len=4) - cipher.encrypt(b('z')*4) - self.assertEqual(len(cipher.digest()), 16) - -class CCMSplitEncryptionTest(unittest.TestCase): - """CCM specific tests to validate how encrypt() - decrypt() can be called multiple times on the - same object.""" - - def __init__(self, module): - unittest.TestCase.__init__(self) - self.module = module - self.key = b('\xFF')*16 - self.iv = b('\x00')*10 - self.description = "CCM Split Encryption Test" - - def shortDescription(self): - return self.description - - def runTest(self): - """Verify that CCM update()/encrypt() can be called multiple times, - provided that lengths are declared beforehand""" - - data = b("AUTH DATA") - pt1 = b("PLAINTEXT1") # Short - pt2 = b("PLAINTEXT2") # Long - pt_ref = pt1+pt2 - - # REFERENCE: Run with 1 update() and 1 encrypt() - cipher = self.module.new(self.key, self.module.MODE_CCM, - self.iv) - cipher.update(data) - ct_ref = cipher.encrypt(pt_ref) - mac_ref = cipher.digest() - - # Verify that calling CCM encrypt()/decrypt() twice is not - # possible without the 'msg_len' parameter and regardless - # of the 'assoc_len' parameter - for ad_len in None, len(data): - cipher = self.module.new(self.key, self.module.MODE_CCM, - self.iv, assoc_len=ad_len) - cipher.update(data) - cipher.encrypt(pt1) - self.assertRaises(TypeError, cipher.encrypt, pt2) - - cipher = self.module.new(self.key, self.module.MODE_CCM, - self.iv, assoc_len=ad_len) - cipher.update(data) - cipher.decrypt(ct_ref[:len(pt1)]) - self.assertRaises(TypeError, cipher.decrypt, ct_ref[len(pt1):]) - - # Run with 2 encrypt()/decrypt(). Results must be the same - # regardless of the 'assoc_len' parameter - for ad_len in None, len(data): - cipher = self.module.new(self.key, self.module.MODE_CCM, - self.iv, assoc_len=ad_len, msg_len=len(pt_ref)) - cipher.update(data) - ct = cipher.encrypt(pt1) - ct += cipher.encrypt(pt2) - mac = cipher.digest() - self.assertEqual(ct_ref, ct) - self.assertEqual(mac_ref, mac) - - cipher = self.module.new(self.key, self.module.MODE_CCM, - self.iv, msg_len=len(pt1+pt2)) - cipher.update(data) - pt = cipher.decrypt(ct[:len(pt1)]) - pt += cipher.decrypt(ct[len(pt1):]) - mac = cipher.verify(mac_ref) - self.assertEqual(pt_ref, pt) - -class AEADTests(unittest.TestCase): - """Tests generic to all AEAD modes""" - - def __init__(self, module, mode_name, key_size): - unittest.TestCase.__init__(self) - self.module = module - self.mode_name = mode_name - self.mode = getattr(module, mode_name) - if not self.isMode("SIV"): - self.key = b('\xFF')*key_size - else: - self.key = b('\xFF')*key_size*2 - self.iv = b('\x00')*10 - self.description = "AEAD Test" - - def isMode(self, name): - if not hasattr(self.module, "MODE_"+name): - return False - return self.mode == getattr(self.module, "MODE_"+name) - - def right_mac_test(self): - """Positive tests for MAC""" - - self.description = "Test for right MAC in %s of %s" % \ - (self.mode_name, self.module.__name__) - - ad_ref = b("Reference AD") - pt_ref = b("Reference plaintext") - - # Encrypt and create the reference MAC - cipher = self.module.new(self.key, self.mode, self.iv) - cipher.update(ad_ref) - ct_ref = cipher.encrypt(pt_ref) - mac_ref = cipher.digest() - - # Decrypt and verify that MAC is accepted - decipher = self.module.new(self.key, self.mode, self.iv) - decipher.update(ad_ref) - pt = decipher.decrypt_and_verify(ct_ref, mac_ref) - self.assertEqual(pt, pt_ref) - - # Verify that hexverify work - decipher.hexverify(hexlify(mac_ref)) - - def wrong_mac_test(self): - """Negative tests for MAC""" - - self.description = "Test for wrong MAC in %s of %s" % \ - (self.mode_name, self.module.__name__) - - ad_ref = b("Reference AD") - pt_ref = b("Reference plaintext") - - # Encrypt and create the reference MAC - cipher = self.module.new(self.key, self.mode, self.iv) - cipher.update(ad_ref) - ct_ref = cipher.encrypt(pt_ref) - mac_ref = cipher.digest() - - # Modify the MAC and verify it is NOT ACCEPTED - wrong_mac = strxor_c(mac_ref, 255) - decipher = self.module.new(self.key, self.mode, self.iv) - decipher.update(ad_ref) - self.assertRaises(ValueError, decipher.decrypt_and_verify, - ct_ref, wrong_mac) - - def zero_data(self): - """Verify transition from INITIALIZED to FINISHED""" - - self.description = "Test for zero data in %s of %s" % \ - (self.mode_name, self.module.__name__) - cipher = self.module.new(self.key, self.mode, self.iv) - cipher.digest() - - def multiple_updates(self): - """Verify that update() can be called multiple times""" - - self.description = "Test for multiple updates in %s of %s" % \ - (self.mode_name, self.module.__name__) - - # In all modes other than SIV, the associated data is a single - # component that can be arbitrarilly split and submitted to update(). - # - # In SIV, associated data is instead organized in a vector or multiple - # components. Each component is passed to update() as a whole. - # This test is therefore not meaningful to SIV. - if self.isMode("SIV"): - return - - ad = b("").join([bchr(x) for x in xrange(0,128)]) - - mac1, mac2, mac3 = (None,)*3 - for chunk_length in 1,10,40,80,128: - chunks = [ad[i:i+chunk_length] for i in range(0, len(ad), chunk_length)] - - # No encryption/decryption - cipher = self.module.new(self.key, self.mode, self.iv) - for c in chunks: - cipher.update(c) - if mac1: - cipher.verify(mac1) - else: - mac1 = cipher.digest() - - # Encryption - cipher = self.module.new(self.key, self.mode, self.iv) - for c in chunks: - cipher.update(c) - ct = cipher.encrypt(b("PT")) - mac2 = cipher.digest() - - # Decryption - cipher = self.module.new(self.key, self.mode, self.iv) - for c in chunks: - cipher.update(c) - cipher.decrypt(ct) - cipher.verify(mac2) - - def no_mix_encrypt_decrypt(self): - """Verify that encrypt and decrypt cannot be mixed up""" - - self.description = "Test for mix of encrypt and decrypt in %s of %s" % \ - (self.mode_name, self.module.__name__) - - # Calling decrypt after encrypt raises an exception - cipher = self.module.new(self.key, self.mode, self.iv) - cipher.encrypt(b("PT")*40) - self.assertRaises(TypeError, cipher.decrypt, b("XYZ")*40) - - # Calling encrypt() after decrypt() raises an exception - # (excluded for SIV, since decrypt() is not valid) - if not self.isMode("SIV"): - cipher = self.module.new(self.key, self.mode, self.iv) - cipher.decrypt(b("CT")*40) - self.assertRaises(TypeError, cipher.encrypt, b("XYZ")*40) - - # Calling verify after encrypt raises an exception - cipher = self.module.new(self.key, self.mode, self.iv) - cipher.encrypt(b("PT")*40) - self.assertRaises(TypeError, cipher.verify, b("XYZ")) - self.assertRaises(TypeError, cipher.hexverify, "12") - - # Calling digest() after decrypt() raises an exception - # (excluded for SIV, since decrypt() is not valid) - if not self.isMode("SIV"): - cipher = self.module.new(self.key, self.mode, self.iv) - cipher.decrypt(b("CT")*40) - self.assertRaises(TypeError, cipher.digest) - self.assertRaises(TypeError, cipher.hexdigest) - - def no_late_update(self): - """Verify that update cannot be called after encrypt or decrypt""" - - self.description = "Test for late update in %s of %s" % \ - (self.mode_name, self.module.__name__) - - # Calling update after encrypt raises an exception - cipher = self.module.new(self.key, self.mode, self.iv) - cipher.update(b("XX")) - cipher.encrypt(b("PT")*40) - self.assertRaises(TypeError, cipher.update, b("XYZ")) - - # Calling update() after decrypt() raises an exception - # (excluded for SIV, since decrypt() is not valid) - if not self.isMode("SIV"): - cipher = self.module.new(self.key, self.mode, self.iv) - cipher.update(b("XX")) - cipher.decrypt(b("CT")*40) - self.assertRaises(TypeError, cipher.update, b("XYZ")) - - def loopback(self): - """Verify composition of encrypt_and_digest() and decrypt_and_verify() - is the identity function.""" - - self.description = "Lookback test decrypt_and_verify(encrypt_and_digest)"\ - "for %s in %s" % (self.mode_name, - self.module.__name__) - - enc_cipher = self.module.new(self.key, self.mode, self.iv) - dec_cipher = self.module.new(self.key, self.mode, self.iv) - - enc_cipher.update(b("XXX")) - dec_cipher.update(b("XXX")) - - plaintext = b("Reference") * 10 - ct, mac = enc_cipher.encrypt_and_digest(plaintext) - pt = dec_cipher.decrypt_and_verify(ct, mac) - - self.assertEqual(plaintext, pt) - - def runTest(self): - self.right_mac_test() - self.wrong_mac_test() - self.zero_data() - self.multiple_updates() - self.no_mix_encrypt_decrypt() - self.no_late_update() - self.loopback() - - def shortDescription(self): - return self.description - class RoundtripTest(unittest.TestCase): def __init__(self, module, params): from Crypto import Random @@ -605,34 +239,19 @@ def shortDescription(self): return """%s .decrypt() output of .encrypt() should not be garbled""" % (self.module_name,) def runTest(self): - - ## ECB mode - mode = self.module.MODE_ECB - encryption_cipher = self.module.new(a2b_hex(self.key), mode) - ciphertext = encryption_cipher.encrypt(self.plaintext) - decryption_cipher = self.module.new(a2b_hex(self.key), mode) - decrypted_plaintext = decryption_cipher.decrypt(ciphertext) - self.assertEqual(self.plaintext, decrypted_plaintext) - - ## OPENPGP mode - mode = self.module.MODE_OPENPGP - encryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv) - eiv_ciphertext = encryption_cipher.encrypt(self.plaintext) - eiv = eiv_ciphertext[:self.module.block_size+2] - ciphertext = eiv_ciphertext[self.module.block_size+2:] - decryption_cipher = self.module.new(a2b_hex(self.key), mode, eiv) - decrypted_plaintext = decryption_cipher.decrypt(ciphertext) - self.assertEqual(self.plaintext, decrypted_plaintext) - - ## All other non-AEAD modes (but CTR) - for mode in (self.module.MODE_CBC, self.module.MODE_CFB, self.module.MODE_OFB): + for mode in (self.module.MODE_ECB, self.module.MODE_CBC, self.module.MODE_CFB, self.module.MODE_OFB, self.module.MODE_OPENPGP): encryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv) ciphertext = encryption_cipher.encrypt(self.plaintext) - decryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv) + + if mode != self.module.MODE_OPENPGP: + decryption_cipher = self.module.new(a2b_hex(self.key), mode, self.iv) + else: + eiv = ciphertext[:self.module.block_size+2] + ciphertext = ciphertext[self.module.block_size+2:] + decryption_cipher = self.module.new(a2b_hex(self.key), mode, eiv) decrypted_plaintext = decryption_cipher.decrypt(ciphertext) self.assertEqual(self.plaintext, decrypted_plaintext) - class PGPTest(unittest.TestCase): def __init__(self, module, params): unittest.TestCase.__init__(self) @@ -664,17 +283,13 @@ def runTest(self): self.module.MODE_OFB, "") self.assertRaises(ValueError, self.module.new, a2b_hex(self.key), self.module.MODE_OPENPGP, "") - if hasattr(self.module, "MODE_CCM"): - for ivlen in (0,6,14): - self.assertRaises(ValueError, self.module.new, a2b_hex(self.key), - self.module.MODE_CCM, bchr(0)*ivlen, msg_len=10) self.module.new(a2b_hex(self.key), self.module.MODE_ECB, "") self.module.new(a2b_hex(self.key), self.module.MODE_CTR, "", counter=self._dummy_counter) def _dummy_counter(self): return "\0" * self.module.block_size -def make_block_tests(module, module_name, test_data, additional_params=dict()): +def make_block_tests(module, module_name, test_data): tests = [] extra_tests_added = 0 for i in range(len(test_data)): @@ -711,7 +326,6 @@ def make_block_tests(module, module_name, test_data, additional_params=dict()): name = "%s #%d: %s" % (module_name, i+1, description) params['description'] = name params['module_name'] = module_name - params.update(additional_params) # Add extra test(s) to the test suite before the current test if not extra_tests_added: @@ -725,18 +339,11 @@ def make_block_tests(module, module_name, test_data, additional_params=dict()): ] extra_tests_added = 1 - # Extract associated data and MAC for AEAD modes - if p_mode in ('CCM', 'EAX', 'SIV', 'GCM'): - assoc_data, params['plaintext'] = params['plaintext'].split('|') - assoc_data2, params['ciphertext'], params['mac'] = params['ciphertext'].split('|') - params['assoc_data'] = assoc_data.split("-") - params['mac_len'] = len(params['mac'])>>1 - # Add the current test to the test suite tests.append(CipherSelfTest(module, params)) # When using CTR mode, test that the interface behaves like a stream cipher - if p_mode in ('OFB', 'CTR'): + if p_mode == 'CTR': tests.append(CipherStreamingSelfTest(module, params)) # When using CTR mode, test the non-shortcut code path. @@ -748,25 +355,6 @@ def make_block_tests(module, module_name, test_data, additional_params=dict()): if not params2['ctr_params'].has_key('disable_shortcut'): params2['ctr_params']['disable_shortcut'] = 1 tests.append(CipherSelfTest(module, params2)) - - # Add tests that don't use test vectors - if hasattr(module, "MODE_CCM"): - tests += [ - CCMMACLengthTest(module), - CCMSplitEncryptionTest(module), - ] - for aead_mode in ("MODE_CCM","MODE_EAX", "MODE_SIV", "MODE_GCM"): - if hasattr(module, aead_mode): - key_sizes = [] - try: - key_sizes += module.key_size - except TypeError: - key_sizes = [ module.key_size ] - for ks in key_sizes: - tests += [ - AEADTests(module, aead_mode, ks), - ] - return tests def make_stream_tests(module, module_name, test_data): diff --git a/lib/Crypto/SelfTest/Cipher/test_AES.py b/lib/Crypto/SelfTest/Cipher/test_AES.py index f54f4733..ea7c323a 100644 --- a/lib/Crypto/SelfTest/Cipher/test_AES.py +++ b/lib/Crypto/SelfTest/Cipher/test_AES.py @@ -26,11 +26,8 @@ __revision__ = "$Id$" -import sys -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * -from Crypto.Util.py3compat import * from common import dict # For compatibility with Python 2.1 and 2.2 +from Crypto.Util.py3compat import * from binascii import hexlify # This is a list of (plaintext, ciphertext, key[, description[, params]]) tuples. @@ -1323,30 +1320,6 @@ 'NIST 800-38A, F.4.5, OFB and AES-256', dict(mode='OFB', iv='000102030405060708090a0b0c0d0e0f')), - ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ - '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17', - '3b3fd92eb72dad20333449f8e83cfb4a'+'7789508d16918f03f53c52dac54ed825'+ - '9740051e9c5fecf64344f7a82260edcc'+'304c6528f659c778', - '2b7e151628aed2a6abf7158809cf4f3c', - 'NIST 800-38A, F.4.1, OFB and AES-128 (partial last block)', - dict(mode='OFB', iv='000102030405060708090a0b0c0d0e0f')), - - ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ - '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17', - 'cdc80d6fddf18cab34c25909c99a4174'+'fcc28b8d4c63837c09e81700c1100401'+ - '8d9a9aeac0f6596f559c6d4daf59a5f2'+'6d9f200857ca6c3e', - '8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b', - 'NIST 800-38A, F.4.3, OFB and AES-192 (partial last block)', - dict(mode='OFB', iv='000102030405060708090a0b0c0d0e0f')), - - ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ - '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17', - 'dc7e84bfda79164b7ecd8486985d3860'+'4febdc6740d20b3ac88f6ad82a4fb08d'+ - '71ab47a086e86eedf39d1c5bba97c408'+'0126141d67f37be8', - '603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4', - 'NIST 800-38A, F.4.5, OFB and AES-256 (partial last block)', - dict(mode='OFB', iv='000102030405060708090a0b0c0d0e0f')), - ('6bc1bee22e409f96e93d7e117393172a'+'ae2d8a571e03ac9c9eb76fac45af8e51'+ '30c81c46a35ce411e5fbc1191a0a52ef'+'f69f2445df4f9b17ad2b417be66c3710', '874d6191b620e3261bef6864990db6ce'+'9806f66b7970fdff8617187bb9fffdff'+ @@ -1445,565 +1418,12 @@ '5baa61e4c9b93f3f0682250b6cf8331b', # Key (hash of 'password') 'GPG Test Vector #1', dict(mode='OPENPGP', iv='3d7d3e62282add7eb203eeba5c800733', encrypted_iv='fd934601ef49cb58b6d9aebca6056bdb96ef' ) ), - - # NIST SP 800-38C test vectors for CCM - # This is a list of tuples with 5 items: - # - # 1. Associated data + '|' + plaintext - # 2. Associated data + '|' + ciphertext + '|' + MAC - # 3. AES-128 key - # 4. Description - # 5. Dictionary of parameters to be passed to AES.new(). - # It must include the nonce. - # - ( '0001020304050607|20212223', - '0001020304050607|7162015b|4dac255d', - '404142434445464748494a4b4c4d4e4f', - 'NIST SP 800-38C Appex C.1', - dict(mode='CCM', nonce='10111213141516') - ), - ( '000102030405060708090a0b0c0d0e0f|202122232425262728292a2b2c2d2e2f', - '000102030405060708090a0b0c0d0e0f|d2a1f0e051ea5f62081a7792073d593d|1fc64fbfaccd', - '404142434445464748494a4b4c4d4e4f', - 'NIST SP 800-38C Appex C.2', - dict(mode='CCM', nonce='1011121314151617') - ), - ( '000102030405060708090a0b0c0d0e0f10111213|'+ - '202122232425262728292a2b2c2d2e2f3031323334353637', - '000102030405060708090a0b0c0d0e0f10111213|'+ - 'e3b201a9f5b71a7a9b1ceaeccd97e70b6176aad9a4428aa5|484392fbc1b09951', - '404142434445464748494a4b4c4d4e4f', - 'NIST SP 800-38C Appex C.3', - dict(mode='CCM', nonce='101112131415161718191a1b') - ), - ( - (''.join(["%02X" % (x*16+y) for x in xrange(0,16) for y in xrange(0,16)]))*256+'|'+ - '202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f', - (''.join(["%02X" % (x*16+y) for x in xrange(0,16) for y in xrange(0,16)]))*256+'|'+ - '69915dad1e84c6376a68c2967e4dab615ae0fd1faec44cc484828529463ccf72|'+ - 'b4ac6bec93e8598e7f0dadbcea5b', - '404142434445464748494a4b4c4d4e4f', - 'NIST SP 800-38C Appex C.4', - dict(mode='CCM', nonce='101112131415161718191a1b1c') - ), - # RFC3610 test vectors - ( - '0001020304050607|08090a0b0c0d0e0f101112131415161718191a1b1c1d1e', - '0001020304050607|588c979a61c663d2f066d0c2c0f989806d5f6b61dac384|'+ - '17e8d12cfdf926e0', - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', - 'RFC3610 Packet Vector #1', - dict(mode='CCM', nonce='00000003020100a0a1a2a3a4a5') - ), - ( - '0001020304050607|08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', - '0001020304050607|72c91a36e135f8cf291ca894085c87e3cc15c439c9e43a3b|'+ - 'a091d56e10400916', - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', - 'RFC3610 Packet Vector #2', - dict(mode='CCM', nonce='00000004030201a0a1a2a3a4a5') - ), - ( - '0001020304050607|08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20', - '0001020304050607|51b1e5f44a197d1da46b0f8e2d282ae871e838bb64da859657|'+ - '4adaa76fbd9fb0c5', - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', - 'RFC3610 Packet Vector #3', - dict(mode='CCM', nonce='00000005040302A0A1A2A3A4A5') - ), - ( - '000102030405060708090a0b|0c0d0e0f101112131415161718191a1b1c1d1e', - '000102030405060708090a0b|a28c6865939a9a79faaa5c4c2a9d4a91cdac8c|'+ - '96c861b9c9e61ef1', - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', - 'RFC3610 Packet Vector #4', - dict(mode='CCM', nonce='00000006050403a0a1a2a3a4a5') - ), - ( - '000102030405060708090a0b|0c0d0e0f101112131415161718191a1b1c1d1e1f', - '000102030405060708090a0b|dcf1fb7b5d9e23fb9d4e131253658ad86ebdca3e|'+ - '51e83f077d9c2d93', - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', - 'RFC3610 Packet Vector #5', - dict(mode='CCM', nonce='00000007060504a0a1a2a3a4a5') - ), - ( - '000102030405060708090a0b|0c0d0e0f101112131415161718191a1b1c1d1e1f20', - '000102030405060708090a0b|6fc1b011f006568b5171a42d953d469b2570a4bd87|'+ - '405a0443ac91cb94', - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', - 'RFC3610 Packet Vector #6', - dict(mode='CCM', nonce='00000008070605a0a1a2a3a4a5') - ), - ( - '0001020304050607|08090a0b0c0d0e0f101112131415161718191a1b1c1d1e', - '0001020304050607|0135d1b2c95f41d5d1d4fec185d166b8094e999dfed96c|'+ - '048c56602c97acbb7490', - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', - 'RFC3610 Packet Vector #7', - dict(mode='CCM', nonce='00000009080706a0a1a2a3a4a5') - ), - ( - '0001020304050607|08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f', - '0001020304050607|7b75399ac0831dd2f0bbd75879a2fd8f6cae6b6cd9b7db24|'+ - 'c17b4433f434963f34b4', - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', - 'RFC3610 Packet Vector #8', - dict(mode='CCM', nonce='0000000a090807a0a1a2a3a4a5') - ), - ( - '0001020304050607|08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20', - '0001020304050607|82531a60cc24945a4b8279181ab5c84df21ce7f9b73f42e197|'+ - 'ea9c07e56b5eb17e5f4e', - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', - 'RFC3610 Packet Vector #9', - dict(mode='CCM', nonce='0000000b0a0908a0a1a2a3a4a5') - ), - ( - '000102030405060708090a0b|0c0d0e0f101112131415161718191a1b1c1d1e', - '000102030405060708090a0b|07342594157785152b074098330abb141b947b|'+ - '566aa9406b4d999988dd', - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', - 'RFC3610 Packet Vector #10', - dict(mode='CCM', nonce='0000000c0b0a09a0a1a2a3a4a5') - ), - ( - '000102030405060708090a0b|0c0d0e0f101112131415161718191a1b1c1d1e1f', - '000102030405060708090a0b|676bb20380b0e301e8ab79590a396da78b834934|'+ - 'f53aa2e9107a8b6c022c', - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', - 'RFC3610 Packet Vector #11', - dict(mode='CCM', nonce='0000000d0c0b0aa0a1a2a3a4a5') - ), - ( - '000102030405060708090a0b|0c0d0e0f101112131415161718191a1b1c1d1e1f20', - '000102030405060708090a0b|c0ffa0d6f05bdb67f24d43a4338d2aa4bed7b20e43|'+ - 'cd1aa31662e7ad65d6db', - 'c0c1c2c3c4c5c6c7c8c9cacbcccdcecf', - 'RFC3610 Packet Vector #12', - dict(mode='CCM', nonce='0000000e0d0c0ba0a1a2a3a4a5') - ), - ( - '0be1a88bace018b1|08e8cf97d820ea258460e96ad9cf5289054d895ceac47c', - '0be1a88bace018b1|4cb97f86a2a4689a877947ab8091ef5386a6ffbdd080f8|'+ - 'e78cf7cb0cddd7b3', - 'd7828d13b2b0bdc325a76236df93cc6b', - 'RFC3610 Packet Vector #13', - dict(mode='CCM', nonce='00412b4ea9cdbe3c9696766cfa') - ), - ( - '63018f76dc8a1bcb|9020ea6f91bdd85afa0039ba4baff9bfb79c7028949cd0ec', - '63018f76dc8a1bcb|4ccb1e7ca981befaa0726c55d378061298c85c92814abc33|'+ - 'c52ee81d7d77c08a', - 'd7828d13b2b0bdc325a76236df93cc6b', - 'RFC3610 Packet Vector #14', - dict(mode='CCM', nonce='0033568ef7b2633c9696766cfa') - ), - ( - 'aa6cfa36cae86b40|b916e0eacc1c00d7dcec68ec0b3bbb1a02de8a2d1aa346132e', - 'aa6cfa36cae86b40|b1d23a2220ddc0ac900d9aa03c61fcf4a559a4417767089708|'+ - 'a776796edb723506', - 'd7828d13b2b0bdc325a76236df93cc6b', - 'RFC3610 Packet Vector #15', - dict(mode='CCM', nonce='00103fe41336713c9696766cfa') - ), - ( - 'd0d0735c531e1becf049c244|12daac5630efa5396f770ce1a66b21f7b2101c', - 'd0d0735c531e1becf049c244|14d253c3967b70609b7cbb7c49916028324526|'+ - '9a6f49975bcadeaf', - 'd7828d13b2b0bdc325a76236df93cc6b', - 'RFC3610 Packet Vector #16', - dict(mode='CCM', nonce='00764c63b8058e3c9696766cfa') - ), - ( - '77b60f011c03e1525899bcae|e88b6a46c78d63e52eb8c546efb5de6f75e9cc0d', - '77b60f011c03e1525899bcae|5545ff1a085ee2efbf52b2e04bee1e2336c73e3f|'+ - '762c0c7744fe7e3c', - 'd7828d13b2b0bdc325a76236df93cc6b', - 'RFC3610 Packet Vector #17', - dict(mode='CCM', nonce='00f8b678094e3b3c9696766cfa') - ), - ( - 'cd9044d2b71fdb8120ea60c0|6435acbafb11a82e2f071d7ca4a5ebd93a803ba87f', - 'cd9044d2b71fdb8120ea60c0|009769ecabdf48625594c59251e6035722675e04c8|'+ - '47099e5ae0704551', - 'd7828d13b2b0bdc325a76236df93cc6b', - 'RFC3610 Packet Vector #18', - dict(mode='CCM', nonce='00d560912d3f703c9696766cfa') - ), - ( - 'd85bc7e69f944fb8|8a19b950bcf71a018e5e6701c91787659809d67dbedd18', - 'd85bc7e69f944fb8|bc218daa947427b6db386a99ac1aef23ade0b52939cb6a|'+ - '637cf9bec2408897c6ba', - 'd7828d13b2b0bdc325a76236df93cc6b', - 'RFC3610 Packet Vector #19', - dict(mode='CCM', nonce='0042fff8f1951c3c9696766cfa') - ), - ( - '74a0ebc9069f5b37|1761433c37c5a35fc1f39f406302eb907c6163be38c98437', - '74a0ebc9069f5b37|5810e6fd25874022e80361a478e3e9cf484ab04f447efff6|'+ - 'f0a477cc2fc9bf548944', - 'd7828d13b2b0bdc325a76236df93cc6b', - 'RFC3610 Packet Vector #20', - dict(mode='CCM', nonce='00920f40e56cdc3c9696766cfa') - ), - ( - '44a3aa3aae6475ca|a434a8e58500c6e41530538862d686ea9e81301b5ae4226bfa', - '44a3aa3aae6475ca|f2beed7bc5098e83feb5b31608f8e29c38819a89c8e776f154|'+ - '4d4151a4ed3a8b87b9ce', - 'd7828d13b2b0bdc325a76236df93cc6b', - 'RFC3610 Packet Vector #21', - dict(mode='CCM', nonce='0027ca0c7120bc3c9696766cfa') - ), - ( - 'ec46bb63b02520c33c49fd70|b96b49e21d621741632875db7f6c9243d2d7c2', - 'ec46bb63b02520c33c49fd70|31d750a09da3ed7fddd49a2032aabf17ec8ebf|'+ - '7d22c8088c666be5c197', - 'd7828d13b2b0bdc325a76236df93cc6b', - 'RFC3610 Packet Vector #22', - dict(mode='CCM', nonce='005b8ccbcd9af83c9696766cfa') - ), - ( - '47a65ac78b3d594227e85e71|e2fcfbb880442c731bf95167c8ffd7895e337076', - '47a65ac78b3d594227e85e71|e882f1dbd38ce3eda7c23f04dd65071eb41342ac|'+ - 'df7e00dccec7ae52987d', - 'd7828d13b2b0bdc325a76236df93cc6b', - 'RFC3610 Packet Vector #23', - dict(mode='CCM', nonce='003ebe94044b9a3c9696766cfa') - ), - ( - '6e37a6ef546d955d34ab6059|abf21c0b02feb88f856df4a37381bce3cc128517d4', - '6e37a6ef546d955d34ab6059|f32905b88a641b04b9c9ffb58cc390900f3da12ab1|'+ - '6dce9e82efa16da62059', - 'd7828d13b2b0bdc325a76236df93cc6b', - 'RFC3610 Packet Vector #24', - dict(mode='CCM', nonce='008d493b30ae8b3c9696766cfa') - ), - - # Test vectors for EAX taken from http://www.cs.ucdavis.edu/~rogaway/papers/eax.pdf - # This is a list of tuples with 5 items: - # - # 1. Header + '|' + plaintext - # 2. Header + '|' + ciphertext + '|' + MAC - # 3. AES-128 key - # 4. Description - # 5. Dictionary of parameters to be passed to AES.new(). It must - # include the nonce. - # - ( '6bfb914fd07eae6b|', - '6bfb914fd07eae6b||e037830e8389f27b025a2d6527e79d01', - '233952dee4d5ed5f9b9c6d6ff80ff478', - 'EAX spec Appendix G', - dict(mode='EAX', nonce='62EC67F9C3A4A407FCB2A8C49031A8B3') - ), - - ( 'fa3bfd4806eb53fa|f7fb', - 'fa3bfd4806eb53fa|19dd|5c4c9331049d0bdab0277408f67967e5', - '91945d3f4dcbee0bf45ef52255f095a4', - 'EAX spec Appendix G', - dict(mode='EAX', nonce='BECAF043B0A23D843194BA972C66DEBD') - ), - - ( '234a3463c1264ac6|1a47cb4933', - '234a3463c1264ac6|d851d5bae0|3a59f238a23e39199dc9266626c40f80', - '01f74ad64077f2e704c0f60ada3dd523', - 'EAX spec Appendix G', - dict(mode='EAX', nonce='70C3DB4F0D26368400A10ED05D2BFF5E') - ), - - ( '33cce2eabff5a79d|481c9e39b1', - '33cce2eabff5a79d|632a9d131a|d4c168a4225d8e1ff755939974a7bede', - 'd07cf6cbb7f313bdde66b727afd3c5e8', - 'EAX spec Appendix G', - dict(mode='EAX', nonce='8408DFFF3C1A2B1292DC199E46B7D617') - ), - - ( 'aeb96eaebe2970e9|40d0c07da5e4', - 'aeb96eaebe2970e9|071dfe16c675|cb0677e536f73afe6a14b74ee49844dd', - '35b6d0580005bbc12b0587124557d2c2', - 'EAX spec Appendix G', - dict(mode='EAX', nonce='FDB6B06676EEDC5C61D74276E1F8E816') - ), - - ( 'd4482d1ca78dce0f|4de3b35c3fc039245bd1fb7d', - 'd4482d1ca78dce0f|835bb4f15d743e350e728414|abb8644fd6ccb86947c5e10590210a4f', - 'bd8e6e11475e60b268784c38c62feb22', - 'EAX spec Appendix G', - dict(mode='EAX', nonce='6EAC5C93072D8E8513F750935E46DA1B') - ), - - ( '65d2017990d62528|8b0a79306c9ce7ed99dae4f87f8dd61636', - '65d2017990d62528|02083e3979da014812f59f11d52630da30|137327d10649b0aa6e1c181db617d7f2', - '7c77d6e813bed5ac98baa417477a2e7d', - 'EAX spec Appendix G', - dict(mode='EAX', nonce='1A8C98DCD73D38393B2BF1569DEEFC19') - ), - - ( '54b9f04e6a09189a|1bda122bce8a8dbaf1877d962b8592dd2d56', - '54b9f04e6a09189a|2ec47b2c4954a489afc7ba4897edcdae8cc3|3b60450599bd02c96382902aef7f832a', - '5fff20cafab119ca2fc73549e20f5b0d', - 'EAX spec Appendix G', - dict(mode='EAX', nonce='DDE59B97D722156D4D9AFF2BC7559826') - ), - - ( '899a175897561d7e|6cf36720872b8513f6eab1a8a44438d5ef11', - '899a175897561d7e|0de18fd0fdd91e7af19f1d8ee8733938b1e8|e7f6d2231618102fdb7fe55ff1991700', - 'a4a4782bcffd3ec5e7ef6d8c34a56123', - 'EAX spec Appendix G', - dict(mode='EAX', nonce='B781FCF2F75FA5A8DE97A9CA48E522EC') - ), - - ( '126735fcc320d25a|ca40d7446e545ffaed3bd12a740a659ffbbb3ceab7', - '126735fcc320d25a|cb8920f87a6c75cff39627b56e3ed197c552d295a7|cfc46afc253b4652b1af3795b124ab6e', - '8395fcf1e95bebd697bd010bc766aac3', - 'EAX spec Appendix G', - dict(mode='EAX', nonce='22E7ADD93CFC6393C57EC0B3C17D6B44') - ), - - # Test vectors for SIV taken from RFC5297 - # This is a list of tuples with 5 items: - # - # 1. Header + '|' + plaintext - # 2. Header + '|' + ciphertext + '|' + MAC - # 3. AES-128 key - # 4. Description - # 5. Dictionary of parameters to be passed to AES.new(). - # It must include the nonce. - # - # A "Header" is a dash ('-') separated sequece of components. - # - ( '101112131415161718191a1b1c1d1e1f2021222324252627|112233445566778899aabbccddee', - '101112131415161718191a1b1c1d1e1f2021222324252627|40c02b9690c4dc04daef7f6afe5c|' + - '85632d07c6e8f37f950acd320a2ecc93', - 'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff', - 'RFC5297 A.1', - dict(mode='SIV', nonce=None) - ), - - ( '00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddccbbaa9988' + - '7766554433221100-102030405060708090a0|' + - '7468697320697320736f6d6520706c61696e7465787420746f20656e63727970' + - '74207573696e67205349562d414553', - - '00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddccbbaa9988' + - '7766554433221100-102030405060708090a0|' + - 'cb900f2fddbe404326601965c889bf17dba77ceb094fa663b7a3f748ba8af829' + - 'ea64ad544a272e9c485b62a3fd5c0d|' + - '7bdb6e3b432667eb06f4d14bff2fbd0f', - - '7f7e7d7c7b7a79787776757473727170404142434445464748494a4b4c4d4e4f', - 'RFC5297 A.2', - dict(mode='SIV', nonce='09f911029d74e35bd84156c5635688c0') - ), - - # Test vectors for GCM taken from - # http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf - # This is a list of tuples with 5 items: - # - # 1. Header + '|' + plaintext - # 2. Header + '|' + ciphertext + '|' + MAC - # 3. AES-128 key - # 4. Description - # 5. Dictionary of parameters to be passed to AES.new(). - # It must include the nonce. - # - ( '|', - '||58e2fccefa7e3061367f1d57a4e7455a', - '00000000000000000000000000000000', - 'GCM Test Case 1', - dict(mode='GCM', nonce='000000000000000000000000') - ), - - ( '|00000000000000000000000000000000', - '|0388dace60b6a392f328c2b971b2fe78|ab6e47d42cec13bdf53a67b21257bddf', - '00000000000000000000000000000000', - 'GCM Test Case 2', - dict(mode='GCM', nonce='000000000000000000000000') - ), - - ( '|d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255', - '|42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e' + - '21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985|' + - '4d5c2af327cd64a62cf35abd2ba6fab4', - 'feffe9928665731c6d6a8f9467308308', - 'GCM Test Case 3', - dict(mode='GCM', nonce='cafebabefacedbaddecaf888') - ), - - ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', - 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - '42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e' + - '21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091|' + - '5bc94fbc3221a5db94fae95ae7121a47', - 'feffe9928665731c6d6a8f9467308308', - 'GCM Test Case 4', - dict(mode='GCM', nonce='cafebabefacedbaddecaf888') - ), - - ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', - 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - '61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c7423' + - '73806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598|' + - '3612d2e79e3b0785561be14aaca2fccb', - 'feffe9928665731c6d6a8f9467308308', - 'GCM Test Case 5', - dict(mode='GCM', nonce='cafebabefacedbad') - ), - - ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', - 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - '8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca7' + - '01e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5|' + - '619cc5aefffe0bfa462af43c1699d050', - 'feffe9928665731c6d6a8f9467308308', - 'GCM Test Case 6', - dict(mode='GCM', nonce='9313225df88406e555909c5aff5269aa'+ - '6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254'+ - '16aedbf5a0de6a57a637b39b' ) - ), - - ( '|', - '||cd33b28ac773f74ba00ed1f312572435', - '000000000000000000000000000000000000000000000000', - 'GCM Test Case 7', - dict(mode='GCM', nonce='000000000000000000000000') - ), - - ( '|00000000000000000000000000000000', - '|98e7247c07f0fe411c267e4384b0f600|2ff58d80033927ab8ef4d4587514f0fb', - '000000000000000000000000000000000000000000000000', - 'GCM Test Case 8', - dict(mode='GCM', nonce='000000000000000000000000') - ), - - ( '|d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255', - '|3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c' + - '7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256|' + - '9924a7c8587336bfb118024db8674a14', - 'feffe9928665731c6d6a8f9467308308feffe9928665731c', - 'GCM Test Case 9', - dict(mode='GCM', nonce='cafebabefacedbaddecaf888') - ), - - ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', - 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - '3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c' + - '7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710|' + - '2519498e80f1478f37ba55bd6d27618c', - 'feffe9928665731c6d6a8f9467308308feffe9928665731c', - 'GCM Test Case 10', - dict(mode='GCM', nonce='cafebabefacedbaddecaf888') - ), - - ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', - 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - '0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057' + - 'fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7|' + - '65dcc57fcf623a24094fcca40d3533f8', - 'feffe9928665731c6d6a8f9467308308feffe9928665731c', - 'GCM Test Case 11', - dict(mode='GCM', nonce='cafebabefacedbad') - ), - - ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', - 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - 'd27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e45' + - '81e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b|' + - 'dcf566ff291c25bbb8568fc3d376a6d9', - 'feffe9928665731c6d6a8f9467308308feffe9928665731c', - 'GCM Test Case 12', - dict(mode='GCM', nonce='9313225df88406e555909c5aff5269aa'+ - '6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254'+ - '16aedbf5a0de6a57a637b39b' ) - ), - - ( '|', - '||530f8afbc74536b9a963b4f1c4cb738b', - '0000000000000000000000000000000000000000000000000000000000000000', - 'GCM Test Case 13', - dict(mode='GCM', nonce='000000000000000000000000') - ), - - ( '|00000000000000000000000000000000', - '|cea7403d4d606b6e074ec5d3baf39d18|d0d1c8a799996bf0265b98b5d48ab919', - '0000000000000000000000000000000000000000000000000000000000000000', - 'GCM Test Case 14', - dict(mode='GCM', nonce='000000000000000000000000') - ), - - ( '|d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255', - '|522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa' + - '8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad|' + - 'b094dac5d93471bdec1a502270e3cc6c', - 'feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308', - 'GCM Test Case 15', - dict(mode='GCM', nonce='cafebabefacedbaddecaf888') - ), - - ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', - 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - '522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa' + - '8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662|' + - '76fc6ece0f4e1768cddf8853bb2d551b', - 'feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308', - 'GCM Test Case 16', - dict(mode='GCM', nonce='cafebabefacedbaddecaf888') - ), - - ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', - 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - 'c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0' + - 'feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f|' + - '3a337dbf46a792c45e454913fe2ea8f2', - 'feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308', - 'GCM Test Case 17', - dict(mode='GCM', nonce='cafebabefacedbad') - ), - - ( 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - 'd9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a72' + - '1c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39', - 'feedfacedeadbeeffeedfacedeadbeefabaddad2|' + - '5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf4' + - '0fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f|' + - 'a44a8266ee1c8eb0c8b5d4cf5ae9f19a', - 'feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308', - 'GCM Test Case 18', - dict(mode='GCM', nonce='9313225df88406e555909c5aff5269aa'+ - '6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b5254'+ - '16aedbf5a0de6a57a637b39b' ) - ), ] def get_tests(config={}): from Crypto.Cipher import AES - from Crypto.Util import cpuid from common import make_block_tests - - tests = make_block_tests(AES, "AES", test_data, {'use_aesni': False}) - if cpuid.have_aes_ni(): - # Run tests with AES-NI instructions if they are available. - tests += make_block_tests(AES, "AESNI", test_data, {'use_aesni': True}) - return tests + return make_block_tests(AES, "AES", test_data) if __name__ == '__main__': import unittest diff --git a/lib/Crypto/SelfTest/Cipher/test_ARC4.py b/lib/Crypto/SelfTest/Cipher/test_ARC4.py index 801d2cb3..4e039d1c 100644 --- a/lib/Crypto/SelfTest/Cipher/test_ARC4.py +++ b/lib/Crypto/SelfTest/Cipher/test_ARC4.py @@ -27,10 +27,6 @@ __revision__ = "$Id$" from Crypto.Util.py3compat import * -from Crypto.SelfTest.st_common import * -from binascii import unhexlify - -from Crypto.Cipher import ARC4 # This is a list of (plaintext, ciphertext, key[, description]) tuples. test_data = [ @@ -72,382 +68,10 @@ "Test vector 4"), ] -class RFC6229_Tests(unittest.TestCase): - # Test vectors from RFC 6229. Each test vector is a tuple with two items: - # the ARC4 key and a dictionary. The dictionary has keystream offsets as keys - # and the 16-byte keystream starting at the relevant offset as value. - rfc6229_data = [ - # Page 3 - ( - '0102030405', - { - 0: 'b2 39 63 05 f0 3d c0 27 cc c3 52 4a 0a 11 18 a8', - 16: '69 82 94 4f 18 fc 82 d5 89 c4 03 a4 7a 0d 09 19', - 240: '28 cb 11 32 c9 6c e2 86 42 1d ca ad b8 b6 9e ae', - 256: '1c fc f6 2b 03 ed db 64 1d 77 df cf 7f 8d 8c 93', - 496: '42 b7 d0 cd d9 18 a8 a3 3d d5 17 81 c8 1f 40 41', - 512: '64 59 84 44 32 a7 da 92 3c fb 3e b4 98 06 61 f6', - 752: 'ec 10 32 7b de 2b ee fd 18 f9 27 76 80 45 7e 22', - 768: 'eb 62 63 8d 4f 0b a1 fe 9f ca 20 e0 5b f8 ff 2b', - 1008:'45 12 90 48 e6 a0 ed 0b 56 b4 90 33 8f 07 8d a5', - 1024:'30 ab bc c7 c2 0b 01 60 9f 23 ee 2d 5f 6b b7 df', - 1520:'32 94 f7 44 d8 f9 79 05 07 e7 0f 62 e5 bb ce ea', - 1536:'d8 72 9d b4 18 82 25 9b ee 4f 82 53 25 f5 a1 30', - 2032:'1e b1 4a 0c 13 b3 bf 47 fa 2a 0b a9 3a d4 5b 8b', - 2048:'cc 58 2f 8b a9 f2 65 e2 b1 be 91 12 e9 75 d2 d7', - 3056:'f2 e3 0f 9b d1 02 ec bf 75 aa ad e9 bc 35 c4 3c', - 3072:'ec 0e 11 c4 79 dc 32 9d c8 da 79 68 fe 96 56 81', - 4080:'06 83 26 a2 11 84 16 d2 1f 9d 04 b2 cd 1c a0 50', - 4096:'ff 25 b5 89 95 99 67 07 e5 1f bd f0 8b 34 d8 75' - } - ), - # Page 4 - ( - '01020304050607', - { - 0: '29 3f 02 d4 7f 37 c9 b6 33 f2 af 52 85 fe b4 6b', - 16: 'e6 20 f1 39 0d 19 bd 84 e2 e0 fd 75 20 31 af c1', - 240: '91 4f 02 53 1c 92 18 81 0d f6 0f 67 e3 38 15 4c', - 256: 'd0 fd b5 83 07 3c e8 5a b8 39 17 74 0e c0 11 d5', - 496: '75 f8 14 11 e8 71 cf fa 70 b9 0c 74 c5 92 e4 54', - 512: '0b b8 72 02 93 8d ad 60 9e 87 a5 a1 b0 79 e5 e4', - 752: 'c2 91 12 46 b6 12 e7 e7 b9 03 df ed a1 da d8 66', - 768: '32 82 8f 91 50 2b 62 91 36 8d e8 08 1d e3 6f c2', - 1008:'f3 b9 a7 e3 b2 97 bf 9a d8 04 51 2f 90 63 ef f1', - 1024:'8e cb 67 a9 ba 1f 55 a5 a0 67 e2 b0 26 a3 67 6f', - 1520:'d2 aa 90 2b d4 2d 0d 7c fd 34 0c d4 58 10 52 9f', - 1536:'78 b2 72 c9 6e 42 ea b4 c6 0b d9 14 e3 9d 06 e3', - 2032:'f4 33 2f d3 1a 07 93 96 ee 3c ee 3f 2a 4f f0 49', - 2048:'05 45 97 81 d4 1f da 7f 30 c1 be 7e 12 46 c6 23', - 3056:'ad fd 38 68 b8 e5 14 85 d5 e6 10 01 7e 3d d6 09', - 3072:'ad 26 58 1c 0c 5b e4 5f 4c ea 01 db 2f 38 05 d5', - 4080:'f3 17 2c ef fc 3b 3d 99 7c 85 cc d5 af 1a 95 0c', - 4096:'e7 4b 0b 97 31 22 7f d3 7c 0e c0 8a 47 dd d8 b8' - } - ), - ( - '0102030405060708', - { - 0: '97 ab 8a 1b f0 af b9 61 32 f2 f6 72 58 da 15 a8', - 16: '82 63 ef db 45 c4 a1 86 84 ef 87 e6 b1 9e 5b 09', - 240: '96 36 eb c9 84 19 26 f4 f7 d1 f3 62 bd df 6e 18', - 256: 'd0 a9 90 ff 2c 05 fe f5 b9 03 73 c9 ff 4b 87 0a', - 496: '73 23 9f 1d b7 f4 1d 80 b6 43 c0 c5 25 18 ec 63', - 512: '16 3b 31 99 23 a6 bd b4 52 7c 62 61 26 70 3c 0f', - 752: '49 d6 c8 af 0f 97 14 4a 87 df 21 d9 14 72 f9 66', - 768: '44 17 3a 10 3b 66 16 c5 d5 ad 1c ee 40 c8 63 d0', - 1008:'27 3c 9c 4b 27 f3 22 e4 e7 16 ef 53 a4 7d e7 a4', - 1024:'c6 d0 e7 b2 26 25 9f a9 02 34 90 b2 61 67 ad 1d', - 1520:'1f e8 98 67 13 f0 7c 3d 9a e1 c1 63 ff 8c f9 d3', - 1536:'83 69 e1 a9 65 61 0b e8 87 fb d0 c7 91 62 aa fb', - 2032:'0a 01 27 ab b4 44 84 b9 fb ef 5a bc ae 1b 57 9f', - 2048:'c2 cd ad c6 40 2e 8e e8 66 e1 f3 7b db 47 e4 2c', - 3056:'26 b5 1e a3 7d f8 e1 d6 f7 6f c3 b6 6a 74 29 b3', - 3072:'bc 76 83 20 5d 4f 44 3d c1 f2 9d da 33 15 c8 7b', - 4080:'d5 fa 5a 34 69 d2 9a aa f8 3d 23 58 9d b8 c8 5b', - 4096:'3f b4 6e 2c 8f 0f 06 8e dc e8 cd cd 7d fc 58 62' - } - ), - # Page 5 - ( - '0102030405060708090a', - { - 0: 'ed e3 b0 46 43 e5 86 cc 90 7d c2 18 51 70 99 02', - 16: '03 51 6b a7 8f 41 3b eb 22 3a a5 d4 d2 df 67 11', - 240: '3c fd 6c b5 8e e0 fd de 64 01 76 ad 00 00 04 4d', - 256: '48 53 2b 21 fb 60 79 c9 11 4c 0f fd 9c 04 a1 ad', - 496: '3e 8c ea 98 01 71 09 97 90 84 b1 ef 92 f9 9d 86', - 512: 'e2 0f b4 9b db 33 7e e4 8b 8d 8d c0 f4 af ef fe', - 752: '5c 25 21 ea cd 79 66 f1 5e 05 65 44 be a0 d3 15', - 768: 'e0 67 a7 03 19 31 a2 46 a6 c3 87 5d 2f 67 8a cb', - 1008:'a6 4f 70 af 88 ae 56 b6 f8 75 81 c0 e2 3e 6b 08', - 1024:'f4 49 03 1d e3 12 81 4e c6 f3 19 29 1f 4a 05 16', - 1520:'bd ae 85 92 4b 3c b1 d0 a2 e3 3a 30 c6 d7 95 99', - 1536:'8a 0f ed db ac 86 5a 09 bc d1 27 fb 56 2e d6 0a', - 2032:'b5 5a 0a 5b 51 a1 2a 8b e3 48 99 c3 e0 47 51 1a', - 2048:'d9 a0 9c ea 3c e7 5f e3 96 98 07 03 17 a7 13 39', - 3056:'55 22 25 ed 11 77 f4 45 84 ac 8c fa 6c 4e b5 fc', - 3072:'7e 82 cb ab fc 95 38 1b 08 09 98 44 21 29 c2 f8', - 4080:'1f 13 5e d1 4c e6 0a 91 36 9d 23 22 be f2 5e 3c', - 4096:'08 b6 be 45 12 4a 43 e2 eb 77 95 3f 84 dc 85 53' - } - ), - ( - '0102030405060708090a0b0c0d0e0f10', - { - 0: '9a c7 cc 9a 60 9d 1e f7 b2 93 28 99 cd e4 1b 97', - 16: '52 48 c4 95 90 14 12 6a 6e 8a 84 f1 1d 1a 9e 1c', - 240: '06 59 02 e4 b6 20 f6 cc 36 c8 58 9f 66 43 2f 2b', - 256: 'd3 9d 56 6b c6 bc e3 01 07 68 15 15 49 f3 87 3f', - 496: 'b6 d1 e6 c4 a5 e4 77 1c ad 79 53 8d f2 95 fb 11', - 512: 'c6 8c 1d 5c 55 9a 97 41 23 df 1d bc 52 a4 3b 89', - 752: 'c5 ec f8 8d e8 97 fd 57 fe d3 01 70 1b 82 a2 59', - 768: 'ec cb e1 3d e1 fc c9 1c 11 a0 b2 6c 0b c8 fa 4d', - 1008:'e7 a7 25 74 f8 78 2a e2 6a ab cf 9e bc d6 60 65', - 1024:'bd f0 32 4e 60 83 dc c6 d3 ce dd 3c a8 c5 3c 16', - 1520:'b4 01 10 c4 19 0b 56 22 a9 61 16 b0 01 7e d2 97', - 1536:'ff a0 b5 14 64 7e c0 4f 63 06 b8 92 ae 66 11 81', - 2032:'d0 3d 1b c0 3c d3 3d 70 df f9 fa 5d 71 96 3e bd', - 2048:'8a 44 12 64 11 ea a7 8b d5 1e 8d 87 a8 87 9b f5', - 3056:'fa be b7 60 28 ad e2 d0 e4 87 22 e4 6c 46 15 a3', - 3072:'c0 5d 88 ab d5 03 57 f9 35 a6 3c 59 ee 53 76 23', - 4080:'ff 38 26 5c 16 42 c1 ab e8 d3 c2 fe 5e 57 2b f8', - 4096:'a3 6a 4c 30 1a e8 ac 13 61 0c cb c1 22 56 ca cc' - } - ), - # Page 6 - ( - '0102030405060708090a0b0c0d0e0f101112131415161718', - { - 0: '05 95 e5 7f e5 f0 bb 3c 70 6e da c8 a4 b2 db 11', - 16: 'df de 31 34 4a 1a f7 69 c7 4f 07 0a ee 9e 23 26', - 240: 'b0 6b 9b 1e 19 5d 13 d8 f4 a7 99 5c 45 53 ac 05', - 256: '6b d2 37 8e c3 41 c9 a4 2f 37 ba 79 f8 8a 32 ff', - 496: 'e7 0b ce 1d f7 64 5a db 5d 2c 41 30 21 5c 35 22', - 512: '9a 57 30 c7 fc b4 c9 af 51 ff da 89 c7 f1 ad 22', - 752: '04 85 05 5f d4 f6 f0 d9 63 ef 5a b9 a5 47 69 82', - 768: '59 1f c6 6b cd a1 0e 45 2b 03 d4 55 1f 6b 62 ac', - 1008:'27 53 cc 83 98 8a fa 3e 16 88 a1 d3 b4 2c 9a 02', - 1024:'93 61 0d 52 3d 1d 3f 00 62 b3 c2 a3 bb c7 c7 f0', - 1520:'96 c2 48 61 0a ad ed fe af 89 78 c0 3d e8 20 5a', - 1536:'0e 31 7b 3d 1c 73 b9 e9 a4 68 8f 29 6d 13 3a 19', - 2032:'bd f0 e6 c3 cc a5 b5 b9 d5 33 b6 9c 56 ad a1 20', - 2048:'88 a2 18 b6 e2 ec e1 e6 24 6d 44 c7 59 d1 9b 10', - 3056:'68 66 39 7e 95 c1 40 53 4f 94 26 34 21 00 6e 40', - 3072:'32 cb 0a 1e 95 42 c6 b3 b8 b3 98 ab c3 b0 f1 d5', - 4080:'29 a0 b8 ae d5 4a 13 23 24 c6 2e 42 3f 54 b4 c8', - 4096:'3c b0 f3 b5 02 0a 98 b8 2a f9 fe 15 44 84 a1 68' - } - ), - ( - '0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20', - { - 0: 'ea a6 bd 25 88 0b f9 3d 3f 5d 1e 4c a2 61 1d 91', - 16: 'cf a4 5c 9f 7e 71 4b 54 bd fa 80 02 7c b1 43 80', - 240: '11 4a e3 44 de d7 1b 35 f2 e6 0f eb ad 72 7f d8', - 256: '02 e1 e7 05 6b 0f 62 39 00 49 64 22 94 3e 97 b6', - 496: '91 cb 93 c7 87 96 4e 10 d9 52 7d 99 9c 6f 93 6b', - 512: '49 b1 8b 42 f8 e8 36 7c be b5 ef 10 4b a1 c7 cd', - 752: '87 08 4b 3b a7 00 ba de 95 56 10 67 27 45 b3 74', - 768: 'e7 a7 b9 e9 ec 54 0d 5f f4 3b db 12 79 2d 1b 35', - 1008:'c7 99 b5 96 73 8f 6b 01 8c 76 c7 4b 17 59 bd 90', - 1024:'7f ec 5b fd 9f 9b 89 ce 65 48 30 90 92 d7 e9 58', - 1520:'40 f2 50 b2 6d 1f 09 6a 4a fd 4c 34 0a 58 88 15', - 1536:'3e 34 13 5c 79 db 01 02 00 76 76 51 cf 26 30 73', - 2032:'f6 56 ab cc f8 8d d8 27 02 7b 2c e9 17 d4 64 ec', - 2048:'18 b6 25 03 bf bc 07 7f ba bb 98 f2 0d 98 ab 34', - 3056:'8a ed 95 ee 5b 0d cb fb ef 4e b2 1d 3a 3f 52 f9', - 3072:'62 5a 1a b0 0e e3 9a 53 27 34 6b dd b0 1a 9c 18', - 4080:'a1 3a 7c 79 c7 e1 19 b5 ab 02 96 ab 28 c3 00 b9', - 4096:'f3 e4 c0 a2 e0 2d 1d 01 f7 f0 a7 46 18 af 2b 48' - } - ), - # Page 7 - ( - '833222772a', - { - 0: '80 ad 97 bd c9 73 df 8a 2e 87 9e 92 a4 97 ef da', - 16: '20 f0 60 c2 f2 e5 12 65 01 d3 d4 fe a1 0d 5f c0', - 240: 'fa a1 48 e9 90 46 18 1f ec 6b 20 85 f3 b2 0e d9', - 256: 'f0 da f5 ba b3 d5 96 83 98 57 84 6f 73 fb fe 5a', - 496: '1c 7e 2f c4 63 92 32 fe 29 75 84 b2 96 99 6b c8', - 512: '3d b9 b2 49 40 6c c8 ed ff ac 55 cc d3 22 ba 12', - 752: 'e4 f9 f7 e0 06 61 54 bb d1 25 b7 45 56 9b c8 97', - 768: '75 d5 ef 26 2b 44 c4 1a 9c f6 3a e1 45 68 e1 b9', - 1008:'6d a4 53 db f8 1e 82 33 4a 3d 88 66 cb 50 a1 e3', - 1024:'78 28 d0 74 11 9c ab 5c 22 b2 94 d7 a9 bf a0 bb', - 1520:'ad b8 9c ea 9a 15 fb e6 17 29 5b d0 4b 8c a0 5c', - 1536:'62 51 d8 7f d4 aa ae 9a 7e 4a d5 c2 17 d3 f3 00', - 2032:'e7 11 9b d6 dd 9b 22 af e8 f8 95 85 43 28 81 e2', - 2048:'78 5b 60 fd 7e c4 e9 fc b6 54 5f 35 0d 66 0f ab', - 3056:'af ec c0 37 fd b7 b0 83 8e b3 d7 0b cd 26 83 82', - 3072:'db c1 a7 b4 9d 57 35 8c c9 fa 6d 61 d7 3b 7c f0', - 4080:'63 49 d1 26 a3 7a fc ba 89 79 4f 98 04 91 4f dc', - 4096:'bf 42 c3 01 8c 2f 7c 66 bf de 52 49 75 76 81 15' - } - ), - ( - '1910833222772a', - { - 0: 'bc 92 22 db d3 27 4d 8f c6 6d 14 cc bd a6 69 0b', - 16: '7a e6 27 41 0c 9a 2b e6 93 df 5b b7 48 5a 63 e3', - 240: '3f 09 31 aa 03 de fb 30 0f 06 01 03 82 6f 2a 64', - 256: 'be aa 9e c8 d5 9b b6 81 29 f3 02 7c 96 36 11 81', - 496: '74 e0 4d b4 6d 28 64 8d 7d ee 8a 00 64 b0 6c fe', - 512: '9b 5e 81 c6 2f e0 23 c5 5b e4 2f 87 bb f9 32 b8', - 752: 'ce 17 8f c1 82 6e fe cb c1 82 f5 79 99 a4 61 40', - 768: '8b df 55 cd 55 06 1c 06 db a6 be 11 de 4a 57 8a', - 1008:'62 6f 5f 4d ce 65 25 01 f3 08 7d 39 c9 2c c3 49', - 1024:'42 da ac 6a 8f 9a b9 a7 fd 13 7c 60 37 82 56 82', - 1520:'cc 03 fd b7 91 92 a2 07 31 2f 53 f5 d4 dc 33 d9', - 1536:'f7 0f 14 12 2a 1c 98 a3 15 5d 28 b8 a0 a8 a4 1d', - 2032:'2a 3a 30 7a b2 70 8a 9c 00 fe 0b 42 f9 c2 d6 a1', - 2048:'86 26 17 62 7d 22 61 ea b0 b1 24 65 97 ca 0a e9', - 3056:'55 f8 77 ce 4f 2e 1d db bf 8e 13 e2 cd e0 fd c8', - 3072:'1b 15 56 cb 93 5f 17 33 37 70 5f bb 5d 50 1f c1', - 4080:'ec d0 e9 66 02 be 7f 8d 50 92 81 6c cc f2 c2 e9', - 4096:'02 78 81 fa b4 99 3a 1c 26 20 24 a9 4f ff 3f 61' - } - ), - # Page 8 - ( - '641910833222772a', - { - 0: 'bb f6 09 de 94 13 17 2d 07 66 0c b6 80 71 69 26', - 16: '46 10 1a 6d ab 43 11 5d 6c 52 2b 4f e9 36 04 a9', - 240: 'cb e1 ff f2 1c 96 f3 ee f6 1e 8f e0 54 2c bd f0', - 256: '34 79 38 bf fa 40 09 c5 12 cf b4 03 4b 0d d1 a7', - 496: '78 67 a7 86 d0 0a 71 47 90 4d 76 dd f1 e5 20 e3', - 512: '8d 3e 9e 1c ae fc cc b3 fb f8 d1 8f 64 12 0b 32', - 752: '94 23 37 f8 fd 76 f0 fa e8 c5 2d 79 54 81 06 72', - 768: 'b8 54 8c 10 f5 16 67 f6 e6 0e 18 2f a1 9b 30 f7', - 1008:'02 11 c7 c6 19 0c 9e fd 12 37 c3 4c 8f 2e 06 c4', - 1024:'bd a6 4f 65 27 6d 2a ac b8 f9 02 12 20 3a 80 8e', - 1520:'bd 38 20 f7 32 ff b5 3e c1 93 e7 9d 33 e2 7c 73', - 1536:'d0 16 86 16 86 19 07 d4 82 e3 6c da c8 cf 57 49', - 2032:'97 b0 f0 f2 24 b2 d2 31 71 14 80 8f b0 3a f7 a0', - 2048:'e5 96 16 e4 69 78 79 39 a0 63 ce ea 9a f9 56 d1', - 3056:'c4 7e 0d c1 66 09 19 c1 11 01 20 8f 9e 69 aa 1f', - 3072:'5a e4 f1 28 96 b8 37 9a 2a ad 89 b5 b5 53 d6 b0', - 4080:'6b 6b 09 8d 0c 29 3b c2 99 3d 80 bf 05 18 b6 d9', - 4096:'81 70 cc 3c cd 92 a6 98 62 1b 93 9d d3 8f e7 b9' - } - ), - ( - '8b37641910833222772a', - { - 0: 'ab 65 c2 6e dd b2 87 60 0d b2 fd a1 0d 1e 60 5c', - 16: 'bb 75 90 10 c2 96 58 f2 c7 2d 93 a2 d1 6d 29 30', - 240: 'b9 01 e8 03 6e d1 c3 83 cd 3c 4c 4d d0 a6 ab 05', - 256: '3d 25 ce 49 22 92 4c 55 f0 64 94 33 53 d7 8a 6c', - 496: '12 c1 aa 44 bb f8 7e 75 e6 11 f6 9b 2c 38 f4 9b', - 512: '28 f2 b3 43 4b 65 c0 98 77 47 00 44 c6 ea 17 0d', - 752: 'bd 9e f8 22 de 52 88 19 61 34 cf 8a f7 83 93 04', - 768: '67 55 9c 23 f0 52 15 84 70 a2 96 f7 25 73 5a 32', - 1008:'8b ab 26 fb c2 c1 2b 0f 13 e2 ab 18 5e ab f2 41', - 1024:'31 18 5a 6d 69 6f 0c fa 9b 42 80 8b 38 e1 32 a2', - 1520:'56 4d 3d ae 18 3c 52 34 c8 af 1e 51 06 1c 44 b5', - 1536:'3c 07 78 a7 b5 f7 2d 3c 23 a3 13 5c 7d 67 b9 f4', - 2032:'f3 43 69 89 0f cf 16 fb 51 7d ca ae 44 63 b2 dd', - 2048:'02 f3 1c 81 e8 20 07 31 b8 99 b0 28 e7 91 bf a7', - 3056:'72 da 64 62 83 22 8c 14 30 08 53 70 17 95 61 6f', - 3072:'4e 0a 8c 6f 79 34 a7 88 e2 26 5e 81 d6 d0 c8 f4', - 4080:'43 8d d5 ea fe a0 11 1b 6f 36 b4 b9 38 da 2a 68', - 4096:'5f 6b fc 73 81 58 74 d9 71 00 f0 86 97 93 57 d8' - } - ), - # Page 9 - ( - 'ebb46227c6cc8b37641910833222772a', - { - 0: '72 0c 94 b6 3e df 44 e1 31 d9 50 ca 21 1a 5a 30', - 16: 'c3 66 fd ea cf 9c a8 04 36 be 7c 35 84 24 d2 0b', - 240: 'b3 39 4a 40 aa bf 75 cb a4 22 82 ef 25 a0 05 9f', - 256: '48 47 d8 1d a4 94 2d bc 24 9d ef c4 8c 92 2b 9f', - 496: '08 12 8c 46 9f 27 53 42 ad da 20 2b 2b 58 da 95', - 512: '97 0d ac ef 40 ad 98 72 3b ac 5d 69 55 b8 17 61', - 752: '3c b8 99 93 b0 7b 0c ed 93 de 13 d2 a1 10 13 ac', - 768: 'ef 2d 67 6f 15 45 c2 c1 3d c6 80 a0 2f 4a db fe', - 1008:'b6 05 95 51 4f 24 bc 9f e5 22 a6 ca d7 39 36 44', - 1024:'b5 15 a8 c5 01 17 54 f5 90 03 05 8b db 81 51 4e', - 1520:'3c 70 04 7e 8c bc 03 8e 3b 98 20 db 60 1d a4 95', - 1536:'11 75 da 6e e7 56 de 46 a5 3e 2b 07 56 60 b7 70', - 2032:'00 a5 42 bb a0 21 11 cc 2c 65 b3 8e bd ba 58 7e', - 2048:'58 65 fd bb 5b 48 06 41 04 e8 30 b3 80 f2 ae de', - 3056:'34 b2 1a d2 ad 44 e9 99 db 2d 7f 08 63 f0 d9 b6', - 3072:'84 a9 21 8f c3 6e 8a 5f 2c cf be ae 53 a2 7d 25', - 4080:'a2 22 1a 11 b8 33 cc b4 98 a5 95 40 f0 54 5f 4a', - 4096:'5b be b4 78 7d 59 e5 37 3f db ea 6c 6f 75 c2 9b' - } - ), - ( - 'c109163908ebe51debb46227c6cc8b37641910833222772a', - { - 0: '54 b6 4e 6b 5a 20 b5 e2 ec 84 59 3d c7 98 9d a7', - 16: 'c1 35 ee e2 37 a8 54 65 ff 97 dc 03 92 4f 45 ce', - 240: 'cf cc 92 2f b4 a1 4a b4 5d 61 75 aa bb f2 d2 01', - 256: '83 7b 87 e2 a4 46 ad 0e f7 98 ac d0 2b 94 12 4f', - 496: '17 a6 db d6 64 92 6a 06 36 b3 f4 c3 7a 4f 46 94', - 512: '4a 5f 9f 26 ae ee d4 d4 a2 5f 63 2d 30 52 33 d9', - 752: '80 a3 d0 1e f0 0c 8e 9a 42 09 c1 7f 4e eb 35 8c', - 768: 'd1 5e 7d 5f fa aa bc 02 07 bf 20 0a 11 77 93 a2', - 1008:'34 96 82 bf 58 8e aa 52 d0 aa 15 60 34 6a ea fa', - 1024:'f5 85 4c db 76 c8 89 e3 ad 63 35 4e 5f 72 75 e3', - 1520:'53 2c 7c ec cb 39 df 32 36 31 84 05 a4 b1 27 9c', - 1536:'ba ef e6 d9 ce b6 51 84 22 60 e0 d1 e0 5e 3b 90', - 2032:'e8 2d 8c 6d b5 4e 3c 63 3f 58 1c 95 2b a0 42 07', - 2048:'4b 16 e5 0a bd 38 1b d7 09 00 a9 cd 9a 62 cb 23', - 3056:'36 82 ee 33 bd 14 8b d9 f5 86 56 cd 8f 30 d9 fb', - 3072:'1e 5a 0b 84 75 04 5d 9b 20 b2 62 86 24 ed fd 9e', - 4080:'63 ed d6 84 fb 82 62 82 fe 52 8f 9c 0e 92 37 bc', - 4096:'e4 dd 2e 98 d6 96 0f ae 0b 43 54 54 56 74 33 91' - } - ), - # Page 10 - ( - '1ada31d5cf688221c109163908ebe51debb46227c6cc8b37641910833222772a', - { - 0: 'dd 5b cb 00 18 e9 22 d4 94 75 9d 7c 39 5d 02 d3', - 16: 'c8 44 6f 8f 77 ab f7 37 68 53 53 eb 89 a1 c9 eb', - 240: 'af 3e 30 f9 c0 95 04 59 38 15 15 75 c3 fb 90 98', - 256: 'f8 cb 62 74 db 99 b8 0b 1d 20 12 a9 8e d4 8f 0e', - 496: '25 c3 00 5a 1c b8 5d e0 76 25 98 39 ab 71 98 ab', - 512: '9d cb c1 83 e8 cb 99 4b 72 7b 75 be 31 80 76 9c', - 752: 'a1 d3 07 8d fa 91 69 50 3e d9 d4 49 1d ee 4e b2', - 768: '85 14 a5 49 58 58 09 6f 59 6e 4b cd 66 b1 06 65', - 1008:'5f 40 d5 9e c1 b0 3b 33 73 8e fa 60 b2 25 5d 31', - 1024:'34 77 c7 f7 64 a4 1b ac ef f9 0b f1 4f 92 b7 cc', - 1520:'ac 4e 95 36 8d 99 b9 eb 78 b8 da 8f 81 ff a7 95', - 1536:'8c 3c 13 f8 c2 38 8b b7 3f 38 57 6e 65 b7 c4 46', - 2032:'13 c4 b9 c1 df b6 65 79 ed dd 8a 28 0b 9f 73 16', - 2048:'dd d2 78 20 55 01 26 69 8e fa ad c6 4b 64 f6 6e', - 3056:'f0 8f 2e 66 d2 8e d1 43 f3 a2 37 cf 9d e7 35 59', - 3072:'9e a3 6c 52 55 31 b8 80 ba 12 43 34 f5 7b 0b 70', - 4080:'d5 a3 9e 3d fc c5 02 80 ba c4 a6 b5 aa 0d ca 7d', - 4096:'37 0b 1c 1f e6 55 91 6d 97 fd 0d 47 ca 1d 72 b8' - } - ) - ] - - def test_keystream(self): - for tv in self.rfc6229_data: - key = unhexlify(b((tv[0]))) - cipher = ARC4.new(key) - count = 0 - for offset in range(0,4096+1,16): - ct = cipher.encrypt(b('\x00')*16) - expected = tv[1].get(offset) - if expected: - expected = unhexlify(b(expected.replace(" ",''))) - self.assertEquals(ct, expected) - count += 1 - self.assertEqual(count, len(tv[1])) - -class Drop_Tests(unittest.TestCase): - key = b('\xAA')*16 - data = b('\x00')*5000 - - def setUp(self): - self.cipher = ARC4.new(self.key) - - def test_drop256_encrypt(self): - cipher_drop = ARC4.new(self.key, 256) - ct_drop = cipher_drop.encrypt(self.data[:16]) - ct = self.cipher.encrypt(self.data)[256:256+16] - self.assertEquals(ct_drop, ct) - - def test_drop256_decrypt(self): - cipher_drop = ARC4.new(self.key, 256) - pt_drop = cipher_drop.decrypt(self.data[:16]) - pt = self.cipher.decrypt(self.data)[256:256+16] - self.assertEquals(pt_drop, pt) - def get_tests(config={}): + from Crypto.Cipher import ARC4 from common import make_stream_tests - tests = make_stream_tests(ARC4, "ARC4", test_data) - tests += list_test_cases(RFC6229_Tests) - tests += list_test_cases(Drop_Tests) - return tests + return make_stream_tests(ARC4, "ARC4", test_data) if __name__ == '__main__': import unittest diff --git a/lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py b/lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py index 86c38a3e..accca613 100644 --- a/lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py +++ b/lib/Crypto/SelfTest/Cipher/test_pkcs1_oaep.py @@ -31,7 +31,7 @@ from Crypto.Util.py3compat import * from Crypto.PublicKey import RSA from Crypto.Cipher import PKCS1_OAEP as PKCS -from Crypto.Hash import MD2,MD5,SHA1,SHA256,RIPEMD160 +from Crypto.Hash import MD2,MD5,SHA as SHA1,SHA256,RIPEMD from Crypto import Random def rws(t): @@ -314,12 +314,11 @@ def testEncryptDecrypt1(self): # Encrypt/Decrypt messages of length [0..128-2*20-2] for pt_len in xrange(0,128-2*20-2): pt = self.rng(pt_len) - cipher = PKCS.new(self.key1024) - ct = cipher.encrypt(pt) - pt2 = cipher.decrypt(ct) + ct = PKCS.encrypt(pt, self.key1024) + pt2 = PKCS.decrypt(ct, self.key1024) self.assertEqual(pt,pt2) - def testEncryptDecrypt2(self): + def testEncryptDecrypt1(self): # Helper function to monitor what's requested from RNG global asked def localRng(N): @@ -327,7 +326,7 @@ def localRng(N): asked += N return self.rng(N) # Verify that OAEP is friendly to all hashes - for hashmod in (MD2,MD5,SHA1,SHA256,RIPEMD160): + for hashmod in (MD2,MD5,SHA1,SHA256,RIPEMD): # Verify that encrypt() asks for as many random bytes # as the hash output size asked = 0 @@ -338,7 +337,7 @@ def localRng(N): self.assertEqual(cipher.decrypt(ct), pt) self.failUnless(asked > hashmod.digest_size) - def testEncryptDecrypt3(self): + def testEncryptDecrypt2(self): # Verify that OAEP supports labels pt = self.rng(35) xlabel = self.rng(22) @@ -346,7 +345,7 @@ def testEncryptDecrypt3(self): ct = cipher.encrypt(pt) self.assertEqual(cipher.decrypt(ct), pt) - def testEncryptDecrypt4(self): + def testEncryptDecrypt3(self): # Verify that encrypt() uses the custom MGF global mgfcalls # Helper function to monitor what's requested from MGF diff --git a/lib/Crypto/SelfTest/Hash/__init__.py b/lib/Crypto/SelfTest/Hash/__init__.py index e2d9cd8c..bb19f9b3 100644 --- a/lib/Crypto/SelfTest/Hash/__init__.py +++ b/lib/Crypto/SelfTest/Hash/__init__.py @@ -28,14 +28,13 @@ def get_tests(config={}): tests = [] - from Crypto.SelfTest.Hash import test_HMAC; tests += test_HMAC.get_tests(config=config) - from Crypto.SelfTest.Hash import test_CMAC; tests += test_CMAC.get_tests(config=config) - from Crypto.SelfTest.Hash import test_MD2; tests += test_MD2.get_tests(config=config) - from Crypto.SelfTest.Hash import test_MD4; tests += test_MD4.get_tests(config=config) - from Crypto.SelfTest.Hash import test_MD5; tests += test_MD5.get_tests(config=config) - from Crypto.SelfTest.Hash import test_RIPEMD160; tests += test_RIPEMD160.get_tests(config=config) - from Crypto.SelfTest.Hash import test_SHA1; tests += test_SHA1.get_tests(config=config) - from Crypto.SelfTest.Hash import test_SHA256; tests += test_SHA256.get_tests(config=config) + from Crypto.SelfTest.Hash import test_HMAC; tests += test_HMAC.get_tests(config=config) + from Crypto.SelfTest.Hash import test_MD2; tests += test_MD2.get_tests(config=config) + from Crypto.SelfTest.Hash import test_MD4; tests += test_MD4.get_tests(config=config) + from Crypto.SelfTest.Hash import test_MD5; tests += test_MD5.get_tests(config=config) + from Crypto.SelfTest.Hash import test_RIPEMD; tests += test_RIPEMD.get_tests(config=config) + from Crypto.SelfTest.Hash import test_SHA; tests += test_SHA.get_tests(config=config) + from Crypto.SelfTest.Hash import test_SHA256; tests += test_SHA256.get_tests(config=config) try: from Crypto.SelfTest.Hash import test_SHA224; tests += test_SHA224.get_tests(config=config) from Crypto.SelfTest.Hash import test_SHA384; tests += test_SHA384.get_tests(config=config) diff --git a/lib/Crypto/SelfTest/Hash/common.py b/lib/Crypto/SelfTest/Hash/common.py index 7bf0cdce..f77fb0f1 100644 --- a/lib/Crypto/SelfTest/Hash/common.py +++ b/lib/Crypto/SelfTest/Hash/common.py @@ -29,10 +29,7 @@ import sys import unittest import binascii -import Crypto.Hash from Crypto.Util.py3compat import * -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * # For compatibility with Python 2.1 and Python 2.2 if sys.hexversion < 0x02030000: @@ -43,8 +40,6 @@ def dict(**kwargs): else: dict = dict -from Crypto.SelfTest.st_common import docstrings_disabled -from Crypto.Util.strxor import strxor_c class HashDigestSizeSelfTest(unittest.TestCase): @@ -99,27 +94,11 @@ def runTest(self): self.assertEqual(self.expected.decode(), out3) # h = .new(data); h.hexdigest() self.assertEqual(self.expected, out4) # h = .new(data); h.digest() - # Verify that the .new() method produces a fresh hash object, except - # for MD5 and SHA1, which are hashlib objects. (But test any .new() - # method that does exist.) - if self.hashmod.__name__ not in ('Crypto.Hash.MD5', 'Crypto.Hash.SHA1') or hasattr(h, 'new'): - h2 = h.new() - h2.update(self.input) - out5 = binascii.b2a_hex(h2.digest()) - self.assertEqual(self.expected, out5) - - # Verify that Crypto.Hash.new(h) produces a fresh hash object - h3 = Crypto.Hash.new(h) - h3.update(self.input) - out6 = binascii.b2a_hex(h3.digest()) - self.assertEqual(self.expected, out6) - - if hasattr(h, 'name'): - # Verify that Crypto.Hash.new(h.name) produces a fresh hash object - h4 = Crypto.Hash.new(h.name) - h4.update(self.input) - out7 = binascii.b2a_hex(h4.digest()) - self.assertEqual(self.expected, out7) + # Verify that new() object method produces a fresh hash object + h2 = h.new() + h2.update(self.input) + out5 = binascii.b2a_hex(h2.digest()) + self.assertEqual(self.expected, out5) class HashTestOID(unittest.TestCase): def __init__(self, hashmod, oid): @@ -128,106 +107,65 @@ def __init__(self, hashmod, oid): self.oid = oid def runTest(self): - from Crypto.Signature import PKCS1_v1_5 h = self.hashmod.new() - self.assertEqual(PKCS1_v1_5._HASH_OIDS[h.name], self.oid) - -class HashDocStringTest(unittest.TestCase): - def __init__(self, hashmod): - unittest.TestCase.__init__(self) - self.hashmod = hashmod - - def runTest(self): - docstring = self.hashmod.__doc__ - self.assert_(hasattr(self.hashmod, '__doc__')) - if not docstrings_disabled(): # -OO makes docstrings disappear globally - self.assert_(isinstance(self.hashmod.__doc__, str)) - -class GenericHashConstructorTest(unittest.TestCase): - def __init__(self, hashmod): - unittest.TestCase.__init__(self) - self.hashmod = hashmod - - def runTest(self): - obj1 = self.hashmod.new("foo") - obj2 = self.hashmod.new() - obj3 = Crypto.Hash.new(obj1.name, "foo") - obj4 = Crypto.Hash.new(obj1.name) - obj5 = Crypto.Hash.new(obj1, "foo") - obj6 = Crypto.Hash.new(obj1) - self.assert_(isinstance(self.hashmod, obj1)) - self.assert_(isinstance(self.hashmod, obj2)) - self.assert_(isinstance(self.hashmod, obj3)) - self.assert_(isinstance(self.hashmod, obj4)) - self.assert_(isinstance(self.hashmod, obj5)) - self.assert_(isinstance(self.hashmod, obj6)) + if self.oid==None: + try: + raised = 0 + a = h.oid + except AttributeError: + raised = 1 + self.assertEqual(raised,1) + else: + self.assertEqual(h.oid, self.oid) class MACSelfTest(unittest.TestCase): - def __init__(self, module, description, result, input, key, params): + def __init__(self, hashmod, description, expected_dict, input, key, hashmods): unittest.TestCase.__init__(self) - self.module = module - self.result = result + self.hashmod = hashmod + self.expected_dict = expected_dict self.input = input self.key = key - self.params = params + self.hashmods = hashmods self.description = description def shortDescription(self): return self.description def runTest(self): - key = binascii.a2b_hex(b(self.key)) - data = binascii.a2b_hex(b(self.input)) - - # Strip whitespace from the expected string (which should be in lowercase-hex) - expected = b("".join(self.result.split())) - - h = self.module.new(key, **self.params) - h.update(data) - out1_bin = h.digest() - out1 = binascii.b2a_hex(h.digest()) - out2 = h.hexdigest() - - # Verify that correct MAC does not raise any exception - h.hexverify(out1) - h.verify(out1_bin) - - # Verify that incorrect MAC does raise ValueError exception - wrong_mac = strxor_c(out1_bin, 255) - self.assertRaises(ValueError, h.verify, wrong_mac) - self.assertRaises(ValueError, h.hexverify, "4556") - - h = self.module.new(key, data, **self.params) - - out3 = h.hexdigest() - out4 = binascii.b2a_hex(h.digest()) - - # Test .copy() - h2 = h.copy() - h.update(b("blah blah blah")) # Corrupt the original hash object - out5 = binascii.b2a_hex(h2.digest()) # The copied hash object should return the correct result - - # PY3K: Check that hexdigest() returns str and digest() returns bytes - if sys.version_info[0] > 2: - self.assertTrue(isinstance(h.digest(), type(b("")))) - self.assertTrue(isinstance(h.hexdigest(), type(""))) - - # PY3K: Check that .hexverify() accepts bytes or str - if sys.version_info[0] > 2: - h.hexverify(h.hexdigest()) - h.hexverify(h.hexdigest().encode('ascii')) - - # PY3K: hexdigest() should return str, and digest() should return bytes - self.assertEqual(expected, out1) - if sys.version_info[0] == 2: - self.assertEqual(expected, out2) - self.assertEqual(expected, out3) - else: - self.assertEqual(expected.decode(), out2) - self.assertEqual(expected.decode(), out3) - self.assertEqual(expected, out4) - self.assertEqual(expected, out5) + for hashname in self.expected_dict.keys(): + hashmod = self.hashmods[hashname] + key = binascii.a2b_hex(b(self.key)) + data = binascii.a2b_hex(b(self.input)) + + # Strip whitespace from the expected string (which should be in lowercase-hex) + expected = b("".join(self.expected_dict[hashname].split())) + + h = self.hashmod.new(key, digestmod=hashmod) + h.update(data) + out1 = binascii.b2a_hex(h.digest()) + out2 = h.hexdigest() + + h = self.hashmod.new(key, data, hashmod) + + out3 = h.hexdigest() + out4 = binascii.b2a_hex(h.digest()) + + # Test .copy() + h2 = h.copy() + h.update(b("blah blah blah")) # Corrupt the original hash object + out5 = binascii.b2a_hex(h2.digest()) # The copied hash object should return the correct result + + # PY3K: hexdigest() should return str(), and digest() bytes + self.assertEqual(expected, out1) + if sys.version_info[0] == 2: + self.assertEqual(expected, out2) + self.assertEqual(expected, out3) + else: + self.assertEqual(expected.decode(), out2) + self.assertEqual(expected.decode(), out3) + self.assertEqual(expected, out4) + self.assertEqual(expected, out5) def make_hash_tests(module, module_name, test_data, digest_size, oid=None): tests = [] @@ -237,25 +175,23 @@ def make_hash_tests(module, module_name, test_data, digest_size, oid=None): if len(row) < 3: description = repr(input) else: - description = row[2] + description = row[2].encode('latin-1') name = "%s #%d: %s" % (module_name, i+1, description) tests.append(HashSelfTest(module, name, expected, input)) + if oid is not None: + oid = b(oid) name = "%s #%d: digest_size" % (module_name, i+1) tests.append(HashDigestSizeSelfTest(module, name, digest_size)) - if oid is not None: - tests.append(HashTestOID(module, oid)) - tests.append(HashDocStringTest(module)) - if getattr(module, 'name', None) is not None: - tests.append(GenericHashConstructorTest(module)) + tests.append(HashTestOID(module, oid)) return tests -def make_mac_tests(module, module_name, test_data): +def make_mac_tests(module, module_name, test_data, hashmods): tests = [] for i in range(len(test_data)): row = test_data[i] - (key, data, results, description, params) = row + (key, data, results, description) = row name = "%s #%d: %s" % (module_name, i+1, description) - tests.append(MACSelfTest(module, name, results, data, key, params)) + tests.append(MACSelfTest(module, name, results, data, key, hashmods)) return tests # vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/lib/Crypto/SelfTest/Hash/test_CMAC.py b/lib/Crypto/SelfTest/Hash/test_CMAC.py deleted file mode 100644 index f16d89f7..00000000 --- a/lib/Crypto/SelfTest/Hash/test_CMAC.py +++ /dev/null @@ -1,249 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SelfTest/Hash/CMAC.py: Self-test for the CMAC module -# -# =================================================================== -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# =================================================================== - -"""Self-test suite for Crypto.Hash.CMAC""" - -import sys -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * -from Crypto.Util.py3compat import * - -from common import dict - -from Crypto.Hash import CMAC -from Crypto.Cipher import AES, DES3 - -# This is a list of (key, data, result, description, module) tuples. -test_data = [ - - ## Test vectors from RFC 4493 ## - ## The are also in NIST SP 800 38B D.2 ## - ( '2b7e151628aed2a6abf7158809cf4f3c', - '', - 'bb1d6929e95937287fa37d129b756746', - 'RFC 4493 #1', - AES - ), - - ( '2b7e151628aed2a6abf7158809cf4f3c', - '6bc1bee22e409f96e93d7e117393172a', - '070a16b46b4d4144f79bdd9dd04a287c', - 'RFC 4493 #2', - AES - ), - - ( '2b7e151628aed2a6abf7158809cf4f3c', - '6bc1bee22e409f96e93d7e117393172a'+ - 'ae2d8a571e03ac9c9eb76fac45af8e51'+ - '30c81c46a35ce411', - 'dfa66747de9ae63030ca32611497c827', - 'RFC 4493 #3', - AES - ), - - ( '2b7e151628aed2a6abf7158809cf4f3c', - '6bc1bee22e409f96e93d7e117393172a'+ - 'ae2d8a571e03ac9c9eb76fac45af8e51'+ - '30c81c46a35ce411e5fbc1191a0a52ef'+ - 'f69f2445df4f9b17ad2b417be66c3710', - '51f0bebf7e3b9d92fc49741779363cfe', - 'RFC 4493 #4', - AES - ), - - ## The rest of Appendix D of NIST SP 800 38B - ## was not totally correct. - ## Values in Examples 14, 15, 18, and 19 were wrong. - ## The updated test values are published in: - ## http://csrc.nist.gov/publications/nistpubs/800-38B/Updated_CMAC_Examples.pdf - - ( '8e73b0f7da0e6452c810f32b809079e5'+ - '62f8ead2522c6b7b', - '', - 'd17ddf46adaacde531cac483de7a9367', - 'NIST SP 800 38B D.2 Example 5', - AES - ), - - ( '8e73b0f7da0e6452c810f32b809079e5'+ - '62f8ead2522c6b7b', - '6bc1bee22e409f96e93d7e117393172a', - '9e99a7bf31e710900662f65e617c5184', - 'NIST SP 800 38B D.2 Example 6', - AES - ), - - ( '8e73b0f7da0e6452c810f32b809079e5'+ - '62f8ead2522c6b7b', - '6bc1bee22e409f96e93d7e117393172a'+ - 'ae2d8a571e03ac9c9eb76fac45af8e51'+ - '30c81c46a35ce411', - '8a1de5be2eb31aad089a82e6ee908b0e', - 'NIST SP 800 38B D.2 Example 7', - AES - ), - - ( '8e73b0f7da0e6452c810f32b809079e5'+ - '62f8ead2522c6b7b', - '6bc1bee22e409f96e93d7e117393172a'+ - 'ae2d8a571e03ac9c9eb76fac45af8e51'+ - '30c81c46a35ce411e5fbc1191a0a52ef'+ - 'f69f2445df4f9b17ad2b417be66c3710', - 'a1d5df0eed790f794d77589659f39a11', - 'NIST SP 800 38B D.2 Example 8', - AES - ), - - ( '603deb1015ca71be2b73aef0857d7781'+ - '1f352c073b6108d72d9810a30914dff4', - '', - '028962f61b7bf89efc6b551f4667d983', - 'NIST SP 800 38B D.3 Example 9', - AES - ), - - ( '603deb1015ca71be2b73aef0857d7781'+ - '1f352c073b6108d72d9810a30914dff4', - '6bc1bee22e409f96e93d7e117393172a', - '28a7023f452e8f82bd4bf28d8c37c35c', - 'NIST SP 800 38B D.3 Example 10', - AES - ), - - ( '603deb1015ca71be2b73aef0857d7781'+ - '1f352c073b6108d72d9810a30914dff4', - '6bc1bee22e409f96e93d7e117393172a'+ - 'ae2d8a571e03ac9c9eb76fac45af8e51'+ - '30c81c46a35ce411', - 'aaf3d8f1de5640c232f5b169b9c911e6', - 'NIST SP 800 38B D.3 Example 11', - AES - ), - - ( '603deb1015ca71be2b73aef0857d7781'+ - '1f352c073b6108d72d9810a30914dff4', - '6bc1bee22e409f96e93d7e117393172a'+ - 'ae2d8a571e03ac9c9eb76fac45af8e51'+ - '30c81c46a35ce411e5fbc1191a0a52ef'+ - 'f69f2445df4f9b17ad2b417be66c3710', - 'e1992190549f6ed5696a2c056c315410', - 'NIST SP 800 38B D.3 Example 12', - AES - ), - - ( '8aa83bf8cbda1062'+ - '0bc1bf19fbb6cd58'+ - 'bc313d4a371ca8b5', - '', - 'b7a688e122ffaf95', - 'NIST SP 800 38B D.4 Example 13', - DES3 - ), - - ( '8aa83bf8cbda1062'+ - '0bc1bf19fbb6cd58'+ - 'bc313d4a371ca8b5', - '6bc1bee22e409f96', - '8e8f293136283797', - 'NIST SP 800 38B D.4 Example 14', - DES3 - ), - - ( '8aa83bf8cbda1062'+ - '0bc1bf19fbb6cd58'+ - 'bc313d4a371ca8b5', - '6bc1bee22e409f96'+ - 'e93d7e117393172a'+ - 'ae2d8a57', - '743ddbe0ce2dc2ed', - 'NIST SP 800 38B D.4 Example 15', - DES3 - ), - - ( '8aa83bf8cbda1062'+ - '0bc1bf19fbb6cd58'+ - 'bc313d4a371ca8b5', - '6bc1bee22e409f96'+ - 'e93d7e117393172a'+ - 'ae2d8a571e03ac9c'+ - '9eb76fac45af8e51', - '33e6b1092400eae5', - 'NIST SP 800 38B D.4 Example 16', - DES3 - ), - - ( '4cf15134a2850dd5'+ - '8a3d10ba80570d38', - '', - 'bd2ebf9a3ba00361', - 'NIST SP 800 38B D.7 Example 17', - DES3 - ), - - ( '4cf15134a2850dd5'+ - '8a3d10ba80570d38', - '6bc1bee22e409f96', - '4ff2ab813c53ce83', - 'NIST SP 800 38B D.7 Example 18', - DES3 - ), - - ( '4cf15134a2850dd5'+ - '8a3d10ba80570d38', - '6bc1bee22e409f96'+ - 'e93d7e117393172a'+ - 'ae2d8a57', - '62dd1b471902bd4e', - 'NIST SP 800 38B D.7 Example 19', - DES3 - ), - - ( '4cf15134a2850dd5'+ - '8a3d10ba80570d38', - '6bc1bee22e409f96'+ - 'e93d7e117393172a'+ - 'ae2d8a571e03ac9c'+ - '9eb76fac45af8e51', - '31b1e431dabc4eb8', - 'NIST SP 800 38B D.7 Example 20', - DES3 - ), - -] - -def get_tests(config={}): - global test_data - from common import make_mac_tests - - # Add new() parameters to the back of each test vector - params_test_data = [] - for row in test_data: - t = list(row) - t[4] = dict(ciphermod=t[4]) - params_test_data.append(t) - - return make_mac_tests(CMAC, "CMAC", params_test_data) - -if __name__ == '__main__': - import unittest - suite = lambda: unittest.TestSuite(get_tests()) - unittest.main(defaultTest='suite') diff --git a/lib/Crypto/SelfTest/Hash/test_HMAC.py b/lib/Crypto/SelfTest/Hash/test_HMAC.py index baaea5e2..c01c97b6 100644 --- a/lib/Crypto/SelfTest/Hash/test_HMAC.py +++ b/lib/Crypto/SelfTest/Hash/test_HMAC.py @@ -29,17 +29,13 @@ from common import dict # For compatibility with Python 2.1 and 2.2 from Crypto.Util.py3compat import * -from Crypto.Hash import MD5, SHA1, SHA224, SHA256, SHA384, SHA512, HMAC - -default_hash = None - # This is a list of (key, data, results, description) tuples. test_data = [ ## Test vectors from RFC 2202 ## # Test that the default hashmod is MD5 ('0b' * 16, '4869205468657265', - dict(default_hash='9294727a3638bb1c13f48ef8158bfc9d'), + dict(default='9294727a3638bb1c13f48ef8158bfc9d'), 'default-is-MD5'), # Test case 1 (MD5) @@ -179,7 +175,9 @@ bfdc63644f0713938a7f51535c3a35e2 '''), 'RFC 4231 #7 (HMAC-SHA256)'), +] +hashlib_test_data = [ # Test case 8 (SHA224) ('4a656665', '7768617420646f2079612077616e74' @@ -205,25 +203,17 @@ def get_tests(config={}): global test_data + from Crypto.Hash import HMAC, MD5, SHA as SHA1, SHA256 from common import make_mac_tests - - # A test vector contains multiple results, each one for a - # different hash algorithm. - # Here we expand each test vector into multiple ones, - # and add the relevant parameters that will be passed to new() - exp_test_data = [] - for row in test_data: - for modname in row[2].keys(): - t = list(row) - t[2] = row[2][modname] - try: - t.append(dict(digestmod=globals()[modname])) - exp_test_data.append(t) - except AttributeError: - import sys - sys.stderr.write("SelfTest: warning: not testing HMAC-%s (not available)\n" % modname) - - return make_mac_tests(HMAC, "HMAC", exp_test_data) + hashmods = dict(MD5=MD5, SHA1=SHA1, SHA256=SHA256, default=None) + try: + from Crypto.Hash import SHA224, SHA384, SHA512 + hashmods.update(dict(SHA224=SHA224, SHA384=SHA384, SHA512=SHA512)) + test_data += hashlib_test_data + except ImportError: + import sys + sys.stderr.write("SelfTest: warning: not testing HMAC-SHA224/384/512 (not available)\n") + return make_mac_tests(HMAC, "HMAC", test_data, hashmods) if __name__ == '__main__': import unittest diff --git a/lib/Crypto/SelfTest/Hash/test_MD2.py b/lib/Crypto/SelfTest/Hash/test_MD2.py index fd03e786..db636d4c 100644 --- a/lib/Crypto/SelfTest/Hash/test_MD2.py +++ b/lib/Crypto/SelfTest/Hash/test_MD2.py @@ -54,7 +54,7 @@ def get_tests(config={}): from common import make_hash_tests return make_hash_tests(MD2, "MD2", test_data, digest_size=16, - oid="1.2.840.113549.2.2") + oid="\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x02") if __name__ == '__main__': import unittest diff --git a/lib/Crypto/SelfTest/Hash/test_MD4.py b/lib/Crypto/SelfTest/Hash/test_MD4.py index 7dbf49f4..1727bb65 100644 --- a/lib/Crypto/SelfTest/Hash/test_MD4.py +++ b/lib/Crypto/SelfTest/Hash/test_MD4.py @@ -54,7 +54,7 @@ def get_tests(config={}): from common import make_hash_tests return make_hash_tests(MD4, "MD4", test_data, digest_size=16, - oid="1.2.840.113549.2.4") + oid="\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x04") if __name__ == '__main__': import unittest diff --git a/lib/Crypto/SelfTest/Hash/test_MD5.py b/lib/Crypto/SelfTest/Hash/test_MD5.py index 0683113e..2e293fc8 100644 --- a/lib/Crypto/SelfTest/Hash/test_MD5.py +++ b/lib/Crypto/SelfTest/Hash/test_MD5.py @@ -54,7 +54,7 @@ def get_tests(config={}): from common import make_hash_tests return make_hash_tests(MD5, "MD5", test_data, digest_size=16, - oid="1.2.840.113549.2.5") + oid="\x06\x08\x2a\x86\x48\x86\xf7\x0d\x02\x05") if __name__ == '__main__': import unittest diff --git a/lib/Crypto/SelfTest/Hash/test_RIPEMD160.py b/lib/Crypto/SelfTest/Hash/test_RIPEMD.py similarity index 90% rename from lib/Crypto/SelfTest/Hash/test_RIPEMD160.py rename to lib/Crypto/SelfTest/Hash/test_RIPEMD.py index b0d69804..6673a934 100644 --- a/lib/Crypto/SelfTest/Hash/test_RIPEMD160.py +++ b/lib/Crypto/SelfTest/Hash/test_RIPEMD.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# SelfTest/Hash/test_RIPEMD160.py: Self-test for the RIPEMD-160 hash function +# SelfTest/Hash/test_RIPEMD.py: Self-test for the RIPEMD-160 hash function # # Written in 2008 by Dwayne C. Litzenberger # @@ -22,7 +22,7 @@ # SOFTWARE. # =================================================================== -#"""Self-test suite for Crypto.Hash.RIPEMD160""" +#"""Self-test suite for Crypto.Hash.RIPEMD""" __revision__ = "$Id$" @@ -59,11 +59,11 @@ ] def get_tests(config={}): - from Crypto.Hash import RIPEMD160 + from Crypto.Hash import RIPEMD from common import make_hash_tests - return make_hash_tests(RIPEMD160, "RIPEMD160", test_data, + return make_hash_tests(RIPEMD, "RIPEMD", test_data, digest_size=20, - oid="1.3.36.3.2.1") + oid="\x06\x05\x2b\x24\x03\02\x01") if __name__ == '__main__': import unittest diff --git a/lib/Crypto/SelfTest/Hash/test_SHA1.py b/lib/Crypto/SelfTest/Hash/test_SHA.py similarity index 91% rename from lib/Crypto/SelfTest/Hash/test_SHA1.py rename to lib/Crypto/SelfTest/Hash/test_SHA.py index 436f7de9..7d72e772 100644 --- a/lib/Crypto/SelfTest/Hash/test_SHA1.py +++ b/lib/Crypto/SelfTest/Hash/test_SHA.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# SelfTest/Hash/SHA1.py: Self-test for the SHA-1 hash function +# SelfTest/Hash/SHA.py: Self-test for the SHA-1 hash function # # Written in 2008 by Dwayne C. Litzenberger # @@ -50,11 +50,11 @@ ] def get_tests(config={}): - from Crypto.Hash import SHA1 + from Crypto.Hash import SHA from common import make_hash_tests - return make_hash_tests(SHA1, "SHA1", test_data, + return make_hash_tests(SHA, "SHA", test_data, digest_size=20, - oid="1.3.14.3.2.26") + oid="\x06\x05\x2B\x0E\x03\x02\x1A") if __name__ == '__main__': import unittest diff --git a/lib/Crypto/SelfTest/Hash/test_SHA224.py b/lib/Crypto/SelfTest/Hash/test_SHA224.py index eb28ebc3..a60f35a9 100644 --- a/lib/Crypto/SelfTest/Hash/test_SHA224.py +++ b/lib/Crypto/SelfTest/Hash/test_SHA224.py @@ -55,7 +55,7 @@ def get_tests(config={}): from common import make_hash_tests return make_hash_tests(SHA224, "SHA224", test_data, digest_size=28, - oid='2.16.840.1.101.3.4.2.4') + oid='\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x04') if __name__ == '__main__': import unittest diff --git a/lib/Crypto/SelfTest/Hash/test_SHA256.py b/lib/Crypto/SelfTest/Hash/test_SHA256.py index 50bdba88..4b451100 100644 --- a/lib/Crypto/SelfTest/Hash/test_SHA256.py +++ b/lib/Crypto/SelfTest/Hash/test_SHA256.py @@ -81,7 +81,7 @@ def get_tests(config={}): from common import make_hash_tests tests = make_hash_tests(SHA256, "SHA256", test_data, digest_size=32, - oid="2.16.840.1.101.3.4.2.1") + oid="\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x01") if config.get('slow_tests'): tests += [LargeSHA256Test()] diff --git a/lib/Crypto/SelfTest/Hash/test_SHA384.py b/lib/Crypto/SelfTest/Hash/test_SHA384.py index 27d16b3d..b7a72c05 100644 --- a/lib/Crypto/SelfTest/Hash/test_SHA384.py +++ b/lib/Crypto/SelfTest/Hash/test_SHA384.py @@ -53,7 +53,7 @@ def get_tests(config={}): from common import make_hash_tests return make_hash_tests(SHA384, "SHA384", test_data, digest_size=48, - oid='2.16.840.1.101.3.4.2.2') + oid='\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x02') if __name__ == '__main__': import unittest diff --git a/lib/Crypto/SelfTest/Hash/test_SHA512.py b/lib/Crypto/SelfTest/Hash/test_SHA512.py index 04a505e3..cb86177e 100644 --- a/lib/Crypto/SelfTest/Hash/test_SHA512.py +++ b/lib/Crypto/SelfTest/Hash/test_SHA512.py @@ -50,7 +50,7 @@ def get_tests(config={}): from common import make_hash_tests return make_hash_tests(SHA512, "SHA512", test_data, digest_size=64, - oid="2.16.840.1.101.3.4.2.3") + oid="\x06\x09\x60\x86\x48\x01\x65\x03\x04\x02\x03") if __name__ == '__main__': import unittest diff --git a/lib/Crypto/SelfTest/IO/__init__.py b/lib/Crypto/SelfTest/IO/__init__.py deleted file mode 100644 index 084904e0..00000000 --- a/lib/Crypto/SelfTest/IO/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ -# -# SelfTest/IO/__init__.py: Self-test for input/output module -# -# =================================================================== -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# =================================================================== - -"""Self-test for I/O""" - -def get_tests(config={}): - tests = [] - from Crypto.SelfTest.IO import test_PKCS8; tests += test_PKCS8.get_tests(config=config) - return tests - -if __name__ == '__main__': - import unittest - suite = lambda: unittest.TestSuite(get_tests()) - unittest.main(defaultTest='suite') - - diff --git a/lib/Crypto/SelfTest/IO/test_PKCS8.py b/lib/Crypto/SelfTest/IO/test_PKCS8.py deleted file mode 100644 index 6902ab4c..00000000 --- a/lib/Crypto/SelfTest/IO/test_PKCS8.py +++ /dev/null @@ -1,418 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SelfTest/PublicKey/test_PKCS8.py: Self-test for the PKCS8 module -# -# =================================================================== -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# =================================================================== - -"""Self-tests for Crypto.PublicKey.PKCS8 module""" - -__revision__ = "$Id$" - -import unittest -import sys -from binascii import unhexlify - -from Crypto.Util.py3compat import * -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * - -from Crypto.IO import PKCS8 - -oid_key = '1.2.840.113549.1.1.1' - -# Original RSA key (in DER format) -# hexdump -v -e '32/1 "%02x" "\n"' key.der -clear_key=""" -308201ab020100025a00b94a7f7075ab9e79e8196f47be707781e80dd965cf16 -0c951a870b71783b6aaabbd550c0e65e5a3dfe15b8620009f6d7e5efec42a3f0 -6fe20faeebb0c356e79cdec6db4dd427e82d8ae4a5b90996227b8ba54ccfc4d2 -5c08050203010001025a00afa09c70d528299b7552fe766b5d20f9a221d66938 -c3b68371d48515359863ff96f0978d700e08cd6fd3d8a3f97066fc2e0d5f78eb -3a50b8e17ba297b24d1b8e9cdfd18d608668198d724ad15863ef0329195dee89 -3f039395022d0ebe0518df702a8b25954301ec60a97efdcec8eaa4f2e76ca7e8 -8dfbc3f7e0bb83f9a0e8dc47c0f8c746e9df6b022d0c9195de13f09b7be1fdd7 -1f56ae7d973e08bd9fd2c3dfd8936bb05be9cc67bd32d663c7f00d70932a0be3 -c24f022d0ac334eb6cabf1933633db007b763227b0d9971a9ea36aca8b669ec9 -4fcf16352f6b3dcae28e4bd6137db4ddd3022d0400a09f15ee7b351a2481cb03 -09920905c236d09c87afd3022f3afc2a19e3b746672b635238956ee7e6dd62d5 -022d0cd88ed14fcfbda5bbf0257f700147137bbab9c797af7df866704b889aa3 -7e2e93df3ff1a0fd3490111dcdbc4c -""" - -# Same key as above, wrapped in PKCS#8 but w/o password -# -# openssl pkcs8 -topk8 -inform DER -nocrypt -in key.der -outform DER -out keyp8.der -# hexdump -v -e '32/1 "%02x" "\n"' keyp8.der -wrapped_clear_key=""" -308201c5020100300d06092a864886f70d0101010500048201af308201ab0201 -00025a00b94a7f7075ab9e79e8196f47be707781e80dd965cf160c951a870b71 -783b6aaabbd550c0e65e5a3dfe15b8620009f6d7e5efec42a3f06fe20faeebb0 -c356e79cdec6db4dd427e82d8ae4a5b90996227b8ba54ccfc4d25c0805020301 -0001025a00afa09c70d528299b7552fe766b5d20f9a221d66938c3b68371d485 -15359863ff96f0978d700e08cd6fd3d8a3f97066fc2e0d5f78eb3a50b8e17ba2 -97b24d1b8e9cdfd18d608668198d724ad15863ef0329195dee893f039395022d -0ebe0518df702a8b25954301ec60a97efdcec8eaa4f2e76ca7e88dfbc3f7e0bb -83f9a0e8dc47c0f8c746e9df6b022d0c9195de13f09b7be1fdd71f56ae7d973e -08bd9fd2c3dfd8936bb05be9cc67bd32d663c7f00d70932a0be3c24f022d0ac3 -34eb6cabf1933633db007b763227b0d9971a9ea36aca8b669ec94fcf16352f6b -3dcae28e4bd6137db4ddd3022d0400a09f15ee7b351a2481cb0309920905c236 -d09c87afd3022f3afc2a19e3b746672b635238956ee7e6dd62d5022d0cd88ed1 -4fcfbda5bbf0257f700147137bbab9c797af7df866704b889aa37e2e93df3ff1 -a0fd3490111dcdbc4c -""" - -### -# -# The key above will now be encrypted with different algorithms. -# The password is always 'TestTest'. -# -# Each item in the wrapped_enc_keys list contains: -# * wrap algorithm -# * iteration count -# * Salt -# * IV -# * Expected result -### -wrapped_enc_keys = [] - -# -# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der -outform DER -out keyenc.der -v2 des3 -# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der -# -wrapped_enc_keys.append(( -'PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC', -2048, -"47EA7227D8B22E2F", # IV -"E3F7A838AB911A4D", # Salt -""" -30820216304006092a864886f70d01050d3033301b06092a864886f70d01050c -300e0408e3f7a838ab911a4d02020800301406082a864886f70d0307040847ea -7227d8b22e2f048201d0ea388b374d2d0e4ceb7a5139f850fdff274884a6e6c0 -64326e09d00dbba9018834edb5a51a6ae3d1806e6e91eebf33788ce71fee0637 -a2ebf58859dd32afc644110c390274a6128b50c39b8d907823810ec471bada86 -6f5b75d8ea04ad310fad2e73621696db8e426cd511ee93ec1714a1a7db45e036 -4bf20d178d1f16bbb250b32c2d200093169d588de65f7d99aad9ddd0104b44f1 -326962e1520dfac3c2a800e8a14f678dff2b3d0bb23f69da635bf2a643ac934e -219a447d2f4460b67149e860e54f365da130763deefa649c72b0dcd48966a2d3 -4a477444782e3e66df5a582b07bbb19778a79bd355074ce331f4a82eb966b0c4 -52a09eab6116f2722064d314ae433b3d6e81d2436e93fdf446112663cde93b87 -9c8be44beb45f18e2c78fee9b016033f01ecda51b9b142091fa69f65ab784d2c -5ad8d34be6f7f1464adfc1e0ef3f7848f40d3bdea4412758f2fcb655c93d8f4d -f6fa48fc5aa4b75dd1c017ab79ac9d737233a6d668f5364ccf47786debd37334 -9c10c9e6efbe78430a61f71c89948aa32cdc3cc7338cf994147819ce7ab23450 -c8f7d9b94c3bb377d17a3fa204b601526317824b142ff6bc843fa7815ece89c0 -839573f234dac8d80cc571a045353d61db904a4398d8ef3df5ac -""" -)) - -# -# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der -outform DER -out keyenc.der -# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der -# -wrapped_enc_keys.append(( --1, # pbeWithMD5AndDES-CBC, only decoding is supported --1, -"", -"", -""" -308201f1301b06092a864886f70d010503300e0408f9b990c89af1d41b020208 -00048201d0c6267fe8592903891933d559e71a7ca68b2e39150f19daca0f7921 -52f97e249d72f670d5140e9150433310ed7c7ee51927693fd39884cb9551cea5 -a7b746f7edf199f8787d4787a35dad930d7db057b2118851211b645ac8b90fa6 -b0e7d49ac8567cbd5fff226e87aa9129a0f52c45e9307752e8575c3b0ff756b7 -31fda6942d15ecb6b27ea19370ccc79773f47891e80d22b440d81259c4c28eac -e0ca839524116bcf52d8c566e49a95ddb0e5493437279a770a39fd333f3fca91 -55884fad0ba5aaf273121f893059d37dd417da7dcfd0d6fa7494968f13b2cc95 -65633f2c891340193e5ec00e4ee0b0e90b3b93da362a4906360845771ade1754 -9df79140be5993f3424c012598eadd3e7c7c0b4db2c72cf103d7943a5cf61420 -93370b9702386c3dd4eb0a47f34b579624a46a108b2d13921fa1b367495fe345 -6aa128aa70f8ca80ae13eb301e96c380724ce67c54380bbea2316c1faf4d058e -b4ca2e23442047606b9bc4b3bf65b432cb271bea4eb35dd3eb360d3be8612a87 -a50e96a2264490aeabdc07c6e78e5dbf4fe3388726d0e2a228346bf3c2907d68 -2a6276b22ae883fb30fa611f4e4193e7a08480fcd7db48308bacbd72bf4807aa -11fd394859f97d22982f7fe890b2e2a0f7e7ffb693 -""" -)) - -# -# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der -# -outform DER -out keyenc.der -v1 PBE-SHA1-RC2-64 -# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der -# -wrapped_enc_keys.append(( --1, # pbeWithSHA1AndRC2-CBC, only decoding is supported --1, -"", -"", -""" -308201f1301b06092a864886f70d01050b300e04083ee943bdae185008020208 -00048201d0e4614d9371d3ff10ceabc2f6a7a13a0f449f9a714144e46518ea55 -e3e6f0cde24031d01ef1f37ec40081449ef01914faf45983dde0d2bc496712de -8dd15a5527dff4721d9016c13f34fb93e3ce68577e30146266d71b539f854e56 -753a192cf126ed4812734d86f81884374f1100772f78d0646e9946407637c565 -d070acab413c55952f7237437f2e48cae7fa0ff8d370de2bf446dd08049a3663 -d9c813ac197468c02e2b687e7ca994cf7f03f01b6eca87dbfed94502c2094157 -ea39f73fe4e591df1a68b04d19d9adab90bb9898467c1464ad20bf2b8fb9a5ff -d3ec91847d1c67fd768a4b9cfb46572eccc83806601372b6fad0243f58f623b7 -1c5809dea0feb8278fe27e5560eed8448dc93f5612f546e5dd7c5f6404365eb2 -5bf3396814367ae8b15c5c432b57eaed1f882c05c7f6517ee9e42b87b7b8d071 -9d6125d1b52f7b2cca1f6bd5f584334bf90bce1a7d938274cafe27b68e629698 -b16e27ae528db28593af9adcfccbebb3b9e1f2af5cd5531b51968389caa6c091 -e7de1f1b96f0d258e54e540d961a7c0ef51fda45d6da5fddd33e9bbfd3a5f8d7 -d7ab2e971de495cddbc86d38444fee9f0ac097b00adaf7802dabe0cff5b43b45 -4f26b7b547016f89be52676866189911c53e2f2477""" -)) - -# -# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der -# -outform DER -out keyenc.der -v1 PBE-MD5-RC2-64 -# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der -# -wrapped_enc_keys.append(( --1, # pbeWithMD5AndRC2-CBC, only decoding is supported --1, -"", -"", -""" -308201f1301b06092a864886f70d010506300e0408f5cd2fee56d9b4b8020208 -00048201d086454942d6166a19d6b108465bd111e7080911f573d54b1369c676 -df28600e84936bfec04f91023ff16499e2e07178c340904f12ffa6886ab66228 -32bf43c2bff5a0ed14e765918cf5fc543ad49566246f7eb3fc044fa5a9c25f40 -8fc8c8296b91658d3bb1067c0aba008c4fefd9e2bcdbbbd63fdc8085482bccf4 -f150cec9a084259ad441a017e5d81a1034ef2484696a7a50863836d0eeda45cd -8cee8ecabfed703f8d9d4bbdf3a767d32a0ccdc38550ee2928d7fe3fa27eda5b -5c7899e75ad55d076d2c2d3c37d6da3d95236081f9671dab9a99afdb1cbc890e -332d1a91105d9a8ce08b6027aa07367bd1daec3059cb51f5d896124da16971e4 -0ca4bcadb06c854bdf39f42dd24174011414e51626d198775eff3449a982df7b -ace874e77e045eb6d7c3faef0750792b29a068a6291f7275df1123fac5789c51 -27ace42836d81633faf9daf38f6787fff0394ea484bbcd465b57d4dbee3cf8df -b77d1db287b3a6264c466805be5a4fe85cfbca180699859280f2dd8e2c2c10b5 -7a7d2ac670c6039d41952fbb0e4f99b560ebe1d020e1b96d02403283819c00cc -529c51f0b0101555e4c58002ba3c6e3c12e3fde1aec94382792e96d9666a2b33 -3dc397b22ecab67ee38a552fec29a1d4ff8719c748""" -)) - -# -# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der -# -outform DER -out keyenc.der -v1 PBE-SHA1-DES -# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der -# -wrapped_enc_keys.append(( --1, # pbeWithSHA1AndDES-CBC, only decoding is supported --1, -"", -"", -""" -308201f1301b06092a864886f70d01050a300e04089bacc9cf1e8f734e020208 -00048201d03e502f3ceafe8fd19ab2939576bfdded26d719b2441db1459688f5 -9673218b41ec1f739edf1e460bd927bc28470c87b2d4fc8ea02ba17b47a63c49 -c5c1bee40529dadfd3ef8b4472c730bc136678c78abfb34670ec9d7dcd17ee3f -892f93f2629e6e0f4b24ecb9f954069bf722f466dece3913bb6abbd2c471d9a5 -c5eea89b14aaccda43d30b0dd0f6eb6e9850d9747aa8aa8414c383ad01c374ee -26d3552abec9ba22669cc9622ccf2921e3d0c8ecd1a70e861956de0bec6104b5 -b649ac994970c83f8a9e84b14a7dff7843d4ca3dd4af87cea43b5657e15ae0b5 -a940ce5047f006ab3596506600724764f23757205fe374fee04911336d655acc -03e159ec27789191d1517c4f3f9122f5242d44d25eab8f0658cafb928566ca0e -8f6589aa0c0ab13ca7a618008ae3eafd4671ee8fe0b562e70b3623b0e2a16eee -97fd388087d2e03530c9fe7db6e52eccc7c48fd701ede35e08922861a9508d12 -bc8bbf24f0c6bee6e63dbcb489b603d4c4a78ce45bf2eab1d5d10456c42a65a8 -3a606f4e4b9b46eb13b57f2624b651859d3d2d5192b45dbd5a2ead14ff20ca76 -48f321309aa56d8c0c4a192b580821cc6c70c75e6f19d1c5414da898ec4dd39d -b0eb93d6ba387a80702dfd2db610757ba340f63230 -""" -)) - -# -# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der -# -outform DER -out keyenc.der -v2 aes128 -# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der -# -wrapped_enc_keys.append(( -'PBKDF2WithHMAC-SHA1AndAES128-CBC', -2048, -"4F66EE5D3BCD531FE6EBF4B4E73016B8", # IV -"479F25156176C53A", # Salt -""" -3082021f304906092a864886f70d01050d303c301b06092a864886f70d01050c -300e0408479f25156176c53a02020800301d060960864801650304010204104f -66ee5d3bcd531fe6ebf4b4e73016b8048201d0e33cfa560423f589d097d21533 -3b880a5ebac5b2ac58b4e73b0d787aee7764f034fe34ca1d1bd845c0a7c3316f -afbfb2129e03dcaf5a5031394206492828dacef1e04639bee5935e0f46114202 -10bc6c37182f4889be11c5d0486c398f4be952e5740f65de9d8edeb275e2b406 -e19bc29ad5ebb97fa536344fc3d84c7e755696f12b810898de4e6f069b8a81c8 -0aab0d45d7d062303aaa4a10c2ce84fdb5a03114039cfe138e38bb15b2ced717 -93549cdad85e730b14d9e2198b663dfdc8d04a4349eb3de59b076ad40b116d4a -25ed917c576bc7c883c95ef0f1180e28fc9981bea069594c309f1aa1b253ceab -a2f0313bb1372bcb51a745056be93d77a1f235a762a45e8856512d436b2ca0f7 -dd60fbed394ba28978d2a2b984b028529d0a58d93aba46c6bbd4ac1e4013cbaa -63b00988bc5f11ccc40141c346762d2b28f64435d4be98ec17c1884985e3807e -e550db606600993efccf6de0dfc2d2d70b5336a3b018fa415d6bdd59f5777118 -16806b7bc17c4c7e20ad7176ebfa5a1aa3f6bc10f04b77afd443944642ac9cca -d740e082b4a3bbb8bafdd34a0b3c5f2f3c2aceccccdccd092b78994b845bfa61 -706c3b9df5165ed1dbcbf1244fe41fc9bf993f52f7658e2f87e1baaeacb0f562 -9d905c -""" -)) - -# -# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der -# -outform DER -out keyenc.der -v2 aes192 -# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der -# -wrapped_enc_keys.append(( -'PBKDF2WithHMAC-SHA1AndAES192-CBC', -2048, -"5CFC2A4FF7B63201A4A8A5B021148186", # IV -"D718541C264944CE", # Salt -""" -3082021f304906092a864886f70d01050d303c301b06092a864886f70d01050c -300e0408d718541c264944ce02020800301d060960864801650304011604105c -fc2a4ff7b63201a4a8a5b021148186048201d08e74aaa21b8bcfb15b9790fe95 -b0e09ddb0f189b6fb1682fdb9f122b804650ddec3c67a1df093a828b3e5fbcc6 -286abbcc5354c482fd796d972e919ca8a5eba1eaa2293af1d648013ddad72106 -75622264dfba55dafdda39e338f058f1bdb9846041ffff803797d3fdf3693135 -8a192729ea8346a7e5e58e925a2e2e4af0818581859e8215d87370eb4194a5ff -bae900857d4c591dbc651a241865a817eaede9987c9f9ae4f95c0bf930eea88c -4d7596e535ffb7ca369988aba75027a96b9d0bc9c8b0b75f359067fd145a378b -02aaa15e9db7a23176224da48a83249005460cc6e429168657f2efa8b1af7537 -d7d7042f2d683e8271b21d591090963eeb57aea6172f88da139e1614d6a7d1a2 -1002d5a7a93d6d21156e2b4777f6fc069287a85a1538c46b7722ccde591ab55c -630e1ceeb1ac42d1b41f3f654e9da86b5efced43775ea68b2594e50e4005e052 -0fe753c0898120c2c07265367ff157f6538a1e4080d6f9d1ca9eb51939c9574e -f2e4e1e87c1434affd5808563cddd376776dbbf790c6a40028f311a8b58dafa2 -0970ed34acd6e3e89d063987893b2b9570ddb8cc032b05a723bba9444933ebf3 -c624204be72f4190e0245197d0cb772bec933fd8442445f9a28bd042d5a3a1e9 -9a8a07 -""" -)) - -# -# openssl pkcs8 -topk8 -passin pass:TestTest -inform DER -in key.der -# -outform DER -out keyenc.der -v2 aes192 -# hexdump -v -e '32/1 "%02x" "\n"' keyenc.der -# -wrapped_enc_keys.append(( -'PBKDF2WithHMAC-SHA1AndAES256-CBC', -2048, -"323351F94462AC563E053A056252C2C4", # IV -"02A6CD0D12E727B5", # Salt -""" -3082021f304906092a864886f70d01050d303c301b06092a864886f70d01050c -300e040802a6cd0d12e727b502020800301d060960864801650304012a041032 -3351f94462ac563e053a056252c2c4048201d07f4ef1c7be21aae738a20c5632 -b8bdbbb9083b6e7f68822267b1f481fd27fdafd61a90660de6e4058790e4c912 -bf3f319a7c37e6eb3d956daaa143865020d554bf6215e8d7492359aaeef45d6e -d85a686ed26c0bf7c18d071d827a86f0b73e1db0c0e7f3d42201544093302a90 -551ad530692468c47ac15c69500b8ca67d4a17b64d15cecc035ae50b768a36cf -07c395afa091e9e6f86f665455fbdc1b21ad79c0908b73da5de75a9b43508d5d -44dc97a870cd3cd9f01ca24452e9b11c1b4982946702cfcbfda5b2fcc0203fb5 -0b52a115760bd635c94d4c95ac2c640ee9a04ffaf6ccff5a8d953dd5d88ca478 -c377811c521f2191639c643d657a9e364af88bb7c14a356c2b0b4870a23c2f54 -d41f8157afff731471dccc6058b15e1151bcf84b39b5e622a3a1d65859c912a5 -591b85e034a1f6af664f030a6bfc8c3d20c70f32b54bcf4da9c2da83cef49cf8 -e9a74f0e5d358fe50b88acdce6a9db9a7ad61536212fc5f877ebfc7957b8bda4 -b1582a0f10d515a20ee06cf768db9c977aa6fbdca7540d611ff953012d009dac -e8abd059f8e8ffea637c9c7721f817aaf0bb23403e26a0ef0ff0e2037da67d41 -af728481f53443551a9bff4cea023164e9622b5441a309e1f4bff98e5bf76677 -8d7cd9 -""" -)) - -def txt2bin(inputs): - s = b('').join([b(x) for x in inputs if not (x in '\n\r\t ')]) - return unhexlify(s) - -class Rng: - def __init__(self, output): - self.output=output - self.idx=0 - def __call__(self, n): - output = self.output[self.idx:self.idx+n] - self.idx += n - return output - -class PKCS8_Decrypt(unittest.TestCase): - - def setUp(self): - self.oid_key = oid_key - self.clear_key = txt2bin(clear_key) - self.wrapped_clear_key = txt2bin(wrapped_clear_key) - self.wrapped_enc_keys = [] - for t in wrapped_enc_keys: - self.wrapped_enc_keys.append(( - t[0], - t[1], - txt2bin(t[2]), - txt2bin(t[3]), - txt2bin(t[4]) - )) - - ### NO ENCRYTION - - def test1(self): - """Verify unwrapping w/o encryption""" - res1, res2, res3 = PKCS8.unwrap(self.wrapped_clear_key) - self.assertEqual(res1, self.oid_key) - self.assertEqual(res2, self.clear_key) - - def test2(self): - """Verify wrapping w/o encryption""" - wrapped = PKCS8.wrap(self.clear_key, self.oid_key) - res1, res2, res3 = PKCS8.unwrap(wrapped) - self.assertEqual(res1, self.oid_key) - self.assertEqual(res2, self.clear_key) - - ## ENCRYPTION - - def test3(self): - """Verify unwrapping with encryption""" - - for t in self.wrapped_enc_keys: - res1, res2, res3 = PKCS8.unwrap(t[4], b("TestTest")) - self.assertEqual(res1, self.oid_key) - self.assertEqual(res2, self.clear_key) - - def test4(self): - """Verify wrapping with encryption""" - - for t in self.wrapped_enc_keys: - if t[0]==-1: - continue - rng = Rng(t[2]+t[3]) - params = { 'iteration_count':t[1] } - wrapped = PKCS8.wrap( - self.clear_key, - self.oid_key, - b("TestTest"), - protection=t[0], - prot_params=params, - key_params=None, - randfunc=rng) - self.assertEqual(wrapped, t[4]) - -def get_tests(config={}): - from Crypto.SelfTest.st_common import list_test_cases - listTests = [] - listTests += list_test_cases(PKCS8_Decrypt) - return listTests - -if __name__ == '__main__': - suite = lambda: unittest.TestSuite(get_tests()) - unittest.main(defaultTest='suite') - diff --git a/lib/Crypto/SelfTest/Protocol/__init__.py b/lib/Crypto/SelfTest/Protocol/__init__.py index 33ff5817..a62c670f 100644 --- a/lib/Crypto/SelfTest/Protocol/__init__.py +++ b/lib/Crypto/SelfTest/Protocol/__init__.py @@ -31,7 +31,6 @@ def get_tests(config={}): from Crypto.SelfTest.Protocol import test_chaffing; tests += test_chaffing.get_tests(config=config) from Crypto.SelfTest.Protocol import test_rfc1751; tests += test_rfc1751.get_tests(config=config) from Crypto.SelfTest.Protocol import test_AllOrNothing; tests += test_AllOrNothing.get_tests(config=config) - from Crypto.SelfTest.Protocol import test_KDF; tests += test_KDF.get_tests(config=config) return tests if __name__ == '__main__': diff --git a/lib/Crypto/SelfTest/Protocol/test_KDF.py b/lib/Crypto/SelfTest/Protocol/test_KDF.py index de09b41d..119836bb 100644 --- a/lib/Crypto/SelfTest/Protocol/test_KDF.py +++ b/lib/Crypto/SelfTest/Protocol/test_KDF.py @@ -25,13 +25,10 @@ import unittest from binascii import unhexlify -from Crypto.Util.py3compat import * - from Crypto.SelfTest.st_common import list_test_cases -from Crypto.Hash import SHA1, HMAC -from Crypto.Cipher import AES, DES3 +from Crypto.Hash import SHA as SHA1,HMAC -from Crypto.Protocol.KDF import PBKDF1, PBKDF2, _S2V +from Crypto.Protocol.KDF import * def t2b(t): return unhexlify(b(t)) @@ -48,7 +45,7 @@ class PBKDF1_Tests(unittest.TestCase): # From http://www.di-mgt.com.au/cryptoKDFs.html#examplespbkdf ("password","78578E5A5D63CB06",16,1000,"DC19847E05C64D2FAF10EBFB4A3D2A20"), ) - + def test1(self): v = self._testData[0] res = PBKDF1(v[0], t2b(v[1]), v[2], v[3], SHA1) @@ -74,7 +71,7 @@ class PBKDF2_Tests(unittest.TestCase): 25, 4096, "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"), ( 'pass\x00word',"7361006c74",16,4096, "56fa6aa75548099dcc37d7f03425e0c3"), ) - + def test1(self): # Test only for HMAC-SHA1 as PRF @@ -88,67 +85,10 @@ def prf(p,s): self.assertEqual(res, t2b(v[4])) self.assertEqual(res, res2) -class S2V_Tests(unittest.TestCase): - - # Sequence of test vectors. - # Each test vector is made up by: - # Item #0: a tuple of strings - # Item #1: an AES key - # Item #2: the result - # Item #3: the cipher module S2V is based on - # Everything is hex encoded - _testData = [ - - # RFC5297, A.1 - ( - ( '101112131415161718191a1b1c1d1e1f2021222324252627', - '112233445566778899aabbccddee' ), - 'fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0', - '85632d07c6e8f37f950acd320a2ecc93', - AES - ), - - # RFC5297, A.2 - ( - ( '00112233445566778899aabbccddeeffdeaddadadeaddadaffeeddcc'+ - 'bbaa99887766554433221100', - '102030405060708090a0', - '09f911029d74e35bd84156c5635688c0', - '7468697320697320736f6d6520706c61'+ - '696e7465787420746f20656e63727970'+ - '74207573696e67205349562d414553'), - '7f7e7d7c7b7a79787776757473727170', - '7bdb6e3b432667eb06f4d14bff2fbd0f', - AES - ), - - ] - - def test1(self): - """Verify correctness of test vector""" - for tv in self._testData: - s2v = _S2V.new(t2b(tv[1]), tv[3]) - for s in tv[0]: - s2v.update(t2b(s)) - result = s2v.derive() - self.assertEqual(result, t2b(tv[2])) - - def test2(self): - """Verify that no more than 127(AES) and 63(TDES) - components are accepted.""" - key = bchr(0)*16 - for module in (AES, DES3): - s2v = _S2V.new(key, module) - max_comps = module.block_size*8-1 - for i in xrange(max_comps): - s2v.update(b("XX")) - self.assertRaises(TypeError, s2v.update, b("YY")) - def get_tests(config={}): tests = [] tests += list_test_cases(PBKDF1_Tests) tests += list_test_cases(PBKDF2_Tests) - tests += list_test_cases(S2V_Tests) return tests if __name__ == '__main__': diff --git a/lib/Crypto/SelfTest/PublicKey/__init__.py b/lib/Crypto/SelfTest/PublicKey/__init__.py index 23a13a4a..61ba53f2 100644 --- a/lib/Crypto/SelfTest/PublicKey/__init__.py +++ b/lib/Crypto/SelfTest/PublicKey/__init__.py @@ -32,13 +32,7 @@ def get_tests(config={}): tests = [] from Crypto.SelfTest.PublicKey import test_DSA; tests += test_DSA.get_tests(config=config) from Crypto.SelfTest.PublicKey import test_RSA; tests += test_RSA.get_tests(config=config) - - from Crypto.SelfTest.PublicKey import test_import_DSA - tests +=test_import_DSA.get_tests(config=config) - - from Crypto.SelfTest.PublicKey import test_import_RSA - tests += test_import_RSA.get_tests(config=config) - + from Crypto.SelfTest.PublicKey import test_importKey; tests += test_importKey.get_tests(config=config) from Crypto.SelfTest.PublicKey import test_ElGamal; tests += test_ElGamal.get_tests(config=config) return tests diff --git a/lib/Crypto/SelfTest/PublicKey/test_DSA.py b/lib/Crypto/SelfTest/PublicKey/test_DSA.py index 037e0876..b05f69ac 100644 --- a/lib/Crypto/SelfTest/PublicKey/test_DSA.py +++ b/lib/Crypto/SelfTest/PublicKey/test_DSA.py @@ -225,8 +225,15 @@ def get_tests(config={}): from Crypto.PublicKey import _fastmath tests += list_test_cases(DSAFastMathTest) except ImportError: - from Crypto.SelfTest.st_common import handle_fastmath_import_error - handle_fastmath_import_error() + from distutils.sysconfig import get_config_var + import inspect + _fm_path = os.path.normpath(os.path.dirname(os.path.abspath( + inspect.getfile(inspect.currentframe()))) + +"/../../PublicKey/_fastmath"+get_config_var("SO")) + if os.path.exists(_fm_path): + raise ImportError("While the _fastmath module exists, importing "+ + "it failed. This may point to the gmp or mpir shared library "+ + "not being in the path. _fastmath was found at "+_fm_path) tests += list_test_cases(DSASlowMathTest) return tests diff --git a/lib/Crypto/SelfTest/PublicKey/test_ElGamal.py b/lib/Crypto/SelfTest/PublicKey/test_ElGamal.py index 5f33c235..cdee8cf6 100644 --- a/lib/Crypto/SelfTest/PublicKey/test_ElGamal.py +++ b/lib/Crypto/SelfTest/PublicKey/test_ElGamal.py @@ -28,7 +28,7 @@ from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex from Crypto import Random from Crypto.PublicKey import ElGamal -from Crypto.Util.number import bytes_to_long +from Crypto.Util.number import * from Crypto.Util.py3compat import * class ElGamalTest(unittest.TestCase): @@ -151,7 +151,7 @@ def convert_tv(self, tv, as_longs=0): tv2['key'] += [tv2[c]] del tv2[c] return tv2 - + def _test_random_key(self, bits): elgObj = ElGamal.generate(bits, Random.new().read) self._check_private_key(elgObj) diff --git a/lib/Crypto/SelfTest/PublicKey/test_RSA.py b/lib/Crypto/SelfTest/PublicKey/test_RSA.py index 16310f71..c971042b 100644 --- a/lib/Crypto/SelfTest/PublicKey/test_RSA.py +++ b/lib/Crypto/SelfTest/PublicKey/test_RSA.py @@ -28,7 +28,6 @@ import sys import os -import pickle if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * @@ -88,21 +87,6 @@ class RSATest(unittest.TestCase): ce 33 52 52 4d 04 16 a5 a4 41 e7 00 af 46 15 03 """ - # The same key, in pickled format (from pycrypto 2.3) - # to ensure backward compatibility - pickled_key_2_3 = \ - "(iCrypto.PublicKey.RSA\n_RSAobj\np0\n(dp2\nS'e'\np3\nL17L\nsS'd'\np4"\ - "\nL11646763154293086160147889314553506764606353688284149120983587488"\ - "79382229568306696406525871631480713149376749558222371890533687587223"\ - "51580531956820574156366843733156436163097164007967904900300775223658"\ - "03543233292399245064743971969473468304536714979010219881003396235861"\ - "8370829441895425705728523874962107052993L\nsS'n'\np5\nL1319966490819"\ - "88309815009412231606409998872008467220356704480658206329986017741425"\ - "59273959878490114749026269828326520214759381792655199845793621772998"\ - "40439054838068985140623386496543388290455526885872858516219460533763"\ - "92312680578795692682905599590422046720587710762927130740460442438533"\ - "124053848898103790124491L\nsb." - def setUp(self): global RSA, Random, bytes_to_long from Crypto.PublicKey import RSA @@ -194,42 +178,6 @@ def test_factoring(self): self.assertRaises(ValueError, self.rsa.construct, [self.n, self.e, self.n-1]) - def test_serialization(self): - """RSA (default implementation) serialize/unserialize key""" - rsaObj_orig = self.rsa.generate(1024) - rsaObj = pickle.loads(pickle.dumps(rsaObj_orig)) - self._check_private_key(rsaObj) - self._exercise_primitive(rsaObj) - pub = rsaObj.publickey() - self._check_public_key(pub) - self._exercise_public_primitive(rsaObj) - - plaintext = a2b_hex(self.plaintext) - ciphertext1 = rsaObj_orig.encrypt(plaintext, b("")) - ciphertext2 = rsaObj.encrypt(plaintext, b("")) - self.assertEqual(ciphertext1, ciphertext2) - - if not (3, 0) <= sys.version_info < (3, 1, 2, 'final', 0): - # Unpickling is broken in Python 3 before 3.1.2 due to http://bugs.python.org/issue6137 - def test_serialization_compat(self): - """RSA (default implementation) backward compatibility serialization""" - rsaObj = pickle.loads(b(self.pickled_key_2_3)) - plaintext = a2b_hex(self.plaintext) - ciphertext = a2b_hex(self.ciphertext) - ciphertext_result = rsaObj.encrypt(plaintext, b(""))[0] - self.assertEqual(ciphertext_result, ciphertext) - - def test_raw_rsa_boundary(self): - # The argument of every RSA raw operation (encrypt/decrypt) must be positive - # and no larger than the modulus - rsa_obj = self.rsa.generate(1024) - - self.assertRaises(ValueError, rsa_obj.decrypt, (rsa_obj.n,)) - self.assertRaises(ValueError, rsa_obj.encrypt, rsa_obj.n, b("")) - - self.assertRaises(ValueError, rsa_obj.decrypt, (0,)) - self.assertRaises(ValueError, rsa_obj.encrypt, 0, b("")) - def _check_private_key(self, rsaObj): # Check capabilities self.assertEqual(1, rsaObj.has_private()) @@ -404,20 +352,6 @@ def test_construct_6tuple(self): def test_factoring(self): RSATest.test_factoring(self) - - def test_serialization(self): - """RSA (_fastmath implementation) serialize/unserialize key - """ - RSATest.test_serialization(self) - - if not (3, 0) <= sys.version_info < (3, 1, 2, 'final', 0): - # Unpickling is broken in Python 3 before 3.1.2 due to http://bugs.python.org/issue6137 - def test_serialization_compat(self): - """RSA (_fastmath implementation) backward compatibility serialization - """ - RSATest.test_serialization_compat(self) - - class RSASlowMathTest(RSATest): def setUp(self): RSATest.setUp(self) @@ -454,17 +388,6 @@ def test_construct_6tuple(self): def test_factoring(self): RSATest.test_factoring(self) - def test_serialization(self): - """RSA (_slowmath implementation) serialize/unserialize key""" - RSATest.test_serialization(self) - - if not (3, 0) <= sys.version_info < (3, 1, 2, 'final', 0): - # Unpickling is broken in Python 3 before 3.1.2 due to http://bugs.python.org/issue6137 - def test_serialization_compat(self): - """RSA (_slowmath implementation) backward compatibility serialization - """ - RSATest.test_serialization_compat(self) - def get_tests(config={}): tests = [] tests += list_test_cases(RSATest) @@ -472,8 +395,15 @@ def get_tests(config={}): from Crypto.PublicKey import _fastmath tests += list_test_cases(RSAFastMathTest) except ImportError: - from Crypto.SelfTest.st_common import handle_fastmath_import_error - handle_fastmath_import_error() + from distutils.sysconfig import get_config_var + import inspect + _fm_path = os.path.normpath(os.path.dirname(os.path.abspath( + inspect.getfile(inspect.currentframe()))) + +"/../../PublicKey/_fastmath"+get_config_var("SO")) + if os.path.exists(_fm_path): + raise ImportError("While the _fastmath module exists, importing "+ + "it failed. This may point to the gmp or mpir shared library "+ + "not being in the path. _fastmath was found at "+_fm_path) if config.get('slow_tests',1): tests += list_test_cases(RSASlowMathTest) return tests diff --git a/lib/Crypto/SelfTest/PublicKey/test_import_RSA.py b/lib/Crypto/SelfTest/PublicKey/test_importKey.py similarity index 75% rename from lib/Crypto/SelfTest/PublicKey/test_import_RSA.py rename to lib/Crypto/SelfTest/PublicKey/test_importKey.py index ff65e774..28a7eee8 100644 --- a/lib/Crypto/SelfTest/PublicKey/test_import_RSA.py +++ b/lib/Crypto/SelfTest/PublicKey/test_importKey.py @@ -66,8 +66,7 @@ class ImportKeyTests(unittest.TestCase): # The same RSA private key as in rsaKeyPEM, but now encrypted rsaKeyEncryptedPEM=( - - # PEM encryption + # With DES and passphrase 'test' ('test', u'''-----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED @@ -80,30 +79,32 @@ class ImportKeyTests(unittest.TestCase): 9bMbdb/1PSvsSzPsqW7KSSrTw6MgJAFJg6lzIYvR5F4poTVBxwBX3+EyEmShiaNY IRX3TgQI0IjrVuLmvlZKbGWP18FXj7I7k9tSsNOOzllTTdq3ny5vgM3A+ynfAaxp dysKznQ6P+IoqML1WxAID4aGRMWka+uArOJ148Rbj9s= ------END RSA PRIVATE KEY-----'''), - - # PKCS8 encryption - ('winter', u'''-----BEGIN ENCRYPTED PRIVATE KEY----- -MIIBpjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIeZIsbW3O+JcCAggA -MBQGCCqGSIb3DQMHBAgSM2p0D8FilgSCAWBhFyP2tiGKVpGj3mO8qIBzinU60ApR -3unvP+N6j7LVgnV2lFGaXbJ6a1PbQXe+2D6DUyBLo8EMXrKKVLqOMGkFMHc0UaV6 -R6MmrsRDrbOqdpTuVRW+NVd5J9kQQh4xnfU/QrcPPt7vpJvSf4GzG0n666Ki50OV -M/feuVlIiyGXY6UWdVDpcOV72cq02eNUs/1JWdh2uEBvA9fCL0c07RnMrdT+CbJQ -NjJ7f8ULtp7xvR9O3Al/yJ4Wv3i4VxF1f3MCXzhlUD4I0ONlr0kJWgeQ80q/cWhw -ntvgJwnCn2XR1h6LA8Wp+0ghDTsL2NhJpWd78zClGhyU4r3hqu1XDjoXa7YCXCix -jCV15+ViDJzlNCwg+W6lRg18sSLkCT7alviIE0U5tHc6UPbbHwT5QqAxAABaP+nZ -CGqJGyiwBzrKebjgSm/KRd4C91XqcsysyH2kKPfT51MLAoD4xelOURBP ------END ENCRYPTED PRIVATE KEY-----''' - ), +-----END RSA PRIVATE KEY-----''', + "\xAF\x8F\x9A\x40\xBD\x2F\xA2\xFC"), + + # With Triple-DES and passphrase 'rocking' + ('rocking', u'''-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,C05D6C07F7FC02F6 + +w4lwQrXaVoTTJ0GgwY566htTA2/t1YlimhxkxYt9AEeCcidS5M0Wq9ClPiPz9O7F +m6K5QpM1rxo1RUE/ZyI85gglRNPdNwkeTOqit+kum7nN73AToX17+irVmOA4Z9E+ +4O07t91GxGMcjUSIFk0ucwEU4jgxRvYscbvOMvNbuZszGdVNzBTVddnShKCsy9i7 +nJbPlXeEKYi/OkRgO4PtfqqWQu5GIEFVUf9ev1QV7AvC+kyWTR1wWYnHX265jU5c +sopxQQtP8XEHIJEdd5/p1oieRcWTCNyY8EkslxDSsrf0OtZp6mZH9N+KU47cgQtt +9qGORmlWnsIoFFKcDohbtOaWBTKhkj5h6OkLjFjfU/sBeV1c+7wDT3dAy5tawXjG +YSxC7qDQIT/RECvV3+oQKEcmpEujn45wAnkTi12BH30= +-----END RSA PRIVATE KEY-----''', + "\xC0\x5D\x6C\x07\xF7\xFC\x02\xF6"), ) - rsaPublicKeyPEM = u'''-----BEGIN RSA PUBLIC KEY----- + rsaPublicKeyPEM = u'''-----BEGIN PUBLIC KEY----- MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+T Lr7UkvEtFrRhDDKMtuIIq19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQ== ------END RSA PUBLIC KEY-----''' +-----END PUBLIC KEY-----''' # Obtained using 'ssh-keygen -i -m PKCS8 -f rsaPublicKeyPEM' - rsaPublicKeyOpenSSH = b('''ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQC/HieQCqCLI1EaXBKBrm2TMSw+/pE/ky6+1JLxLRa0YQwyjLbiCKtfRay+KVCDMpjzEiwZ94SS3t9A8OPBkDOF comment\n''') + rsaPublicKeyOpenSSH = '''ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAQQC/HieQCqCLI1EaXBKBrm2TMSw+/pE/ky6+1JLxLRa0YQwyjLbiCKtfRay+KVCDMpjzEiwZ94SS3t9A8OPBkDOF comment\n''' # The private key, in PKCS#1 format encoded with DER rsaKeyDER = a2b_hex( @@ -297,85 +298,25 @@ def testExportKey5(self): self.assertEqual(openssh_1[0], openssh_2[0]) self.assertEqual(openssh_1[1], openssh_2[1]) - def testExportKey7(self): + def testExportKey4(self): + key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) + # Tuple with index #1 is encrypted with 3DES + t = map(b,self.rsaKeyEncryptedPEM[1]) + # Force the salt being used when exporting + key._randfunc = lambda N: (t[2]*divmod(N+len(t[2]),len(t[2]))[0])[:N] + pemKey = key.exportKey("PEM", t[0]) + self.assertEqual(pemKey, t[1]) + + def testExportKey5(self): key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) derKey = key.exportKey("DER", pkcs=8) self.assertEqual(derKey, self.rsaKeyDER8) - def testExportKey8(self): + def testExportKey6(self): key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) pemKey = key.exportKey("PEM", pkcs=8) self.assertEqual(pemKey, b(self.rsaKeyPEM8)) - def testExportKey9(self): - key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) - self.assertRaises(ValueError, key.exportKey, "invalid-format") - - def testExportKey10(self): - # Export and re-import the encrypted key. It must match. - # PEM envelope, PKCS#1, old PEM encryption - key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) - outkey = key.exportKey('PEM', 'test') - self.failUnless(tostr(outkey).find('4,ENCRYPTED')!=-1) - self.failUnless(tostr(outkey).find('BEGIN RSA PRIVATE KEY')!=-1) - inkey = RSA.importKey(outkey, 'test') - self.assertEqual(key.n, inkey.n) - self.assertEqual(key.e, inkey.e) - self.assertEqual(key.d, inkey.d) - - def testExportKey11(self): - # Export and re-import the encrypted key. It must match. - # PEM envelope, PKCS#1, old PEM encryption - key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) - outkey = key.exportKey('PEM', 'test', pkcs=1) - self.failUnless(tostr(outkey).find('4,ENCRYPTED')!=-1) - self.failUnless(tostr(outkey).find('BEGIN RSA PRIVATE KEY')!=-1) - inkey = RSA.importKey(outkey, 'test') - self.assertEqual(key.n, inkey.n) - self.assertEqual(key.e, inkey.e) - self.assertEqual(key.d, inkey.d) - - def testExportKey12(self): - # Export and re-import the encrypted key. It must match. - # PEM envelope, PKCS#8, old PEM encryption - key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) - outkey = key.exportKey('PEM', 'test', pkcs=8) - self.failUnless(tostr(outkey).find('4,ENCRYPTED')!=-1) - self.failUnless(tostr(outkey).find('BEGIN PRIVATE KEY')!=-1) - inkey = RSA.importKey(outkey, 'test') - self.assertEqual(key.n, inkey.n) - self.assertEqual(key.e, inkey.e) - self.assertEqual(key.d, inkey.d) - - def testExportKey13(self): - # Export and re-import the encrypted key. It must match. - # PEM envelope, PKCS#8, PKCS#8 encryption - key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) - outkey = key.exportKey('PEM', 'test', pkcs=8, - protection='PBKDF2WithHMAC-SHA1AndDES-EDE3-CBC') - self.failUnless(tostr(outkey).find('4,ENCRYPTED')==-1) - self.failUnless(tostr(outkey).find('BEGIN ENCRYPTED PRIVATE KEY')!=-1) - inkey = RSA.importKey(outkey, 'test') - self.assertEqual(key.n, inkey.n) - self.assertEqual(key.e, inkey.e) - self.assertEqual(key.d, inkey.d) - - def testExportKey14(self): - # Export and re-import the encrypted key. It must match. - # DER envelope, PKCS#8, PKCS#8 encryption - key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) - outkey = key.exportKey('DER', 'test', pkcs=8) - inkey = RSA.importKey(outkey, 'test') - self.assertEqual(key.n, inkey.n) - self.assertEqual(key.e, inkey.e) - self.assertEqual(key.d, inkey.d) - - def testExportKey15(self): - # Verify that that error an condition is detected when trying to - # use a password with DER encoding and PKCS#1. - key = self.rsa.construct([self.n, self.e, self.d, self.p, self.q, self.pInv]) - self.assertRaises(ValueError, key.exportKey, 'DER', 'test', 1) - class ImportKeyTestsSlow(ImportKeyTests): def setUp(self): self.rsa = RSA.RSAImplementation(use_fast_math=0) diff --git a/lib/Crypto/SelfTest/PublicKey/test_import_DSA.py b/lib/Crypto/SelfTest/PublicKey/test_import_DSA.py deleted file mode 100644 index 82e1ad8d..00000000 --- a/lib/Crypto/SelfTest/PublicKey/test_import_DSA.py +++ /dev/null @@ -1,389 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SelfTest/PublicKey/test_import_DSA.py: Self-test for importing DSA keys -# -# =================================================================== -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# =================================================================== - -import unittest - -from Crypto.PublicKey import DSA -from Crypto.SelfTest.st_common import * -from Crypto.Util.py3compat import * - -from binascii import unhexlify - -class ImportKeyTests(unittest.TestCase): - - y = 92137165128186062214622779787483327510946462589285775188003362705875131352591574106484271700740858696583623951844732128165434284507709057439633739849986759064015013893156866539696757799934634945787496920169462601722830899660681779448742875054459716726855443681559131362852474817534616736104831095601710736729L - p = 162452170958135306109773853318304545923250830605675936228618290525164105310663722368377131295055868997377338797580997938253236213714988311430600065853662861806894003694743806769284131194035848116051021923956699231855223389086646903420682639786976554552864568460372266462812137447840653688476258666833303658691L - q = 988791743931120302950649732173330531512663554851L - g = 85583152299197514738065570254868711517748965097380456700369348466136657764813442044039878840094809620913085570225318356734366886985903212775602770761953571967834823306046501307810937486758039063386311593890777319935391363872375452381836756832784184928202587843258855704771836753434368484556809100537243908232L - x = 540873410045082450874416847965843801027716145253L - - def setUp(self): - - # It is easier to write test vectors in text form, - # and convert them to byte strigs dynamically here - for mname, mvalue in ImportKeyTests.__dict__.items(): - if mname[:4] in ('der_', 'pem_', 'ssh_'): - if mname[:4] == 'der_': - mvalue = unhexlify(tobytes(mvalue)) - mvalue = tobytes(mvalue) - setattr(self, mname, mvalue) - - # 1. SubjectPublicKeyInfo - der_public=\ - '308201b73082012b06072a8648ce3804013082011e02818100e756ee1717f4b6'+\ - '794c7c214724a19763742c45572b4b3f8ff3b44f3be9f44ce039a2757695ec91'+\ - '5697da74ef914fcd1b05660e2419c761d639f45d2d79b802dbd23e7ab8b81b47'+\ - '9a380e1f30932584ba2a0b955032342ebc83cb5ca906e7b0d7cd6fe656cecb4c'+\ - '8b5a77123a8c6750a481e3b06057aff6aa6eba620b832d60c3021500ad32f48c'+\ - 'd3ae0c45a198a61fa4b5e20320763b2302818079dfdc3d614fe635fceb7eaeae'+\ - '3718dc2efefb45282993ac6749dc83c223d8c1887296316b3b0b54466cf444f3'+\ - '4b82e3554d0b90a778faaf1306f025dae6a3e36c7f93dd5bac4052b92370040a'+\ - 'ca70b8d5820599711900efbc961812c355dd9beffe0981da85c5548074b41c56'+\ - 'ae43fd300d89262e4efd89943f99a651b03888038185000281810083352a69a1'+\ - '32f34843d2a0eb995bff4e2f083a73f0049d2c91ea2f0ce43d144abda48199e4'+\ - 'b003c570a8af83303d45105f606c5c48d925a40ed9c2630c2fa4cdbf838539de'+\ - 'b9a29f919085f2046369f627ca84b2cb1e2c7940564b670f963ab1164d4e2ca2'+\ - 'bf6ffd39f12f548928bf4d2d1b5e6980b4f1be4c92a91986fba559' - - def testImportKey1(self): - key_obj = self.dsa.importKey(self.der_public) - self.failIf(key_obj.has_private()) - self.assertEqual(self.y, key_obj.key.y) - self.assertEqual(self.p, key_obj.key.p) - self.assertEqual(self.q, key_obj.key.q) - self.assertEqual(self.g, key_obj.key.g) - - def testExportKey1(self): - tup = (self.y, self.g, self.p, self.q) - key = self.dsa.construct(tup) - encoded = key.exportKey('DER') - self.assertEqual(self.der_public, encoded) - - # 2. - pem_public="""\ ------BEGIN DSA PUBLIC KEY----- -MIIBtzCCASsGByqGSM44BAEwggEeAoGBAOdW7hcX9LZ5THwhRyShl2N0LEVXK0s/ -j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4uBtH -mjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47BgV6/2 -qm66YguDLWDDAhUArTL0jNOuDEWhmKYfpLXiAyB2OyMCgYB539w9YU/mNfzrfq6u -NxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG8CXa -5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0tBxW -rkP9MA2JJi5O/YmUP5mmUbA4iAOBhQACgYEAgzUqaaEy80hD0qDrmVv/Ti8IOnPw -BJ0skeovDOQ9FEq9pIGZ5LADxXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTne -uaKfkZCF8gRjafYnyoSyyx4seUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmA -tPG+TJKpGYb7pVk= ------END DSA PUBLIC KEY-----""" - - def testImportKey2(self): - for pem in (self.pem_public, tostr(self.pem_public)): - key_obj = self.dsa.importKey(pem) - self.failIf(key_obj.has_private()) - self.assertEqual(self.y, key_obj.key.y) - self.assertEqual(self.p, key_obj.key.p) - self.assertEqual(self.q, key_obj.key.q) - self.assertEqual(self.g, key_obj.key.g) - - def testExportKey2(self): - tup = (self.y, self.g, self.p, self.q) - key = self.dsa.construct(tup) - encoded = key.exportKey('PEM') - self.assertEqual(self.pem_public, encoded) - - # 3. OpenSSL/OpenSSH format - der_private=\ - '308201bb02010002818100e756ee1717f4b6794c7c214724a19763742c45572b'+\ - '4b3f8ff3b44f3be9f44ce039a2757695ec915697da74ef914fcd1b05660e2419'+\ - 'c761d639f45d2d79b802dbd23e7ab8b81b479a380e1f30932584ba2a0b955032'+\ - '342ebc83cb5ca906e7b0d7cd6fe656cecb4c8b5a77123a8c6750a481e3b06057'+\ - 'aff6aa6eba620b832d60c3021500ad32f48cd3ae0c45a198a61fa4b5e2032076'+\ - '3b2302818079dfdc3d614fe635fceb7eaeae3718dc2efefb45282993ac6749dc'+\ - '83c223d8c1887296316b3b0b54466cf444f34b82e3554d0b90a778faaf1306f0'+\ - '25dae6a3e36c7f93dd5bac4052b92370040aca70b8d5820599711900efbc9618'+\ - '12c355dd9beffe0981da85c5548074b41c56ae43fd300d89262e4efd89943f99'+\ - 'a651b038880281810083352a69a132f34843d2a0eb995bff4e2f083a73f0049d'+\ - '2c91ea2f0ce43d144abda48199e4b003c570a8af83303d45105f606c5c48d925'+\ - 'a40ed9c2630c2fa4cdbf838539deb9a29f919085f2046369f627ca84b2cb1e2c'+\ - '7940564b670f963ab1164d4e2ca2bf6ffd39f12f548928bf4d2d1b5e6980b4f1'+\ - 'be4c92a91986fba55902145ebd9a3f0b82069d98420986b314215025756065' - - def testImportKey3(self): - key_obj = self.dsa.importKey(self.der_private) - self.failUnless(key_obj.has_private()) - self.assertEqual(self.y, key_obj.key.y) - self.assertEqual(self.p, key_obj.key.p) - self.assertEqual(self.q, key_obj.key.q) - self.assertEqual(self.g, key_obj.key.g) - self.assertEqual(self.x, key_obj.key.x) - - def testExportKey3(self): - tup = (self.y, self.g, self.p, self.q, self.x) - key = self.dsa.construct(tup) - encoded = key.exportKey('DER', pkcs8=False) - self.assertEqual(self.der_private, encoded) - - # 4. - pem_private="""\ ------BEGIN DSA PRIVATE KEY----- -MIIBuwIBAAKBgQDnVu4XF/S2eUx8IUckoZdjdCxFVytLP4/ztE876fRM4DmidXaV -7JFWl9p075FPzRsFZg4kGcdh1jn0XS15uALb0j56uLgbR5o4Dh8wkyWEuioLlVAy -NC68g8tcqQbnsNfNb+ZWzstMi1p3EjqMZ1CkgeOwYFev9qpuumILgy1gwwIVAK0y -9IzTrgxFoZimH6S14gMgdjsjAoGAed/cPWFP5jX8636urjcY3C7++0UoKZOsZ0nc -g8Ij2MGIcpYxazsLVEZs9ETzS4LjVU0LkKd4+q8TBvAl2uaj42x/k91brEBSuSNw -BArKcLjVggWZcRkA77yWGBLDVd2b7/4JgdqFxVSAdLQcVq5D/TANiSYuTv2JlD+Z -plGwOIgCgYEAgzUqaaEy80hD0qDrmVv/Ti8IOnPwBJ0skeovDOQ9FEq9pIGZ5LAD -xXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTneuaKfkZCF8gRjafYnyoSyyx4s -eUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmAtPG+TJKpGYb7pVkCFF69mj8L -ggadmEIJhrMUIVAldWBl ------END DSA PRIVATE KEY-----""" - - def testImportKey4(self): - for pem in (self.pem_private, tostr(self.pem_private)): - key_obj = self.dsa.importKey(pem) - self.failUnless(key_obj.has_private()) - self.assertEqual(self.y, key_obj.key.y) - self.assertEqual(self.p, key_obj.key.p) - self.assertEqual(self.q, key_obj.key.q) - self.assertEqual(self.g, key_obj.key.g) - self.assertEqual(self.x, key_obj.key.x) - - def testExportKey4(self): - tup = (self.y, self.g, self.p, self.q, self.x) - key = self.dsa.construct(tup) - encoded = key.exportKey('PEM', pkcs8=False) - self.assertEqual(self.pem_private, encoded) - - # 5. PKCS8 (unencrypted) - der_pkcs8=\ - '3082014a0201003082012b06072a8648ce3804013082011e02818100e756ee17'+\ - '17f4b6794c7c214724a19763742c45572b4b3f8ff3b44f3be9f44ce039a27576'+\ - '95ec915697da74ef914fcd1b05660e2419c761d639f45d2d79b802dbd23e7ab8'+\ - 'b81b479a380e1f30932584ba2a0b955032342ebc83cb5ca906e7b0d7cd6fe656'+\ - 'cecb4c8b5a77123a8c6750a481e3b06057aff6aa6eba620b832d60c3021500ad'+\ - '32f48cd3ae0c45a198a61fa4b5e20320763b2302818079dfdc3d614fe635fceb'+\ - '7eaeae3718dc2efefb45282993ac6749dc83c223d8c1887296316b3b0b54466c'+\ - 'f444f34b82e3554d0b90a778faaf1306f025dae6a3e36c7f93dd5bac4052b923'+\ - '70040aca70b8d5820599711900efbc961812c355dd9beffe0981da85c5548074'+\ - 'b41c56ae43fd300d89262e4efd89943f99a651b03888041602145ebd9a3f0b82'+\ - '069d98420986b314215025756065' - - def testImportKey5(self): - key_obj = self.dsa.importKey(self.der_pkcs8) - self.failUnless(key_obj.has_private()) - self.assertEqual(self.y, key_obj.key.y) - self.assertEqual(self.p, key_obj.key.p) - self.assertEqual(self.q, key_obj.key.q) - self.assertEqual(self.g, key_obj.key.g) - self.assertEqual(self.x, key_obj.key.x) - - def testExportKey5(self): - tup = (self.y, self.g, self.p, self.q, self.x) - key = self.dsa.construct(tup) - encoded = key.exportKey('DER') - self.assertEqual(self.der_pkcs8, encoded) - encoded = key.exportKey('DER', pkcs8=True) - self.assertEqual(self.der_pkcs8, encoded) - - # 6. - pem_pkcs8="""\ ------BEGIN PRIVATE KEY----- -MIIBSgIBADCCASsGByqGSM44BAEwggEeAoGBAOdW7hcX9LZ5THwhRyShl2N0LEVX -K0s/j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4 -uBtHmjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47Bg -V6/2qm66YguDLWDDAhUArTL0jNOuDEWhmKYfpLXiAyB2OyMCgYB539w9YU/mNfzr -fq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG -8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0 -tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAQWAhRevZo/C4IGnZhCCYazFCFQJXVgZQ== ------END PRIVATE KEY-----""" - - def testImportKey6(self): - for pem in (self.pem_pkcs8, tostr(self.pem_pkcs8)): - key_obj = self.dsa.importKey(pem) - self.failUnless(key_obj.has_private()) - self.assertEqual(self.y, key_obj.key.y) - self.assertEqual(self.p, key_obj.key.p) - self.assertEqual(self.q, key_obj.key.q) - self.assertEqual(self.g, key_obj.key.g) - self.assertEqual(self.x, key_obj.key.x) - - def testExportKey6(self): - tup = (self.y, self.g, self.p, self.q, self.x) - key = self.dsa.construct(tup) - encoded = key.exportKey('PEM') - self.assertEqual(self.pem_pkcs8, encoded) - encoded = key.exportKey('PEM', pkcs8=True) - self.assertEqual(self.pem_pkcs8, encoded) - - # 7. OpenSSH/RFC4253 - ssh_pub="""ssh-dss AAAAB3NzaC1kc3MAAACBAOdW7hcX9LZ5THwhRyShl2N0LEVXK0s/j/O0Tzvp9EzgOaJ1dpXskVaX2nTvkU/NGwVmDiQZx2HWOfRdLXm4AtvSPnq4uBtHmjgOHzCTJYS6KguVUDI0LryDy1ypBuew181v5lbOy0yLWncSOoxnUKSB47BgV6/2qm66YguDLWDDAAAAFQCtMvSM064MRaGYph+kteIDIHY7IwAAAIB539w9YU/mNfzrfq6uNxjcLv77RSgpk6xnSdyDwiPYwYhyljFrOwtURmz0RPNLguNVTQuQp3j6rxMG8CXa5qPjbH+T3VusQFK5I3AECspwuNWCBZlxGQDvvJYYEsNV3Zvv/gmB2oXFVIB0tBxWrkP9MA2JJi5O/YmUP5mmUbA4iAAAAIEAgzUqaaEy80hD0qDrmVv/Ti8IOnPwBJ0skeovDOQ9FEq9pIGZ5LADxXCor4MwPUUQX2BsXEjZJaQO2cJjDC+kzb+DhTneuaKfkZCF8gRjafYnyoSyyx4seUBWS2cPljqxFk1OLKK/b/058S9UiSi/TS0bXmmAtPG+TJKpGYb7pVk=""" - - def testImportKey7(self): - for ssh in (self.ssh_pub, tostr(self.ssh_pub)): - key_obj = self.dsa.importKey(ssh) - self.failIf(key_obj.has_private()) - self.assertEqual(self.y, key_obj.key.y) - self.assertEqual(self.p, key_obj.key.p) - self.assertEqual(self.q, key_obj.key.q) - self.assertEqual(self.g, key_obj.key.g) - - def testExportKey7(self): - tup = (self.y, self.g, self.p, self.q) - key = self.dsa.construct(tup) - encoded = key.exportKey('OpenSSH') - self.assertEqual(self.ssh_pub, encoded) - - # 8. Encrypted OpenSSL/OpenSSH - pem_private_encrypted="""\ ------BEGIN DSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: AES-128-CBC,70B6908939D65E9F2EB999E8729788CE - -4V6GHRDpCrdZ8MBjbyp5AlGUrjvr2Pn2e2zVxy5RBt4FBj9/pa0ae0nnyUPMLSUU -kKyOR0topRYTVRLElm4qVrb5uNZ3hRwfbklr+pSrB7O9eHz9V5sfOQxyODS07JxK -k1OdOs70/ouMXLF9EWfAZOmWUccZKHNblUwg1p1UrZIz5jXw4dUE/zqhvXh6d+iC -ADsICaBCjCrRQJKDp50h3+ndQjkYBKVH+pj8TiQ79U7lAvdp3+iMghQN6YXs9mdI -gFpWw/f97oWM4GHZFqHJ+VSMNFjBiFhAvYV587d7Lk4dhD8sCfbxj42PnfRgUItc -nnPqHxmhMQozBWzYM4mQuo3XbF2WlsNFbOzFVyGhw1Bx1s91qvXBVWJh2ozrW0s6 -HYDV7ZkcTml/4kjA/d+mve6LZ8kuuR1qCiZx6rkffhh1gDN/1Xz3HVvIy/dQ+h9s -5zp7PwUoWbhqp3WCOr156P6gR8qo7OlT6wMh33FSXK/mxikHK136fV2shwTKQVII -rJBvXpj8nACUmi7scKuTWGeUoXa+dwTZVVe+b+L2U1ZM7+h/neTJiXn7u99PFUwu -xVJtxaV37m3aXxtCsPnbBg== ------END DSA PRIVATE KEY-----""" - - def testImportKey8(self): - for pem in (self.pem_private_encrypted, tostr(self.pem_private_encrypted)): - key_obj = self.dsa.importKey(pem, "PWDTEST") - self.failUnless(key_obj.has_private()) - self.assertEqual(self.y, key_obj.key.y) - self.assertEqual(self.p, key_obj.key.p) - self.assertEqual(self.q, key_obj.key.q) - self.assertEqual(self.g, key_obj.key.g) - self.assertEqual(self.x, key_obj.key.x) - - def testExportKey8(self): - tup = (self.y, self.g, self.p, self.q, self.x) - key = self.dsa.construct(tup) - encoded = key.exportKey('PEM', pkcs8=False, passphrase="PWDTEST") - key = self.dsa.importKey(encoded, "PWDTEST") - self.assertEqual(self.y, key.key.y) - self.assertEqual(self.p, key.key.p) - self.assertEqual(self.q, key.key.q) - self.assertEqual(self.g, key.key.g) - self.assertEqual(self.x, key.key.x) - - # 9. Encrypted PKCS8 - # pbeWithMD5AndDES-CBC - pem_pkcs8_encrypted="""\ ------BEGIN ENCRYPTED PRIVATE KEY----- -MIIBcTAbBgkqhkiG9w0BBQMwDgQI0GC3BJ/jSw8CAggABIIBUHc1cXZpExIE9tC7 -7ryiW+5ihtF2Ekurq3e408GYSAu5smJjN2bvQXmzRFBz8W38K8eMf1sbWroZ4+zn -kZSbb9nSm5kAa8lR2+oF2k+WRswMR/PTC3f/D9STO2X0QxdrzKgIHEcSGSHp5jTx -aVvbkCDHo9vhBTl6S3ogZ48As/MEro76+9igUwJ1jNhIQZPJ7e20QH5qDpQFFJN4 -CKl2ENSEuwGiqBszItFy4dqH0g63ZGZV/xt9wSO9Rd7SK/EbA/dklOxBa5Y/VItM -gnIhs9XDMoGYyn6F023EicNJm6g/bVQk81BTTma4tm+12TKGdYm+QkeZvCOMZylr -Wv67cKwO3cAXt5C3QXMDgYR64XvuaT5h7C0igMp2afSXJlnbHEbFxQVJlv83T4FM -eZ4k+NQDbEL8GiHmFxzDWQAuPPZKJWEEEV2p/To+WOh+kSDHQw== ------END ENCRYPTED PRIVATE KEY-----""" - - def testImportKey9(self): - for pem in (self.pem_pkcs8_encrypted, tostr(self.pem_pkcs8_encrypted)): - key_obj = self.dsa.importKey(pem, "PWDTEST") - self.failUnless(key_obj.has_private()) - self.assertEqual(self.y, key_obj.key.y) - self.assertEqual(self.p, key_obj.key.p) - self.assertEqual(self.q, key_obj.key.q) - self.assertEqual(self.g, key_obj.key.g) - self.assertEqual(self.x, key_obj.key.x) - - # 10. Encrypted PKCS8 - # pkcs5PBES2 / - # pkcs5PBKDF2 (rounds=1000, salt=D725BF1B6B8239F4) / - # des-EDE3-CBC (iv=27A1C66C42AFEECE) - # - der_pkcs8_encrypted=\ - '30820196304006092a864886f70d01050d3033301b06092a864886f70d01050c'+\ - '300e0408d725bf1b6b8239f4020203e8301406082a864886f70d0307040827a1'+\ - 'c66c42afeece048201505cacfde7bf8edabb3e0d387950dc872662ea7e9b1ed4'+\ - '400d2e7e6186284b64668d8d0328c33a9d9397e6f03df7cb68268b0a06b4e22f'+\ - '7d132821449ecf998a8b696dbc6dd2b19e66d7eb2edfeb4153c1771d49702395'+\ - '4f36072868b5fcccf93413a5ac4b2eb47d4b3f681c6bd67ae363ed776f45ae47'+\ - '174a00098a7c930a50f820b227ddf50f9742d8e950d02586ff2dac0e3c372248'+\ - 'e5f9b6a7a02f4004f20c87913e0f7b52bccc209b95d478256a890b31d4c9adec'+\ - '21a4d157a179a93a3dad06f94f3ce486b46dfa7fc15fd852dd7680bbb2f17478'+\ - '7e71bd8dbaf81eca7518d76c1d26256e95424864ba45ca5d47d7c5a421be02fa'+\ - 'b94ab01e18593f66cf9094eb5c94b9ecf3aa08b854a195cf87612fbe5e96c426'+\ - '2b0d573e52dc71ba3f5e468c601e816c49b7d32c698b22175e89aaef0c443770'+\ - '5ef2f88a116d99d8e2869a4fd09a771b84b49e4ccb79aadcb1c9' - - def testImportKey10(self): - key_obj = self.dsa.importKey(self.der_pkcs8_encrypted, "PWDTEST") - self.failUnless(key_obj.has_private()) - self.assertEqual(self.y, key_obj.key.y) - self.assertEqual(self.p, key_obj.key.p) - self.assertEqual(self.q, key_obj.key.q) - self.assertEqual(self.g, key_obj.key.g) - self.assertEqual(self.x, key_obj.key.x) - - def testExportKey10(self): - tup = (self.y, self.g, self.p, self.q, self.x) - key = self.dsa.construct(tup) - randfunc = BytesIO(unhexlify(b("27A1C66C42AFEECE") + b("D725BF1B6B8239F4"))).read - key._randfunc = randfunc - encoded = key.exportKey('DER', pkcs8=True, passphrase="PWDTEST") - self.assertEqual(self.der_pkcs8_encrypted, encoded) - - # ---- - - def testImportError1(self): - self.assertRaises(ValueError, self.dsa.importKey, self.der_pkcs8_encrypted, "wrongpwd") - - def testExportError2(self): - tup = (self.y, self.g, self.p, self.q, self.x) - key = self.dsa.construct(tup) - self.assertRaises(ValueError, key.exportKey, 'DER', pkcs8=False, passphrase="PWDTEST") - -class ImportKeyTestsSlow(ImportKeyTests): - def setUp(self): - ImportKeyTests.setUp(self) - self.dsa = DSA.DSAImplementation(use_fast_math=0) - -class ImportKeyTestsFast(ImportKeyTests): - def setUp(self): - ImportKeyTests.setUp(self) - self.dsa = DSA.DSAImplementation(use_fast_math=1) - -if __name__ == '__main__': - unittest.main() - -def get_tests(config={}): - tests = [] - try: - from Crypto.PublicKey import _fastmath - tests += list_test_cases(ImportKeyTestsFast) - except ImportError: - pass - tests += list_test_cases(ImportKeyTestsSlow) - return tests - -if __name__ == '__main__': - suite = lambda: unittest.TestSuite(get_tests()) - unittest.main(defaultTest='suite') - diff --git a/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py b/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py index c5638e66..c4e6ccf2 100644 --- a/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py +++ b/lib/Crypto/SelfTest/Random/Fortuna/test_FortunaAccumulator.py @@ -30,7 +30,6 @@ if sys.version_info[0] == 2 and sys.version_info[1] == 1: from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * -from Crypto.SelfTest.st_common import assert_disabled import unittest from binascii import b2a_hex @@ -68,9 +67,8 @@ def test_FortunaPool(self): def test_which_pools(self): """FortunaAccumulator.which_pools""" - # which_pools(0) should trigger an assertion failure (unless using -O or -OO) - if not assert_disabled(): - self.assertRaises(AssertionError, FortunaAccumulator.which_pools, 0) + # which_pools(0) should fail + self.assertRaises(AssertionError, FortunaAccumulator.which_pools, 0) self.assertEqual(FortunaAccumulator.which_pools(1), [0]) self.assertEqual(FortunaAccumulator.which_pools(2), [0, 1]) diff --git a/lib/Crypto/SelfTest/Random/test_random.py b/lib/Crypto/SelfTest/Random/test_random.py index 3e85c3c2..f9ffc663 100644 --- a/lib/Crypto/SelfTest/Random/test_random.py +++ b/lib/Crypto/SelfTest/Random/test_random.py @@ -133,7 +133,7 @@ def runTest(self): self.assertEqual(b('1') in z, True) self.assertRaises(TypeError, random.shuffle, b('12')) self.assertRaises(TypeError, random.shuffle, 1) - self.assertRaises(TypeError, random.shuffle, "11") + self.assertRaises(TypeError, random.shuffle, "1") self.assertRaises(TypeError, random.shuffle, (1,2)) # 2to3 wraps a list() around it, alas - but I want to shoot # myself in the foot here! :D diff --git a/lib/Crypto/SelfTest/Signature/test_pkcs1_15.py b/lib/Crypto/SelfTest/Signature/test_pkcs1_15.py index c2d60f87..bc366962 100644 --- a/lib/Crypto/SelfTest/Signature/test_pkcs1_15.py +++ b/lib/Crypto/SelfTest/Signature/test_pkcs1_15.py @@ -26,8 +26,7 @@ from Crypto.PublicKey import RSA from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex -from Crypto.Hash import MD2, SHA1, MD5, SHA224, SHA256, SHA384, SHA512,\ - RIPEMD160 +from Crypto.Hash import * from Crypto import Random from Crypto.Signature import PKCS1_v1_5 as PKCS from Crypto.Util.py3compat import * @@ -124,7 +123,7 @@ class PKCS1_15_Tests(unittest.TestCase): '''4a700a16432a291a3194646952687d5316458b8b86fb0a25aa30e0dcecdb 442676759ac63d56ec1499c3ae4c0013c2053cabd5b5804848994541ac16 fa243a4d''', - SHA1 + SHA ), # @@ -147,7 +146,7 @@ class PKCS1_15_Tests(unittest.TestCase): A9D20970C54E6651070B0144D43844C899320DD8FA7819F7EBC6A7715287332E C8675C136183B3F8A1F81EF969418267130A756FDBB2C71D9A667446E34E0EAD 9CF31BFB66F816F319D0B7E430A5F2891553986E003720261C7E9022C0D9F11F''', - SHA1 + SHA ) ) @@ -165,7 +164,7 @@ def testSign1(self): # Data to sign can either be in hex form or not try: h.update(t2b(row[1])) - except ValueError: + except: h.update(b(row[1])) # The real test signer = PKCS.new(key) @@ -186,7 +185,7 @@ def testVerify1(self): # Data to sign can either be in hex form or not try: h.update(t2b(row[1])) - except ValueError: + except: h.update(b(row[1])) # The real test verifier = PKCS.new(key) @@ -198,7 +197,7 @@ def testSignVerify(self): rng = Random.new().read key = RSA.generate(1024, rng) - for hashmod in (MD2,MD5,SHA1,SHA224,SHA256,SHA384,SHA512,RIPEMD160): + for hashmod in (MD2,MD5,SHA,SHA224,SHA256,SHA384,SHA512,RIPEMD): h = hashmod.new() h.update(b('blah blah blah')) @@ -207,37 +206,10 @@ def testSignVerify(self): result = signer.verify(h, s) self.failUnless(result) -class PKCS1_15_NoParams(unittest.TestCase): - """Verify that PKCS#1 v1.5 signatures pass even without NULL parameters in - the algorithm identifier (bug #1119552).""" - - rsakey = """-----BEGIN RSA PRIVATE KEY----- - MIIBOwIBAAJBAL8eJ5AKoIsjURpcEoGubZMxLD7+kT+TLr7UkvEtFrRhDDKMtuII - q19FrL4pUIMymPMSLBn3hJLe30Dw48GQM4UCAwEAAQJACUSDEp8RTe32ftq8IwG8 - Wojl5mAd1wFiIOrZ/Uv8b963WJOJiuQcVN29vxU5+My9GPZ7RA3hrDBEAoHUDPrI - OQIhAPIPLz4dphiD9imAkivY31Rc5AfHJiQRA7XixTcjEkojAiEAyh/pJHks/Mlr - +rdPNEpotBjfV4M4BkgGAA/ipcmaAjcCIQCHvhwwKVBLzzTscT2HeUdEeBMoiXXK - JACAr3sJQJGxIQIgarRp+m1WSKV1MciwMaTOnbU7wxFs9DP1pva76lYBzgUCIQC9 - n0CnZCJ6IZYqSt0H5N7+Q+2Ro64nuwV/OSQfM6sBwQ== - -----END RSA PRIVATE KEY-----""" - - msg = b("This is a test\x0a") - - # PKCS1 v1.5 signature of the message computed using SHA-1. - # The digestAlgorithm SEQUENCE does NOT contain the NULL parameter. - signature = '''a287a13517f716e72fb14eea8e33a8db4a4643314607e7ca3e3e281893db7401 - 3dda8b855fd99f6fecedcb25fcb7a434f35cd0a101f8b19348e0bd7b6f152dfc''' - - def testVerify(self): - verifier = PKCS.new(RSA.importKey(self.rsakey)) - h = SHA1.new(self.msg) - result = verifier.verify(h, t2b(self.signature)) - self.failUnless(result) def get_tests(config={}): tests = [] tests += list_test_cases(PKCS1_15_Tests) - tests += list_test_cases(PKCS1_15_NoParams) return tests if __name__ == '__main__': diff --git a/lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py b/lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py index e37e7a17..f5256a51 100644 --- a/lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py +++ b/lib/Crypto/SelfTest/Signature/test_pkcs1_pss.py @@ -29,8 +29,7 @@ from Crypto.PublicKey import RSA from Crypto import Random from Crypto.SelfTest.st_common import list_test_cases, a2b_hex, b2a_hex -from Crypto.Hash import SHA1, MD2, RIPEMD160, SHA224, SHA384, SHA512,\ - SHA256, MD5 +from Crypto.Hash import * from Crypto.Signature import PKCS1_PSS as PKCS from Crypto.Util.py3compat import * @@ -137,7 +136,7 @@ class PKCS1_PSS_Tests(unittest.TestCase): '''e3 b5 d5 d0 02 c1 bc e5 0c 2b 65 ef 88 a1 88 d8 3b ce 7e 61''', # Hash algorithm - SHA1 + SHA ), # @@ -193,7 +192,7 @@ class PKCS1_PSS_Tests(unittest.TestCase): '''de e9 59 c7 e0 64 11 36 14 20 ff 80 18 5e d5 7f 3e 67 76 af''', # Hash - SHA1 + SHA ), # @@ -239,7 +238,7 @@ class PKCS1_PSS_Tests(unittest.TestCase): '''ef 28 69 fa 40 c3 46 cb 18 3d ab 3d 7b ff c9 8f d5 6d f4 2d''', # Hash - SHA1 + SHA ), # @@ -286,7 +285,7 @@ class PKCS1_PSS_Tests(unittest.TestCase): # Salt '''57 bf 16 0b cb 02 bb 1d c7 28 0c f0 45 85 30 b7 d2 83 2f f7''', - SHA1 + SHA ), # @@ -340,7 +339,7 @@ class PKCS1_PSS_Tests(unittest.TestCase): # Salt '''1d 65 49 1d 79 c8 64 b3 73 00 9b e6 f6 f2 46 7b ac 4c 78 fa''', - SHA1 + SHA ) ) @@ -381,12 +380,12 @@ def testVerify1(self): self.failUnless(result) def testSignVerify(self): - h = SHA1.new() + h = SHA.new() h.update(b('blah blah blah')) rng = Random.new().read key = MyKey(RSA.generate(1024,rng)) - + # Helper function to monitor what's request from MGF global mgfcalls def newMGF(seed,maskLen): @@ -395,7 +394,7 @@ def newMGF(seed,maskLen): return bchr(0x00)*maskLen # Verify that PSS is friendly to all ciphers - for hashmod in (MD2,MD5,SHA1,SHA224,SHA256,SHA384,RIPEMD160): + for hashmod in (MD2,MD5,SHA,SHA224,SHA256,SHA384,RIPEMD): h = hashmod.new() h.update(b('blah blah blah')) @@ -407,7 +406,7 @@ def newMGF(seed,maskLen): self.failUnless(signer.verify(h, s)) self.assertEqual(key.asked, h.digest_size) - h = SHA1.new() + h = SHA.new() h.update(b('blah blah blah')) # Verify that sign() uses a different salt length diff --git a/lib/Crypto/SelfTest/Util/__init__.py b/lib/Crypto/SelfTest/Util/__init__.py index f404d0ba..abd640ad 100644 --- a/lib/Crypto/SelfTest/Util/__init__.py +++ b/lib/Crypto/SelfTest/Util/__init__.py @@ -34,7 +34,6 @@ def get_tests(config={}): from Crypto.SelfTest.Util import test_winrandom; tests += test_winrandom.get_tests(config=config) from Crypto.SelfTest.Util import test_number; tests += test_number.get_tests(config=config) from Crypto.SelfTest.Util import test_Counter; tests += test_Counter.get_tests(config=config) - from Crypto.SelfTest.Util import test_Padding; tests += test_Padding.get_tests(config=config) return tests if __name__ == '__main__': diff --git a/lib/Crypto/SelfTest/Util/test_Counter.py b/lib/Crypto/SelfTest/Util/test_Counter.py index 7dbfc975..33c9bd7d 100644 --- a/lib/Crypto/SelfTest/Util/test_Counter.py +++ b/lib/Crypto/SelfTest/Util/test_Counter.py @@ -39,24 +39,34 @@ def setUp(self): from Crypto.Util import Counter def test_BE_shortcut(self): - """Big endian""" + """Big endian, shortcut enabled""" c = Counter.new(128) + self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_ c = Counter.new(128, little_endian=False) + self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_ + c = Counter.new(128, disable_shortcut=False) + self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_ + c = Counter.new(128, little_endian=False, disable_shortcut=False) + self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_ def test_LE_shortcut(self): - """Little endian""" + """Little endian, shortcut enabled""" c = Counter.new(128, little_endian=True) + self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_ + c = Counter.new(128, little_endian=True, disable_shortcut=False) + self.assertEqual(c.__PCT_CTR_SHORTCUT__,True) # assert_ def test_BE_no_shortcut(self): - """Big endian, with disable_shortcut""" - # Just testing API backward-compatibility. disable_shortcut is now a no-op. + """Big endian, shortcut disabled""" c = Counter.new(128, disable_shortcut=True) + self.assertRaises(AttributeError, getattr, c, '__PCT_CTR_SHORTCUT__') c = Counter.new(128, little_endian=False, disable_shortcut=True) + self.assertRaises(AttributeError, getattr, c, '__PCT_CTR_SHORTCUT__') def test_LE_no_shortcut(self): """Little endian, shortcut disabled""" - # Just testing API backward-compatibility. disable_shortcut is now a no-op. c = Counter.new(128, little_endian=True, disable_shortcut=True) + self.assertRaises(AttributeError, getattr, c, '__PCT_CTR_SHORTCUT__') def test_BE_defaults(self): """128-bit, Big endian, defaults""" diff --git a/lib/Crypto/SelfTest/Util/test_Padding.py b/lib/Crypto/SelfTest/Util/test_Padding.py deleted file mode 100644 index b8a01abb..00000000 --- a/lib/Crypto/SelfTest/Util/test_Padding.py +++ /dev/null @@ -1,140 +0,0 @@ -# -*- coding: utf-8 -*- -# -# SelfTest/Util/test_Padding.py: Self-test for padding functions -# -# =================================================================== -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# =================================================================== - -import unittest -from binascii import unhexlify as uh - -from Crypto.Util.py3compat import * -from Crypto.SelfTest.st_common import list_test_cases -from Crypto.Util.Padding import pad, unpad - -class PKCS7_Tests(unittest.TestCase): - - def test1(self): - padded = pad(b(""), 4) - self.failUnless(padded == uh(b("04040404"))) - padded = pad(b(""), 4, 'pkcs7') - self.failUnless(padded == uh(b("04040404"))) - back = unpad(padded, 4) - self.failUnless(back == b("")) - - def test2(self): - padded = pad(uh(b("12345678")), 4) - self.failUnless(padded == uh(b("1234567804040404"))) - back = unpad(padded, 4) - self.failUnless(back == uh(b("12345678"))) - - def test3(self): - padded = pad(uh(b("123456")), 4) - self.failUnless(padded == uh(b("12345601"))) - back = unpad(padded, 4) - self.failUnless(back == uh(b("123456"))) - - def test4(self): - padded = pad(uh(b("1234567890")), 4) - self.failUnless(padded == uh(b("1234567890030303"))) - back = unpad(padded, 4) - self.failUnless(back == uh(b("1234567890"))) - - def testn1(self): - self.assertRaises(ValueError, pad, uh(b("12")), 4, 'pkcs8') - - def testn2(self): - self.assertRaises(ValueError, unpad, b("\0\0\0"), 4) - - def testn3(self): - self.assertRaises(ValueError, unpad, b("123456\x02"), 4) - self.assertRaises(ValueError, unpad, b("123456\x00"), 4) - self.assertRaises(ValueError, unpad, b("123456\x05\x05\x05\x05\x05"), 4) - -class X923_Tests(unittest.TestCase): - - def test1(self): - padded = pad(b(""), 4, 'x923') - self.failUnless(padded == uh(b("00000004"))) - back = unpad(padded, 4, 'x923') - self.failUnless(back == b("")) - - def test2(self): - padded = pad(uh(b("12345678")), 4, 'x923') - self.failUnless(padded == uh(b("1234567800000004"))) - back = unpad(padded, 4, 'x923') - self.failUnless(back == uh(b("12345678"))) - - def test3(self): - padded = pad(uh(b("123456")), 4, 'x923') - self.failUnless(padded == uh(b("12345601"))) - back = unpad(padded, 4, 'x923') - self.failUnless(back == uh(b("123456"))) - - def test4(self): - padded = pad(uh(b("1234567890")), 4, 'x923') - self.failUnless(padded == uh(b("1234567890000003"))) - back = unpad(padded, 4, 'x923') - self.failUnless(back == uh(b("1234567890"))) - - def testn1(self): - self.assertRaises(ValueError, unpad, b("123456\x02"), 4, 'x923') - self.assertRaises(ValueError, unpad, b("123456\x00"), 4, 'x923') - self.assertRaises(ValueError, unpad, b("123456\x00\x00\x00\x00\x05"), 4, 'x923') - -class ISO7816_Tests(unittest.TestCase): - - def test1(self): - padded = pad(b(""), 4, 'iso7816') - self.failUnless(padded == uh(b("80000000"))) - back = unpad(padded, 4, 'iso7816') - self.failUnless(back == b("")) - - def test2(self): - padded = pad(uh(b("12345678")), 4, 'iso7816') - self.failUnless(padded == uh(b("1234567880000000"))) - back = unpad(padded, 4, 'iso7816') - self.failUnless(back == uh(b("12345678"))) - - def test3(self): - padded = pad(uh(b("123456")), 4, 'iso7816') - self.failUnless(padded == uh(b("12345680"))) - #import pdb; pdb.set_trace() - back = unpad(padded, 4, 'iso7816') - self.failUnless(back == uh(b("123456"))) - - def test4(self): - padded = pad(uh(b("1234567890")), 4, 'iso7816') - self.failUnless(padded == uh(b("1234567890800000"))) - back = unpad(padded, 4, 'iso7816') - self.failUnless(back == uh(b("1234567890"))) - - def testn1(self): - self.assertRaises(ValueError, unpad, b("123456\x81"), 4, 'iso7816') - -def get_tests(config={}): - tests = [] - tests += list_test_cases(PKCS7_Tests) - tests += list_test_cases(X923_Tests) - tests += list_test_cases(ISO7816_Tests) - return tests - -if __name__ == '__main__': - suite = lambda: unittest.TestSuite(get_tests()) - unittest.main(defaultTest='suite') - diff --git a/lib/Crypto/SelfTest/Util/test_asn1.py b/lib/Crypto/SelfTest/Util/test_asn1.py index e40a46fb..578dabef 100644 --- a/lib/Crypto/SelfTest/Util/test_asn1.py +++ b/lib/Crypto/SelfTest/Util/test_asn1.py @@ -28,626 +28,262 @@ import sys from Crypto.Util.py3compat import * -from Crypto.Util.asn1 import DerObject, DerSetOf, newDerSetOf, DerInteger,\ - DerBitString, newDerBitString, newDerObjectId,\ - DerObjectId, DerNull, DerOctetString,\ - newDerOctetString, DerSequence, newDerSequence,\ - newDerInteger -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * +from Crypto.Util.asn1 import DerSequence, DerObject class DerObjectTests(unittest.TestCase): - def testObjInit1(self): - # Fail with invalid tag format (must be 1 byte) - self.assertRaises(ValueError, DerObject, b('\x00\x99')) - # Fail with invalid implicit tag (must be <0x1F) - self.assertRaises(ValueError, DerObject, 0x1F) - - # ------ - - def testObjEncode1(self): - # No payload - der = DerObject(b('\x02')) - self.assertEquals(der.encode(), b('\x02\x00')) - # Small payload (primitive) - der.payload = b('\x45') - self.assertEquals(der.encode(), b('\x02\x01\x45')) - # Invariant - self.assertEquals(der.encode(), b('\x02\x01\x45')) - # Initialize with numerical tag - der = DerObject(0x04) - der.payload = b('\x45') - self.assertEquals(der.encode(), b('\x04\x01\x45')) - # Initialize with constructed type - der = DerObject(b('\x10'), constructed=True) - self.assertEquals(der.encode(), b('\x30\x00')) - - def testObjEncode2(self): - # Initialize with payload - der = DerObject(0x03, b('\x12\x12')) - self.assertEquals(der.encode(), b('\x03\x02\x12\x12')) - - def testObjEncode3(self): - # Long payload - der = DerObject(b('\x10')) - der.payload = b("0")*128 - self.assertEquals(der.encode(), b('\x10\x81\x80' + "0"*128)) - - def testObjEncode4(self): - # Implicit tags (constructed) - der = DerObject(0x10, implicit=1, constructed=True) - der.payload = b('ppll') - self.assertEquals(der.encode(), b('\xa1\x04ppll')) - # Implicit tags (primitive) - der = DerObject(0x02, implicit=0x1E, constructed=False) - der.payload = b('ppll') - self.assertEquals(der.encode(), b('\x9E\x04ppll')) - - # ----- - - def testObjDecode1(self): - # Decode short payload - der = DerObject(0x02) - der.decode(b('\x02\x02\x01\x02')) - self.assertEquals(der.payload, b("\x01\x02")) - self.assertEquals(der._idOctet, 0x02) - - def testObjDecode2(self): - # Decode long payload - der = DerObject(0x02) - der.decode(b('\x02\x81\x80' + "1"*128)) - self.assertEquals(der.payload, b("1")*128) - self.assertEquals(der._idOctet, 0x02) - - def testObjDecode3(self): - # Decode payload with too much data gives error - der = DerObject(0x02) - self.assertRaises(ValueError, der.decode, b('\x02\x02\x01\x02\xFF')) - # Decode payload with too little data gives error - der = DerObject(0x02) - self.assertRaises(EOFError, der.decode, b('\x02\x02\x01')) - - def testObjDecode4(self): - # Decode implicit tag (primitive) - der = DerObject(0x02, constructed=False, implicit=0xF) - self.assertRaises(ValueError, der.decode, b('\x02\x02\x01\x02')) - der.decode(b('\x8F\x01\x00')) - self.assertEquals(der.payload, b('\x00')) - # Decode implicit tag (constructed) - der = DerObject(0x02, constructed=True, implicit=0xF) - self.assertRaises(ValueError, der.decode, b('\x02\x02\x01\x02')) - der.decode(b('\xAF\x01\x00')) - self.assertEquals(der.payload, b('\x00')) - - def testObjDecode5(self): - # Decode payload with unexpected tag gives error - der = DerObject(0x02) - self.assertRaises(ValueError, der.decode, b('\x03\x02\x01\x02')) - - def testObjDecode6(self): - # Arbitrary DER object - der = DerObject() - der.decode(b('\x65\x01\x88')) - self.assertEquals(der._idOctet, 0x65) - self.assertEquals(der.payload, b('\x88')) - -class DerIntegerTests(unittest.TestCase): - - def testInit1(self): - der = newDerInteger(1) - self.assertEquals(der.encode(), b('\x02\x01\x01')) - - def testEncode1(self): - # Single-byte integers - # Value 0 - der = DerInteger(0) - self.assertEquals(der.encode(), b('\x02\x01\x00')) - # Value 1 - der = DerInteger(1) - self.assertEquals(der.encode(), b('\x02\x01\x01')) - # Value 127 - der = DerInteger(127) - self.assertEquals(der.encode(), b('\x02\x01\x7F')) - - def testEncode2(self): - # Multi-byte integers - # Value 128 - der = DerInteger(128) - self.assertEquals(der.encode(), b('\x02\x02\x00\x80')) - # Value 0x180 - der = DerInteger(0x180L) - self.assertEquals(der.encode(), b('\x02\x02\x01\x80')) - # One very long integer - der = DerInteger(2L**2048) - self.assertEquals(der.encode(), - b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00')) - - def testEncode3(self): - # Negative integers - # Value -1 - der = DerInteger(-1) - self.assertEquals(der.encode(), b('\x02\x01\xFF')) - # Value -128 - der = DerInteger(-128) - self.assertEquals(der.encode(), b('\x02\x01\x80')) - # Value - der = DerInteger(-87873) - self.assertEquals(der.encode(), b('\x02\x03\xFE\xA8\xBF')) - - # ----- - - def testDecode1(self): - # Single-byte integer - der = DerInteger() - # Value 0 - der.decode(b('\x02\x01\x00')) - self.assertEquals(der.value, 0) - # Value 1 - der.decode(b('\x02\x01\x01')) - self.assertEquals(der.value, 1) - # Value 127 - der.decode(b('\x02\x01\x7F')) - self.assertEquals(der.value, 127) - - def testDecode2(self): - # Multi-byte integer - der = DerInteger() - # Value 0x180L - der.decode(b('\x02\x02\x01\x80')) - self.assertEquals(der.value,0x180L) - # One very long integer - der.decode( - b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00')) - self.assertEquals(der.value,2L**2048) - - def testDecode3(self): - # Negative integer - der = DerInteger() - # Value -1 - der.decode(b('\x02\x01\xFF')) - self.assertEquals(der.value, -1) - # Value -32768 - der.decode(b('\x02\x02\x80\x00')) - self.assertEquals(der.value, -32768) - - def testDecode5(self): - # We still accept BER integer format - der = DerInteger() - # Redundant leading zeroes - der.decode(b('\x02\x02\x00\x01')) - self.assertEquals(der.value, 1) - # Redundant leading 0xFF - der.decode(b('\x02\x02\xFF\xFF')) - self.assertEquals(der.value, -1) - # Empty payload - der.decode(b('\x02\x00')) - self.assertEquals(der.value, 0) - - def testErrDecode1(self): - # Wide length field - der = DerInteger() - self.assertRaises(ValueError, der.decode, b('\x02\x81\x01\x01')) + def testObjEncode1(self): + # No payload + der = DerObject(b('\x33')) + self.assertEquals(der.encode(), b('\x33\x00')) + # Small payload + der.payload = b('\x45') + self.assertEquals(der.encode(), b('\x33\x01\x45')) + # Invariant + self.assertEquals(der.encode(), b('\x33\x01\x45')) + # Initialize with numerical tag + der = DerObject(b(0x33)) + der.payload = b('\x45') + self.assertEquals(der.encode(), b('\x33\x01\x45')) + + def testObjEncode2(self): + # Known types + der = DerObject('SEQUENCE') + self.assertEquals(der.encode(), b('\x30\x00')) + der = DerObject('BIT STRING') + self.assertEquals(der.encode(), b('\x03\x00')) + + def testObjEncode3(self): + # Long payload + der = DerObject(b('\x34')) + der.payload = b("0")*128 + self.assertEquals(der.encode(), b('\x34\x81\x80' + "0"*128)) + + def testObjDecode1(self): + # Decode short payload + der = DerObject() + der.decode(b('\x20\x02\x01\x02')) + self.assertEquals(der.payload, b("\x01\x02")) + self.assertEquals(der.typeTag, 0x20) + + def testObjDecode2(self): + # Decode short payload + der = DerObject() + der.decode(b('\x22\x81\x80' + "1"*128)) + self.assertEquals(der.payload, b("1")*128) + self.assertEquals(der.typeTag, 0x22) class DerSequenceTests(unittest.TestCase): - def testInit1(self): - der = newDerSequence(1, DerInteger(2), '0\x00') - self.assertEquals(der.encode(), b('0\x08\x02\x01\x01\x02\x01\x020\x00')) - - def testEncode1(self): - # Empty sequence - der = DerSequence() - self.assertEquals(der.encode(), b('0\x00')) - self.failIf(der.hasOnlyInts()) - # One single-byte integer (zero) - der.append(0) - self.assertEquals(der.encode(), b('0\x03\x02\x01\x00')) - self.assertEquals(der.hasInts(),1) - self.assertEquals(der.hasInts(False),1) - self.failUnless(der.hasOnlyInts()) - self.failUnless(der.hasOnlyInts(False)) - # Invariant - self.assertEquals(der.encode(), b('0\x03\x02\x01\x00')) - - def testEncode2(self): - # Indexing - der = DerSequence() - der.append(0) - der[0] = 1 - self.assertEquals(len(der),1) - self.assertEquals(der[0],1) - self.assertEquals(der[-1],1) - self.assertEquals(der.encode(), b('0\x03\x02\x01\x01')) - # - der[:] = [1] - self.assertEquals(len(der),1) - self.assertEquals(der[0],1) - self.assertEquals(der.encode(), b('0\x03\x02\x01\x01')) - - def testEncode3(self): - # One multi-byte integer (non-zero) - der = DerSequence() - der.append(0x180L) - self.assertEquals(der.encode(), b('0\x04\x02\x02\x01\x80')) - - def testEncode4(self): - # One very long integer - der = DerSequence() - der.append(2L**2048) - self.assertEquals(der.encode(), b('0\x82\x01\x05')+ - b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00')) - - def testEncode5(self): - der = DerSequence() - der += 1 - der += b('\x30\x00') - self.assertEquals(der.encode(), b('\x30\x05\x02\x01\x01\x30\x00')) - - def testEncode6(self): - # Two positive integers - der = DerSequence() - der.append(0x180L) - der.append(0xFFL) - self.assertEquals(der.encode(), b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff')) - self.failUnless(der.hasOnlyInts()) - self.failUnless(der.hasOnlyInts(False)) - # Two mixed integers - der = DerSequence() - der.append(2) - der.append(-2) - self.assertEquals(der.encode(), b('0\x06\x02\x01\x02\x02\x01\xFE')) - self.assertEquals(der.hasInts(), 1) - self.assertEquals(der.hasInts(False), 2) - self.failIf(der.hasOnlyInts()) - self.failUnless(der.hasOnlyInts(False)) - # - der.append(0x01) - der[1:] = [9,8] - self.assertEquals(len(der),3) - self.assertEqual(der[1:],[9,8]) - self.assertEqual(der[1:-1],[9]) - self.assertEquals(der.encode(), b('0\x09\x02\x01\x02\x02\x01\x09\x02\x01\x08')) - - def testEncode7(self): - # One integer and another type (no matter what it is) - der = DerSequence() - der.append(0x180L) - der.append(b('\x00\x02\x00\x00')) - self.assertEquals(der.encode(), b('0\x08\x02\x02\x01\x80\x00\x02\x00\x00')) - self.failIf(der.hasOnlyInts()) - - #### - - def testDecode1(self): - # Empty sequence - der = DerSequence() - der.decode(b('0\x00')) - self.assertEquals(len(der),0) - # One single-byte integer (zero) - der.decode(b('0\x03\x02\x01\x00')) - self.assertEquals(len(der),1) - self.assertEquals(der[0],0) - # Invariant - der.decode(b('0\x03\x02\x01\x00')) - self.assertEquals(len(der),1) - self.assertEquals(der[0],0) - - def testDecode2(self): - # One single-byte integer (non-zero) - der = DerSequence() - der.decode(b('0\x03\x02\x01\x7f')) - self.assertEquals(len(der),1) - self.assertEquals(der[0],127) - - def testDecode4(self): - # One very long integer - der = DerSequence() - der.decode(b('0\x82\x01\x05')+ - b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ - b('\x00\x00\x00\x00\x00\x00\x00\x00\x00')) - self.assertEquals(len(der),1) - self.assertEquals(der[0],2L**2048) - - def testDecode6(self): - # Two integers - der = DerSequence() - der.decode(b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff')) - self.assertEquals(len(der),2) - self.assertEquals(der[0],0x180L) - self.assertEquals(der[1],0xFFL) - - def testDecode7(self): - # One integer and 2 other types - der = DerSequence() - der.decode(b('0\x0A\x02\x02\x01\x80\x24\x02\xb6\x63\x12\x00')) - self.assertEquals(len(der),3) - self.assertEquals(der[0],0x180L) - self.assertEquals(der[1],b('\x24\x02\xb6\x63')) - self.assertEquals(der[2],b('\x12\x00')) - - def testDecode8(self): - # Only 2 other types - der = DerSequence() - der.decode(b('0\x06\x24\x02\xb6\x63\x12\x00')) - self.assertEquals(len(der),2) - self.assertEquals(der[0],b('\x24\x02\xb6\x63')) - self.assertEquals(der[1],b('\x12\x00')) - self.assertEquals(der.hasInts(), 0) - self.assertEquals(der.hasInts(False), 0) - self.failIf(der.hasOnlyInts()) - self.failIf(der.hasOnlyInts(False)) - - def testErrDecode1(self): - # Not a sequence - der = DerSequence() - self.assertRaises(EOFError, der.decode, b('')) - self.assertRaises(ValueError, der.decode, b('\x00')) - self.assertRaises(EOFError, der.decode, b('\x30')) - - def testErrDecode2(self): - der = DerSequence() - # Too much data - self.assertRaises(ValueError, der.decode, b('\x30\x00\x00')) - - def testErrDecode3(self): - # Wrong length format - der = DerSequence() - # Missing length in sub-item - self.assertRaises(EOFError, der.decode, b('\x30\x04\x02\x01\x01\x00')) - # Valid BER, but invalid DER length - self.assertRaises(ValueError, der.decode, b('\x30\x81\x03\x02\x01\x01')) - self.assertRaises(ValueError, der.decode, b('\x30\x04\x02\x81\x01\x01')) - -class DerOctetStringTests(unittest.TestCase): - - def testInit1(self): - der = newDerOctetString(b('\xFF')) - self.assertEquals(der.encode(), b('\x04\x01\xFF')) - - def testEncode1(self): - # Empty sequence - der = DerOctetString() - self.assertEquals(der.encode(), b('\x04\x00')) - # Small payload - der.payload = b('\x01\x02') - self.assertEquals(der.encode(), b('\x04\x02\x01\x02')) - - #### - - def testDecode1(self): - # Empty sequence - der = DerOctetString() - der.decode(b('\x04\x00')) - self.assertEquals(der.payload, b('')) - # Small payload - der.decode(b('\x04\x02\x01\x02')) - self.assertEquals(der.payload, b('\x01\x02')) - - def testErrDecode1(self): - # No leftovers allowed - der = DerOctetString() - self.assertRaises(ValueError, der.decode, b('\x04\x01\x01\xff')) - -class DerNullTests(unittest.TestCase): - - def testEncode1(self): - der = DerNull() - self.assertEquals(der.encode(), b('\x05\x00')) - - #### - - def testDecode1(self): - # Empty sequence - der = DerNull() - der.decode(b('\x05\x00')) - -class DerObjectIdTests(unittest.TestCase): - - def testInit1(self): - der = newDerObjectId("1.1") - self.assertEquals(der.encode(), b('\x06\x01)')) - - def testEncode1(self): - der = DerObjectId('1.2.840.113549.1.1.1') - self.assertEquals(der.encode(), b('\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01')) - # - der = DerObjectId() - der.value = '1.2.840.113549.1.1.1' - self.assertEquals(der.encode(), b('\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01')) - - #### - - def testDecode1(self): - # Empty sequence - der = DerObjectId() - der.decode(b('\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01')) - self.assertEquals(der.value, '1.2.840.113549.1.1.1') - -class DerBitStringTests(unittest.TestCase): - - def testInit1(self): - der = newDerBitString(b("\xFF")) - self.assertEquals(der.encode(), b('\x03\x02\x00\xFF')) - - def testEncode1(self): - # Empty sequence - der = DerBitString() - self.assertEquals(der.encode(), b('\x03\x01\x00')) - # Small payload - der = DerBitString(b('\x01\x02')) - self.assertEquals(der.encode(), b('\x03\x03\x00\x01\x02')) - # Small payload - der = DerBitString() - der.value = b('\x01\x02') - self.assertEquals(der.encode(), b('\x03\x03\x00\x01\x02')) - - #### - - def testDecode1(self): - # Empty sequence - der = DerBitString() - der.decode(b('\x03\x00')) - self.assertEquals(der.value, b('')) - # Small payload - der.decode(b('\x03\x03\x00\x01\x02')) - self.assertEquals(der.value, b('\x01\x02')) - -class DerSetOfTests(unittest.TestCase): - - def testInit1(self): - der = newDerSetOf(DerInteger(1), DerInteger(2)) - self.assertEquals(der.encode(), b('1\x06\x02\x01\x01\x02\x01\x02')) - - def testEncode1(self): - # Empty set - der = DerSetOf() - self.assertEquals(der.encode(), b('1\x00')) - # One single-byte integer (zero) - der.add(0) - self.assertEquals(der.encode(), b('1\x03\x02\x01\x00')) - # Invariant - self.assertEquals(der.encode(), b('1\x03\x02\x01\x00')) - - def testEncode2(self): - # Two integers - der = DerSetOf() - der.add(0x180L) - der.add(0xFFL) - self.assertEquals(der.encode(), b('1\x08\x02\x02\x00\xff\x02\x02\x01\x80')) - # Initialize with integers - der = DerSetOf([0x180L, 0xFFL]) - self.assertEquals(der.encode(), b('1\x08\x02\x02\x00\xff\x02\x02\x01\x80')) - - def testEncode3(self): - # One integer and another type (no matter what it is) - der = DerSetOf() - der.add(0x180L) - self.assertRaises(ValueError, der.add, b('\x00\x02\x00\x00')) - - def testEncode4(self): - # Only non integers - der = DerSetOf() - der.add(b('\x01\x00')) - der.add(b('\x01\x01\x01')) - self.assertEquals(der.encode(), b('1\x05\x01\x00\x01\x01\x01')) - - #### - - def testDecode1(self): - # Empty sequence - der = DerSetOf() - der.decode(b('1\x00')) - self.assertEquals(len(der),0) - # One single-byte integer (zero) - der.decode(b('1\x03\x02\x01\x00')) - self.assertEquals(len(der),1) - self.assertEquals(list(der),[0]) - - def testDecode2(self): - # Two integers - der = DerSetOf() - der.decode(b('1\x08\x02\x02\x01\x80\x02\x02\x00\xff')) - self.assertEquals(len(der),2) - l = list(der) - self.failUnless(0x180 in l) - self.failUnless(0xFF in l) - - def testDecode3(self): - # One integer and 2 other types - der = DerSetOf() - #import pdb; pdb.set_trace() - self.assertRaises(ValueError, der.decode, - b('0\x0A\x02\x02\x01\x80\x24\x02\xb6\x63\x12\x00')) - - def testErrDecode1(self): - # No leftovers allowed - der = DerSetOf() - self.assertRaises(ValueError, der.decode, - b('1\x08\x02\x02\x01\x80\x02\x02\x00\xff\xAA')) + def testEncode1(self): + # Empty sequence + der = DerSequence() + self.assertEquals(der.encode(), b('0\x00')) + self.failIf(der.hasOnlyInts()) + # One single-byte integer (zero) + der.append(0) + self.assertEquals(der.encode(), b('0\x03\x02\x01\x00')) + self.failUnless(der.hasOnlyInts()) + # Invariant + self.assertEquals(der.encode(), b('0\x03\x02\x01\x00')) + + def testEncode2(self): + # One single-byte integer (non-zero) + der = DerSequence() + der.append(127) + self.assertEquals(der.encode(), b('0\x03\x02\x01\x7f')) + # Indexing + der[0] = 1 + self.assertEquals(len(der),1) + self.assertEquals(der[0],1) + self.assertEquals(der[-1],1) + self.assertEquals(der.encode(), b('0\x03\x02\x01\x01')) + # + der[:] = [1] + self.assertEquals(len(der),1) + self.assertEquals(der[0],1) + self.assertEquals(der.encode(), b('0\x03\x02\x01\x01')) + + def testEncode3(self): + # One multi-byte integer (non-zero) + der = DerSequence() + der.append(0x180L) + self.assertEquals(der.encode(), b('0\x04\x02\x02\x01\x80')) + + def testEncode4(self): + # One very long integer + der = DerSequence() + der.append(2**2048) + self.assertEquals(der.encode(), b('0\x82\x01\x05')+ + b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00')) + + def testEncode5(self): + # One single-byte integer (looks negative) + der = DerSequence() + der.append(0xFFL) + self.assertEquals(der.encode(), b('0\x04\x02\x02\x00\xff')) + + def testEncode6(self): + # Two integers + der = DerSequence() + der.append(0x180L) + der.append(0xFFL) + self.assertEquals(der.encode(), b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff')) + self.failUnless(der.hasOnlyInts()) + # + der.append(0x01) + der[1:] = [9,8] + self.assertEquals(len(der),3) + self.assertEqual(der[1:],[9,8]) + self.assertEqual(der[1:-1],[9]) + self.assertEquals(der.encode(), b('0\x0A\x02\x02\x01\x80\x02\x01\x09\x02\x01\x08')) + + def testEncode6(self): + # One integer and another type (no matter what it is) + der = DerSequence() + der.append(0x180L) + der.append(b('\x00\x02\x00\x00')) + self.assertEquals(der.encode(), b('0\x08\x02\x02\x01\x80\x00\x02\x00\x00')) + self.failIf(der.hasOnlyInts()) + + #### + + def testDecode1(self): + # Empty sequence + der = DerSequence() + der.decode(b('0\x00')) + self.assertEquals(len(der),0) + # One single-byte integer (zero) + der.decode(b('0\x03\x02\x01\x00')) + self.assertEquals(len(der),1) + self.assertEquals(der[0],0) + # Invariant + der.decode(b('0\x03\x02\x01\x00')) + self.assertEquals(len(der),1) + self.assertEquals(der[0],0) + + def testDecode2(self): + # One single-byte integer (non-zero) + der = DerSequence() + der.decode(b('0\x03\x02\x01\x7f')) + self.assertEquals(len(der),1) + self.assertEquals(der[0],127) + + def testDecode3(self): + # One multi-byte integer (non-zero) + der = DerSequence() + der.decode(b('0\x04\x02\x02\x01\x80')) + self.assertEquals(len(der),1) + self.assertEquals(der[0],0x180L) + + def testDecode4(self): + # One very long integer + der = DerSequence() + der.decode(b('0\x82\x01\x05')+ + b('\x02\x82\x01\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')+ + b('\x00\x00\x00\x00\x00\x00\x00\x00\x00')) + self.assertEquals(len(der),1) + self.assertEquals(der[0],2**2048) + + def testDecode5(self): + # One single-byte integer (looks negative) + der = DerSequence() + der.decode(b('0\x04\x02\x02\x00\xff')) + self.assertEquals(len(der),1) + self.assertEquals(der[0],0xFFL) + + def testDecode6(self): + # Two integers + der = DerSequence() + der.decode(b('0\x08\x02\x02\x01\x80\x02\x02\x00\xff')) + self.assertEquals(len(der),2) + self.assertEquals(der[0],0x180L) + self.assertEquals(der[1],0xFFL) + + def testDecode7(self): + # One integer and 2 other types + der = DerSequence() + der.decode(b('0\x0A\x02\x02\x01\x80\x24\x02\xb6\x63\x12\x00')) + self.assertEquals(len(der),3) + self.assertEquals(der[0],0x180L) + self.assertEquals(der[1],b('\x24\x02\xb6\x63')) + self.assertEquals(der[2],b('\x12\x00')) + + def testDecode8(self): + # Only 2 other types + der = DerSequence() + der.decode(b('0\x06\x24\x02\xb6\x63\x12\x00')) + self.assertEquals(len(der),2) + self.assertEquals(der[0],b('\x24\x02\xb6\x63')) + self.assertEquals(der[1],b('\x12\x00')) + + def testErrDecode1(self): + # Not a sequence + der = DerSequence() + self.assertRaises(ValueError, der.decode, b('')) + self.assertRaises(ValueError, der.decode, b('\x00')) + self.assertRaises(ValueError, der.decode, b('\x30')) + + def testErrDecode2(self): + # Wrong payload type + der = DerSequence() + self.assertRaises(ValueError, der.decode, b('\x30\x00\x00'), True) + + def testErrDecode3(self): + # Wrong length format + der = DerSequence() + self.assertRaises(ValueError, der.decode, b('\x30\x04\x02\x01\x01\x00')) + self.assertRaises(ValueError, der.decode, b('\x30\x81\x03\x02\x01\x01')) + self.assertRaises(ValueError, der.decode, b('\x30\x04\x02\x81\x01\x01')) + + def testErrDecode4(self): + # Wrong integer format + der = DerSequence() + # Multi-byte encoding for zero + #self.assertRaises(ValueError, der.decode, '\x30\x04\x02\x02\x00\x00') + # Negative integer + self.assertRaises(ValueError, der.decode, b('\x30\x04\x02\x01\xFF')) def get_tests(config={}): from Crypto.SelfTest.st_common import list_test_cases listTests = [] listTests += list_test_cases(DerObjectTests) - listTests += list_test_cases(DerIntegerTests) listTests += list_test_cases(DerSequenceTests) - listTests += list_test_cases(DerOctetStringTests) - listTests += list_test_cases(DerNullTests) - listTests += list_test_cases(DerObjectIdTests) - listTests += list_test_cases(DerBitStringTests) - listTests += list_test_cases(DerSetOfTests) return listTests if __name__ == '__main__': diff --git a/lib/Crypto/SelfTest/Util/test_number.py b/lib/Crypto/SelfTest/Util/test_number.py index ac23e917..0502e9e1 100644 --- a/lib/Crypto/SelfTest/Util/test_number.py +++ b/lib/Crypto/SelfTest/Util/test_number.py @@ -31,10 +31,6 @@ from Crypto.Util.py21compat import * import unittest -from Crypto.SelfTest.st_common import assert_disabled - -class MyError(Exception): - """Dummy exception used for tests""" # NB: In some places, we compare tuples instead of just output values so that # if any inputs cause a test failure, we'll be able to tell which ones. @@ -47,9 +43,8 @@ def setUp(self): def test_ceil_shift(self): """Util.number.ceil_shift""" - if not assert_disabled(): - self.assertRaises(AssertionError, number.ceil_shift, -1, 1) - self.assertRaises(AssertionError, number.ceil_shift, 1, -1) + self.assertRaises(AssertionError, number.ceil_shift, -1, 1) + self.assertRaises(AssertionError, number.ceil_shift, 1, -1) # b = 0 self.assertEqual(0, number.ceil_shift(0, 0)) @@ -281,11 +276,6 @@ def test_size(self): self.assertEqual(number.size(0xa2ba40),8*3) self.assertEqual(number.size(0xa2ba40ee07e3b2bd2f02ce227f36a195024486e49c19cb41bbbdfbba98b22b0e577c2eeaffa20d883a76e65e394c69d4b3c05a1e8fadda27edb2a42bc000fe888b9b32c22d15add0cd76b3e7936e19955b220dd17d4ea904b1ec102b2e4de7751222aa99151024c7cb41cc5ea21d00eeb41f7c800834d2c6e06bce3bce7ea9a5L), 1024) -class FastmathTests(unittest.TestCase): - def setUp(self): - global number - from Crypto.Util import number - def test_negative_number_roundtrip_mpzToLongObj_longObjToMPZ(self): """Test that mpzToLongObj and longObjToMPZ (internal functions) roundtrip negative numbers correctly.""" n = -100000000000000000000000000000000000L @@ -294,42 +284,9 @@ def test_negative_number_roundtrip_mpzToLongObj_longObjToMPZ(self): self.assertEqual(n, k.n) self.assertEqual(e, k.e) - def test_isPrime_randfunc_exception(self): - """Test that when isPrime is called, an exception raised in randfunc is propagated.""" - def randfunc(n): - raise MyError - prime = 3536384141L # Needs to be large enough so that rabinMillerTest will be invoked - self.assertRaises(MyError, number._fastmath.isPrime, prime, randfunc=randfunc) - - def test_getStrongPrime_randfunc_exception(self): - """Test that when getStrongPrime is called, an exception raised in randfunc is propagated.""" - def randfunc(n): - raise MyError - self.assertRaises(MyError, number._fastmath.getStrongPrime, 512, randfunc=randfunc) - - def test_isPrime_randfunc_bogus(self): - """Test that when isPrime is called, an exception is raised if randfunc returns something bogus.""" - def randfunc(n): - return None - prime = 3536384141L # Needs to be large enough so that rabinMillerTest will be invoked - self.assertRaises(TypeError, number._fastmath.isPrime, prime, randfunc=randfunc) - - def test_getStrongPrime_randfunc_bogus(self): - """Test that when getStrongPrime is called, an exception is raised if randfunc returns something bogus.""" - def randfunc(n): - return None - self.assertRaises(TypeError, number._fastmath.getStrongPrime, 512, randfunc=randfunc) - def get_tests(config={}): from Crypto.SelfTest.st_common import list_test_cases - tests = list_test_cases(MiscTests) - try: - from Crypto.PublicKey import _fastmath - tests += list_test_cases(FastmathTests) - except ImportError: - from Crypto.SelfTest.st_common import handle_fastmath_import_error - handle_fastmath_import_error() - return tests + return list_test_cases(MiscTests) if __name__ == '__main__': suite = lambda: unittest.TestSuite(get_tests()) diff --git a/lib/Crypto/SelfTest/__init__.py b/lib/Crypto/SelfTest/__init__.py index cb5782f3..40b39693 100644 --- a/lib/Crypto/SelfTest/__init__.py +++ b/lib/Crypto/SelfTest/__init__.py @@ -66,13 +66,11 @@ def run(module=None, verbosity=0, stream=None, tests=None, config=None, **kwargs raise ValueError("'module' and 'tests' arguments are mutually exclusive") if stream is None: kwargs['stream'] = StringIO() - else: - kwargs['stream'] = stream runner = unittest.TextTestRunner(verbosity=verbosity, **kwargs) result = runner.run(suite) if not result.wasSuccessful(): if stream is None: - sys.stderr.write(kwargs['stream'].getvalue()) + sys.stderr.write(stream.getvalue()) raise SelfTestError("Self-test failed", result) return result @@ -85,7 +83,6 @@ def get_tests(config={}): from Crypto.SelfTest import Random; tests += Random.get_tests(config=config) from Crypto.SelfTest import Util; tests += Util.get_tests(config=config) from Crypto.SelfTest import Signature; tests += Signature.get_tests(config=config) - from Crypto.SelfTest import IO; tests += IO.get_tests(config=config) return tests if __name__ == '__main__': diff --git a/lib/Crypto/SelfTest/st_common.py b/lib/Crypto/SelfTest/st_common.py index e76525c8..c56eac5f 100644 --- a/lib/Crypto/SelfTest/st_common.py +++ b/lib/Crypto/SelfTest/st_common.py @@ -59,30 +59,4 @@ def b2a_hex(s): # For completeness return binascii.b2a_hex(s) -def handle_fastmath_import_error(): - import Crypto.PublicKey - import imp - try: - file, pathname, description = imp.find_module("_fastmath", Crypto.PublicKey.__path__) - except ImportError: - sys.stderr.write("SelfTest: warning: not testing _fastmath module (not available)\n") - else: - file.close() - raise ImportError("While the _fastmath module exists, importing " - "it failed. This may point to the gmp or mpir shared library " - "not being in the path. _fastmath was found at %s" % (pathname,)) - -def docstrings_disabled(): - """Returns True if docstrings are disabled (e.g. by using python -OO)""" - return docstrings_disabled.__doc__ is None - -def assert_disabled(): - """Returns True if 'assert' is a no-op (e.g. by using python -O)""" - try: - assert False - except AssertionError: - return False - else: - return True - # vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/lib/Crypto/Signature/PKCS1_PSS.py b/lib/Crypto/Signature/PKCS1_PSS.py index fb97b21f..4f50eb85 100644 --- a/lib/Crypto/Signature/PKCS1_PSS.py +++ b/lib/Crypto/Signature/PKCS1_PSS.py @@ -30,22 +30,22 @@ this: >>> from Crypto.Signature import PKCS1_PSS - >>> from Crypto.Hash import SHA1 - >>> from Crypto.PublicKey import RSA1 + >>> from Crypto.Hash import SHA + >>> from Crypto.PublicKey import RSA >>> from Crypto import Random >>> >>> message = 'To be signed' >>> key = RSA.importKey(open('privkey.der').read()) - >>> h = SHA1.new() + >>> h = SHA.new() >>> h.update(message) >>> signer = PKCS1_PSS.new(key) - >>> signature = signer.sign(h) + >>> signature = PKCS1_PSS.sign(key) At the receiver side, verification can be done like using the public part of the RSA key: >>> key = RSA.importKey(open('pubkey.der').read()) - >>> h = SHA1.new() + >>> h = SHA.new() >>> h.update(message) >>> verifier = PKCS1_PSS.new(key) >>> if verifier.verify(h, signature): @@ -72,7 +72,6 @@ import Crypto.Util.number from Crypto.Util.number import ceil_shift, ceil_div, long_to_bytes from Crypto.Util.strxor import strxor -from Crypto.Hash import new as Hash_new class PSS_SigScheme: """This signature scheme can perform PKCS#1 PSS RSA signature or verification.""" @@ -204,11 +203,7 @@ def MGF1(mgfSeed, maskLen, hash): T = b("") for counter in xrange(ceil_div(maskLen, hash.digest_size)): c = long_to_bytes(counter, 4) - try: - T = T + hash.new(mgfSeed + c).digest() - except AttributeError: - # hash object doesn't have a "new" method. Use Crypto.Hash.new() to instantiate it - T = T + Hash_new(hash, mgfSeed + c).digest() + T = T + hash.new(mgfSeed + c).digest() assert(len(T)>=maskLen) return T[:maskLen] @@ -258,11 +253,7 @@ def EMSA_PSS_ENCODE(mhash, emBits, randFunc, mgf, sLen): if randFunc and sLen>0: salt = randFunc(sLen) # Step 5 and 6 - try: - h = mhash.new(bchr(0x00)*8 + mhash.digest() + salt) - except AttributeError: - # hash object doesn't have a "new" method. Use Crypto.Hash.new() to instantiate it - h = Hash_new(mhash, bchr(0x00)*8 + mhash.digest() + salt) + h = mhash.new(bchr(0x00)*8 + mhash.digest() + salt) # Step 7 and 8 db = bchr(0x00)*(emLen-sLen-mhash.digest_size-2) + bchr(0x01) + salt # Step 9 @@ -337,11 +328,7 @@ def EMSA_PSS_VERIFY(mhash, em, emBits, mgf, sLen): salt = b("") if sLen: salt = db[-sLen:] # Step 12 and 13 - try: - hp = mhash.new(bchr(0x00)*8 + mhash.digest() + salt).digest() - except AttributeError: - # hash object doesn't have a "new" method. Use Crypto.Hash.new() to instantiate it - hp = Hash_new(mhash, bchr(0x00)*8 + mhash.digest() + salt).digest() + hp = mhash.new(bchr(0x00)*8 + mhash.digest() + salt).digest() # Step 14 if h!=hp: return False diff --git a/lib/Crypto/Signature/PKCS1_v1_5.py b/lib/Crypto/Signature/PKCS1_v1_5.py index 6a2e0d01..73ac251c 100644 --- a/lib/Crypto/Signature/PKCS1_v1_5.py +++ b/lib/Crypto/Signature/PKCS1_v1_5.py @@ -60,13 +60,9 @@ __revision__ = "$Id$" __all__ = [ 'new', 'PKCS115_SigScheme' ] -import sys - import Crypto.Util.number from Crypto.Util.number import ceil_div -from Crypto.Util.asn1 import DerSequence, DerNull, DerOctetString, DerObjectId -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * +from Crypto.Util.asn1 import DerSequence, DerNull, DerOctetString from Crypto.Util.py3compat import * class PKCS115_SigScheme: @@ -154,13 +150,7 @@ def verify(self, mhash, S): em1 = bchr(0x00)*(k-len(m)) + m # Step 3 try: - em2_with_params = EMSA_PKCS1_V1_5_ENCODE(mhash, k, True) - # MD hashes always require NULL params in AlgorithmIdentifier. - # For all others, it is optional. - if _HASH_OIDS[mhash.name].startswith('1.2.840.113549.2.'): # MD2/MD4/MD5 - em2_without_params = em2_with_params - else: - em2_without_params = EMSA_PKCS1_V1_5_ENCODE(mhash, k, False) + em2 = EMSA_PKCS1_V1_5_ENCODE(mhash, k) except ValueError: return 0 # Step 4 @@ -168,9 +158,9 @@ def verify(self, mhash, S): # of its components one at a time) we avoid attacks to the padding # scheme like Bleichenbacher's (see http://www.mail-archive.com/cryptography@metzdowd.com/msg06537). # - return em1==em2_with_params or em1==em2_without_params + return em1==em2 -def EMSA_PKCS1_V1_5_ENCODE(hash, emLen, with_hash_parameters=True): +def EMSA_PKCS1_V1_5_ENCODE(hash, emLen): """ Implement the ``EMSA-PKCS1-V1_5-ENCODE`` function, as defined in PKCS#1 v2.1 (RFC3447, 9.2). @@ -184,9 +174,6 @@ def EMSA_PKCS1_V1_5_ENCODE(hash, emLen, with_hash_parameters=True): The hash object that holds the digest of the message being signed. emLen : int The length the final encoding must have, in bytes. - with_hash_parameters: - If True (default), include NULL parameters for the hash - algorithm in the ``digestAlgorithm`` SEQUENCE. :attention: the early standard (RFC2313) stated that ``DigestInfo`` had to be BER-encoded. This means that old signatures @@ -194,6 +181,11 @@ def EMSA_PKCS1_V1_5_ENCODE(hash, emLen, with_hash_parameters=True): is not supported in DER. Such encoding cannot be reproduced by this function. + :attention: the same standard defined ``DigestAlgorithm`` to be + of ``AlgorithmIdentifier`` type, where the PARAMETERS + item is optional. Encodings for ``MD2/4/5`` without + ``PARAMETERS`` cannot be reproduced by this function. + :Return: An ``emLen`` byte long string that encodes the hash. """ @@ -216,19 +208,7 @@ def EMSA_PKCS1_V1_5_ENCODE(hash, emLen, with_hash_parameters=True): # { OID id-sha512 PARAMETERS NULL } # } # - # Appendix B.1 also says that for SHA-1/-2 algorithms, the parameters - # should be omitted. They may be present, but when they are, they shall - # have NULL value. - - if with_hash_parameters: - digestAlgo = DerSequence([ - DerObjectId(_HASH_OIDS[hash.name]).encode(), - DerNull().encode() - ]) - else: - digestAlgo = DerSequence([ - DerObjectId(_HASH_OIDS[hash.name]).encode(), - ]) + digestAlgo = DerSequence([hash.oid, DerNull().encode()]) digest = DerOctetString(hash.digest()) digestInfo = DerSequence([ digestAlgo.encode(), @@ -238,7 +218,7 @@ def EMSA_PKCS1_V1_5_ENCODE(hash, emLen, with_hash_parameters=True): # We need at least 11 bytes for the remaining data: 3 fixed bytes and # at least 8 bytes of padding). if emLen>> from Crypto.Cipher import AES >>> from Crypto.Util import Counter - >>> from Crypto import Random >>> - >>> nonce = Random.get_random_bytes(8) - >>> ctr = Counter.new(64, nonce) - >>> key = b'AES-128 symm key' - >>> plaintext = b'X'*1000000 - >>> cipher = AES.new(key, AES.MODE_CTR, counter=ctr) - >>> ciphertext = cipher.encrypt(plaintext) + >>> pt = b'\x00'*1000000 + >>> ctr = Counter.new(128) + >>> cipher = AES.new(b'\x00'*16, AES.MODE_CTR, counter=ctr) + >>> ct = cipher.encrypt(pt) :undocumented: __package__ """ @@ -59,23 +56,19 @@ from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * -from Crypto.pct_warnings import DisableShortcut_DeprecationWarning from Crypto.Util import _counter import struct -import warnings - # Factory function -_deprecated = "deprecated" -def new(nbits, prefix=b(""), suffix=b(""), initial_value=1, overflow=0, little_endian=False, allow_wraparound=False, disable_shortcut=_deprecated): +def new(nbits, prefix=b(""), suffix=b(""), initial_value=1, overflow=0, little_endian=False, allow_wraparound=False, disable_shortcut=False): """Create a stateful counter block function suitable for CTR encryption modes. Each call to the function returns the next counter block. Each counter block is made up by three parts:: - + prefix || counter value || postfix - The counter value is incremented by 1 at each call. + The counter value is incremented by one at each call. :Parameters: nbits : integer @@ -88,18 +81,17 @@ def new(nbits, prefix=b(""), suffix=b(""), initial_value=1, overflow=0, little_e used. initial_value : integer The initial value of the counter. Default value is 1. - overflow : integer - This value is currently ignored. little_endian : boolean - If *True*, the counter number will be encoded in little endian format. - If *False* (default), in big endian format. + If True, the counter number will be encoded in little endian format. + If False (default), in big endian format. allow_wraparound : boolean - If *True*, the counter will automatically restart from zero after - reaching the maximum value (``2**nbits-1``). - If *False* (default), the object will raise an *OverflowError*. - disable_shortcut : deprecated - This option is a no-op for backward compatibility. It will be removed - in a future version. Don't use it. + If True, the function will raise an *OverflowError* exception as soon + as the counter wraps around. If False (default), the counter will + simply restart from zero. + disable_shortcut : boolean + If True, do not make ciphers from `Crypto.Cipher` bypass the Python + layer when invoking the counter block function. + If False (default), bypass the Python layer. :Returns: The counter block function. """ @@ -116,13 +108,10 @@ def new(nbits, prefix=b(""), suffix=b(""), initial_value=1, overflow=0, little_e initval = _encode(initial_value, nbytes, little_endian) - if disable_shortcut is not _deprecated: # exact object comparison - warnings.warn("disable_shortcut has no effect and is deprecated", DisableShortcut_DeprecationWarning) - if little_endian: - return _counter._newLE(bstr(prefix), bstr(suffix), initval, allow_wraparound=allow_wraparound) + return _counter._newLE(bstr(prefix), bstr(suffix), initval, allow_wraparound=allow_wraparound, disable_shortcut=disable_shortcut) else: - return _counter._newBE(bstr(prefix), bstr(suffix), initval, allow_wraparound=allow_wraparound) + return _counter._newBE(bstr(prefix), bstr(suffix), initval, allow_wraparound=allow_wraparound, disable_shortcut=disable_shortcut) def _encode(n, nbytes, little_endian=False): retval = [] diff --git a/lib/Crypto/Util/Padding.py b/lib/Crypto/Util/Padding.py deleted file mode 100644 index e05b79a9..00000000 --- a/lib/Crypto/Util/Padding.py +++ /dev/null @@ -1,100 +0,0 @@ -# -# -*- coding: utf-8 -*- -# -# Util/Padding.py : Functions to manage padding -# -# =================================================================== -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# =================================================================== - -""" Functions to manage padding - -This module provides minimal support for adding and removing standard padding -from data. -""" - -__all__ = [ 'ValueError', 'pad', 'unpad' ] - -from Crypto.Util.py3compat import * - - -def pad(data_to_pad, block_size, style='pkcs7'): - """Apply standard padding. - - :Parameters: - data_to_pad : byte string - The data that needs to be padded. - block_size : integer - The block boundary to use for padding. The output length is guaranteed - to be a multiple of ``block_size``. - style : string - Padding algorithm. It can be *'pkcs7'* (default), *'iso7816'* or *'x923'*. - :Return: - The original data with the appropriate padding added at the end. - """ - - padding_len = block_size-len(data_to_pad)%block_size - if style == 'pkcs7': - padding = bchr(padding_len)*padding_len - elif style == 'x923': - padding = bchr(0)*(padding_len-1) + bchr(padding_len) - elif style == 'iso7816': - padding = bchr(128) + bchr(0)*(padding_len-1) - else: - raise ValueError("Unknown padding style") - return data_to_pad + padding - -def unpad(padded_data, block_size, style='pkcs7'): - """Remove standard padding. - - :Parameters: - padded_data : byte string - A piece of data with padding that needs to be stripped. - block_size : integer - The block boundary to use for padding. The input length - must be a multiple of ``block_size``. - style : string - Padding algorithm. It can be *'pkcs7'* (default), *'iso7816'* or *'x923'*. - :Return: - Data without padding. - :Raises ValueError: - if the padding is incorrect. - """ - - pdata_len = len(padded_data) - if pdata_len % block_size: - raise ValueError("Input data is not padded") - if style in ('pkcs7', 'x923'): - padding_len = bord(padded_data[-1]) - if padding_len<1 or padding_len>min(block_size, pdata_len): - raise ValueError("Padding is incorrect.") - if style == 'pkcs7': - if padded_data[-padding_len:]!=bchr(padding_len)*padding_len: - raise ValueError("PKCS#7 padding is incorrect.") - else: - if padded_data[-padding_len:-1]!=bchr(0)*(padding_len-1): - raise ValueError("ANSI X.923 padding is incorrect.") - elif style == 'iso7816': - padding_len = pdata_len - padded_data.rfind(bchr(128)) - if padding_len<1 or padding_len>min(block_size, pdata_len): - raise ValueError("Padding is incorrect.") - if padding_len>1 and padded_data[1-padding_len:]!=bchr(0)*(padding_len-1): - raise ValueError("ISO 7816-4 padding is incorrect.") - else: - raise ValueError("Unknown padding style") - return padded_data[:-padding_len] - diff --git a/lib/Crypto/Util/__init__.py b/lib/Crypto/Util/__init__.py index b2030c03..a3bef8ae 100644 --- a/lib/Crypto/Util/__init__.py +++ b/lib/Crypto/Util/__init__.py @@ -23,22 +23,15 @@ Contains useful modules that don't belong into any of the other Crypto.* subpackages. -======================== ============================================= -Module Description -======================== ============================================= -`Crypto.Util.number` Number-theoretic functions (primality testing, etc.) -`Crypto.Util.Counter` Fast counter functions for CTR cipher modes. -`Crypto.Util.randpool` Random number generation -`Crypto.Util.RFC1751` Converts between 128-bit keys and human-readable - strings of words. -`Crypto.Util.asn1` Minimal support for ASN.1 DER encoding -`Crypto.Util.Padding` Set of functions for adding and removing padding. -======================== ============================================= +Crypto.Util.number Number-theoretic functions (primality testing, etc.) +Crypto.Util.randpool Random number generation +Crypto.Util.RFC1751 Converts between 128-bit keys and human-readable + strings of words. +Crypto.Util.asn1 Minimal support for ASN.1 DER encoding """ -__all__ = ['randpool', 'RFC1751', 'number', 'strxor', 'asn1', 'Counter', - 'Padding' ] +__all__ = ['randpool', 'RFC1751', 'number', 'strxor', 'asn1' ] __revision__ = "$Id$" diff --git a/lib/Crypto/Util/_time.py b/lib/Crypto/Util/_time.py deleted file mode 100644 index ff4c6a92..00000000 --- a/lib/Crypto/Util/_time.py +++ /dev/null @@ -1,28 +0,0 @@ -# -*- coding: ascii -*- -# -# _time.py : Internal monotonic time module. -# -# Written in 2013 by Dwayne C. Litzenberger -# -# =================================================================== -# The contents of this file are dedicated to the public domain. To -# the extent that dedication to the public domain is not available, -# everyone is granted a worldwide, perpetual, royalty-free, -# non-exclusive license to exercise all rights associated with the -# contents of this file for any purpose whatsoever. -# No rights are reserved. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS -# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# =================================================================== - -try: - from time import monotonic as maybe_monotonic_time -except ImportError: - from time import time as maybe_monotonic_time diff --git a/lib/Crypto/Util/asn1.py b/lib/Crypto/Util/asn1.py index 4c0ca37e..dd5ec31d 100644 --- a/lib/Crypto/Util/asn1.py +++ b/lib/Crypto/Util/asn1.py @@ -19,349 +19,148 @@ # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. # =================================================================== -""" ASN.1 DER encoding and decoding - -This module provides minimal support for encoding and decoding `ASN.1`_ DER -objects. - -.. _`ASN.1`: ftp://ftp.rsasecurity.com/pub/pkcs/ascii/layman.asc - -""" - -from __future__ import nested_scopes +from Crypto.Util.number import long_to_bytes, bytes_to_long import sys - -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * from Crypto.Util.py3compat import * -if sys.version_info[0] == 2 and sys.version_info[1] == 1: - from Crypto.Util.py21compat import * - -from Crypto.Util.number import long_to_bytes, bytes_to_long - -__all__ = [ 'DerObject', 'DerInteger', 'DerOctetString', 'DerNull', - 'DerSequence', 'DerObjectId', 'DerBitString', 'DerSetOf', - 'newDerInteger', 'newDerOctetString', 'newDerSequence', - 'newDerObjectId', 'newDerBitString', 'newDerSetOf' ] - -def _isInt(x, onlyNonNegative=False): - test = 0 - try: - test += x - except TypeError: - return False - return not onlyNonNegative or x>=0 - -class BytesIO_EOF(BytesIO): - """This class differs from BytesIO in that an EOFError exception is - raised whenever EOF is reached.""" - - def __init__(self, *params): - BytesIO.__init__(self, *params) - self.setRecord(False) - - def setRecord(self, record): - self._record = record - self._recording = b("") - - def read(self, length): - s = BytesIO.read(self, length) - if len(s)127: encoding = long_to_bytes(payloadLen) return bchr(len(encoding)+128) + encoding return bchr(payloadLen) def encode(self): - """Return this DER element, fully encoded as a binary byte string.""" - # Concatenate identifier octets, length octets, - # and contents octets - return bchr(self._idOctet) + self._lengthOctets() + self.payload + """Return a complete DER element, fully encoded as a TLV.""" + return bchr(self.typeTag) + self._lengthOctets(len(self.payload)) + self.payload - def _decodeLen(self, s): - """Decode DER length octets from a file.""" + def _decodeLen(self, idx, der): + """Given a (part of a) DER element, and an index to the first byte of + a DER length tag (L), return a tuple with the payload size, + and the index of the first byte of the such payload (V). - length = bord(s.read_byte()) + Raises a ValueError exception if the DER length is invalid. + Raises an IndexError exception if the DER element is too short. + """ + length = bord(der[idx]) if length<=127: - return length - payloadLength = bytes_to_long(s.read(length & 0x7F)) - # According to DER (but not BER) the long form is used - # only when the length doesn't fit into 7 bits. + return (length,idx+1) + payloadLength = bytes_to_long(der[idx+1:idx+1+(length & 0x7F)]) if payloadLength<=127: - raise ValueError("Not a DER length tag (but still valid BER).") - return payloadLength + raise ValueError("Not a DER length tag.") + return (payloadLength, idx+1+(length & 0x7F)) - def decode(self, derEle): + def decode(self, derEle, noLeftOvers=0): """Decode a complete DER element, and re-initializes this object with it. - :Parameters: - derEle : byte string - A complete DER element. + @param derEle A complete DER element. It must start with a DER T + tag. + @param noLeftOvers Indicate whether it is acceptable to complete the + parsing of the DER element and find that not all + bytes in derEle have been used. + @return Index of the first unused byte in the given DER element. - :Raise ValueError: - In case of parsing errors. - :Raise EOFError: - If the DER element is too short. + Raises a ValueError exception in case of parsing errors. + Raises an IndexError exception if the DER element is too short. """ - - s = BytesIO_EOF(derEle) - self._decodeFromStream(s) - # There shouldn't be other bytes left try: - b = s.read_byte() - raise ValueError("Unexpected extra data after the DER structure") - except EOFError: - pass - - def _decodeFromStream(self, s): - """Decode a complete DER element from a file.""" - - try: - idOctet = bord(s.read_byte()) - except EOFError: - raise _NoDerElementError - if self._idOctet != None: - if idOctet != self._idOctet: - raise ValueError("Unexpected DER tag") - else: - self._idOctet = idOctet - length = self._decodeLen(s) - self.payload = s.read(length) + self.typeTag = bord(derEle[0]) + if (self.typeTag & 0x1F)==0x1F: + raise ValueError("Unsupported DER tag") + (length,idx) = self._decodeLen(1, derEle) + if noLeftOvers and len(derEle) != (idx+length): + raise ValueError("Not a DER structure") + self.payload = derEle[idx:idx+length] + except IndexError: + raise ValueError("Not a valid DER SEQUENCE.") + return idx+length class DerInteger(DerObject): - """Class to model a DER INTEGER. - - An example of encoding is: - - >>> from Crypto.Util.asn1 import DerInteger - >>> from binascii import hexlify, unhexlify - >>> int_der = DerInteger(9) - >>> print hexlify(int_der.encode()) - - which will show ``020109``, the DER encoding of 9. - - And for decoding: - - >>> s = unhexlify(b'020109') - >>> try: - >>> int_der = DerInteger() - >>> int_der.decode(s) - >>> print int_der.value - >>> except (ValueError, EOFError): - >>> print "Not a valid DER INTEGER" + def __init__(self, value = 0): + """Class to model an INTEGER DER element. - the output will be ``9``. - """ - - def __init__(self, value=0, implicit=None): - """Initialize the DER object as an INTEGER. - - :Parameters: - value : integer - The value of the integer. - - implicit : integer - The IMPLICIT tag to use for the encoded object. - It overrides the universal tag for INTEGER (2). + Limitation: only non-negative values are supported. """ - - DerObject.__init__(self, 0x02, b(''), implicit, False) - self.value = value #: The integer value + DerObject.__init__(self, 'INTEGER') + self.value = value def encode(self): - """Return the DER INTEGER, fully encoded as a - binary string.""" - - number = self.value - self.payload = b('') - while True: - self.payload = bchr(number&255) + self.payload - if 128 <= number <= 255: + """Return a complete INTEGER DER element, fully encoded as a TLV.""" + self.payload = long_to_bytes(self.value) + if bord(self.payload[0])>127: self.payload = bchr(0x00) + self.payload - if -128 <= number <= 255: - break - number >>= 8 return DerObject.encode(self) - def decode(self, derEle): - """Decode a complete DER INTEGER DER, and re-initializes this + def decode(self, derEle, noLeftOvers=0): + """Decode a complete INTEGER DER element, and re-initializes this object with it. - :Parameters: - derEle : byte string - A complete INTEGER DER element. + @param derEle A complete INTEGER DER element. It must start with a DER + INTEGER tag. + @param noLeftOvers Indicate whether it is acceptable to complete the + parsing of the DER element and find that not all + bytes in derEle have been used. + @return Index of the first unused byte in the given DER element. - :Raise ValueError: - In case of parsing errors. - :Raise EOFError: - If the DER element is too short. + Raises a ValueError exception if the DER element is not a + valid non-negative INTEGER. + Raises an IndexError exception if the DER element is too short. """ - DerObject.decode(self, derEle) - - def _decodeFromStream(self, s): - """Decode a complete DER INTEGER from a file.""" - - # Fill up self.payload - DerObject._decodeFromStream(self, s) - - # Derive self.value from self.payload - self.value = 0L - bits = 1 - for i in self.payload: - self.value *= 256 - self.value += bord(i) - bits <<= 8 - if self.payload and bord(self.payload[0]) & 0x80: - self.value -= bits - -def newDerInteger(number): - """Create a DerInteger object, already initialized with an integer.""" - - der = DerInteger(number) - return der + tlvLength = DerObject.decode(self, derEle, noLeftOvers) + if self.typeTag!=self.typeTags['INTEGER']: + raise ValueError ("Not a DER INTEGER.") + if bord(self.payload[0])>127: + raise ValueError ("Negative INTEGER.") + self.value = bytes_to_long(self.payload) + return tlvLength class DerSequence(DerObject): - """Class to model a DER SEQUENCE. - - This object behaves like a dynamic Python sequence. - - Sub-elements that are INTEGERs behave like Python integers. + """Class to model a SEQUENCE DER element. - Any other sub-element is a binary string encoded as a complete DER + This object behave like a dynamic Python sequence. + Sub-elements that are INTEGERs, look like Python integers. + Any other sub-element is a binary string encoded as the complete DER sub-element (TLV). - - An example of encoding is: - - >>> from Crypto.Util.asn1 import DerSequence, DerInteger - >>> from binascii import hexlify, unhexlify - >>> obj_der = unhexlify('070102') - >>> seq_der = DerSequence([4]) - >>> seq_der.append(9) - >>> seq_der.append(obj_der.encode()) - >>> print hexlify(seq_der.encode()) - - which will show ``3009020104020109070102``, the DER encoding of the - sequence containing ``4``, ``9``, and the object with payload ``02``. - - For decoding: - - >>> s = unhexlify(b'3009020104020109070102') - >>> try: - >>> seq_der = DerSequence() - >>> seq_der.decode(s) - >>> print len(seq_der) - >>> print seq_der[0] - >>> print seq_der[:] - >>> except (ValueError, EOFError): - >>> print "Not a valid DER SEQUENCE" - - the output will be:: - - 3 - 4 - [4L, 9L, b'\x07\x01\x02'] - """ - def __init__(self, startSeq=None, implicit=None): - """Initialize the DER object as a SEQUENCE. - - :Parameters: - startSeq : Python sequence - A sequence whose element are either integers or - other DER objects. - - implicit : integer - The IMPLICIT tag to use for the encoded object. - It overrides the universal tag for SEQUENCE (16). - """ - - DerObject.__init__(self, 0x10, b(''), implicit, True) + def __init__(self, startSeq=None): + """Initialize the SEQUENCE DER object. Always empty + initially.""" + DerObject.__init__(self, 'SEQUENCE') if startSeq==None: self._seq = [] else: @@ -383,517 +182,105 @@ def __getslice__(self, i, j): return self._seq[max(0, i):max(0, j)] def __len__(self): return len(self._seq) - def __iadd__(self, item): - self._seq.append(item) - return self def append(self, item): - self._seq.append(item) - return self + return self._seq.append(item) - def hasInts(self, onlyNonNegative=True): - """Return the number of items in this sequence that are - integers. - - :Parameters: - onlyNonNegative : boolean - If True, negative integers are not counted in. - """ - def _isInt2(x): - return _isInt(x, onlyNonNegative) - return len(filter(_isInt2, self._seq)) - - def hasOnlyInts(self, onlyNonNegative=True): - """Return True if all items in this sequence are integers - or non-negative integers. - - This function returns False is the sequence is empty, - or at least one member is not an integer. - - :Parameters: - onlyNonNegative : boolean - If True, the presence of negative integers - causes the method to return False.""" - return self._seq and self.hasInts(onlyNonNegative)==len(self._seq) + def hasInts(self): + """Return the number of items in this sequence that are numbers.""" + return len(filter(isInt, self._seq)) + def hasOnlyInts(self): + """Return True if all items in this sequence are numbers.""" + return self._seq and self.hasInts()==len(self._seq) + def encode(self): - """Return this DER SEQUENCE, fully encoded as a - binary string. + """Return the DER encoding for the ASN.1 SEQUENCE, containing + the non-negative integers and longs added to this object. - :Raises ValueError: - If some elements in the sequence are neither integers - nor byte strings. + Limitation: Raises a ValueError exception if it some elements + in the sequence are neither Python integers nor complete DER INTEGERs. """ self.payload = b('') for item in self._seq: - try: - self.payload += item - except TypeError: try: - self.payload += DerInteger(item).encode() - except TypeError: - raise ValueError("Trying to DER encode an unknown object") + self.payload += item + except: + try: + self.payload += DerInteger(item).encode() + except: + raise ValueError("Trying to DER encode an unknown object") return DerObject.encode(self) - def decode(self, derEle): - """Decode a complete DER SEQUENCE, and re-initializes this + def decode(self, derEle, noLeftOvers=0): + """Decode a complete SEQUENCE DER element, and re-initializes this object with it. - :Parameters: - derEle : byte string - A complete SEQUENCE DER element. - - :Raise ValueError: - In case of parsing errors. - :Raise EOFError: - If the DER element is too short. + @param derEle A complete SEQUENCE DER element. It must start with a DER + SEQUENCE tag. + @param noLeftOvers Indicate whether it is acceptable to complete the + parsing of the DER element and find that not all + bytes in derEle have been used. + @return Index of the first unused byte in the given DER element. DER INTEGERs are decoded into Python integers. Any other DER element is not decoded. Its validity is not checked. - """ - DerObject.decode(self, derEle) - def _decodeFromStream(self, s): - """Decode a complete DER SEQUENCE from a file.""" + Raises a ValueError exception if the DER element is not a + valid DER SEQUENCE. + Raises an IndexError exception if the DER element is too short. + """ self._seq = [] - - # Fill up self.payload - DerObject._decodeFromStream(self, s) - - # Add one item at a time to self.seq, by scanning self.payload - p = BytesIO_EOF(self.payload) - while True: - try: - p.setRecord(True) - der = DerObject() - der._decodeFromStream(p) - - # Parse INTEGERs differently - if der._idOctet != 0x02: - self._seq.append(p._recording) - else: - derInt = DerInteger() - derInt.decode(p._recording) - self._seq.append(derInt.value) - - except _NoDerElementError: - break - # end - -def newDerSequence(*der_objs): - """Create a DerSequence object, already initialized with all objects - passed as parameters.""" - - der = DerSequence() - for obj in der_objs: - if isinstance(obj, DerObject): - der += obj.encode() - else: - der += obj - return der + try: + tlvLength = DerObject.decode(self, derEle, noLeftOvers) + if self.typeTag!=self.typeTags['SEQUENCE']: + raise ValueError("Not a DER SEQUENCE.") + # Scan one TLV at once + idx = 0 + while idx>> from Crypto.Util.asn1 import DerOctetString - >>> from binascii import hexlify, unhexlify - >>> os_der = DerOctetString(b'\\xaa') - >>> os_der.payload += b'\\xbb' - >>> print hexlify(os_der.encode()) - - which will show ``0402aabb``, the DER encoding for the byte string - ``b'\\xAA\\xBB'``. - - For decoding: - - >>> s = unhexlify(b'0402aabb') - >>> try: - >>> os_der = DerOctetString() - >>> os_der.decode(s) - >>> print hexlify(os_der.payload) - >>> except (ValueError, EOFError): - >>> print "Not a valid DER OCTET STRING" - - the output will be ``aabb``. - """ - - def __init__(self, value=b(''), implicit=None): - """Initialize the DER object as an OCTET STRING. - - :Parameters: - value : byte string - The initial payload of the object. - If not specified, the payload is empty. + def __init__(self, value = b('')): + DerObject.__init__(self, 'OCTET STRING') + self.payload = value - implicit : integer - The IMPLICIT tag to use for the encoded object. - It overrides the universal tag for OCTET STRING (4). - """ - DerObject.__init__(self, 0x04, value, implicit, False) - -def newDerOctetString(binstring): - """Create a DerOctetString object, already initialized with the binary - string.""" - - if isinstance(binstring, DerObject): - der = DerOctetString(binstring.encode()) - else: - der = DerOctetString(binstring) - return der + def decode(self, derEle, noLeftOvers=0): + p = DerObject.decode(derEle, noLeftOvers) + if not self.isType("OCTET STRING"): + raise ValueError("Not a valid OCTET STRING.") + return p class DerNull(DerObject): - """Class to model a DER NULL element.""" - def __init__(self): - """Initialize the DER object as a NULL.""" - - DerObject.__init__(self, 0x05, b(''), False) + DerObject.__init__(self, 'NULL') class DerObjectId(DerObject): - """Class to model a DER OBJECT ID. - - An example of encoding is: - - >>> from Crypto.Util.asn1 import DerObjectId - >>> from binascii import hexlify, unhexlify - >>> oid_der = DerObjectId("1.2") - >>> oid_der.value += ".840.113549.1.1.1" - >>> print hexlify(oid_der.encode()) - - which will show ``06092a864886f70d010101``, the DER encoding for the - RSA Object Identifier ``1.2.840.113549.1.1.1``. - - For decoding: - - >>> s = unhexlify(b'06092a864886f70d010101') - >>> try: - >>> oid_der = DerObjectId() - >>> oid_der.decode(s) - >>> print oid_der.value - >>> except (ValueError, EOFError): - >>> print "Not a valid DER OBJECT ID" - - the output will be ``1.2.840.113549.1.1.1``. - """ - - def __init__(self, value='', implicit=None): - """Initialize the DER object as an OBJECT ID. - - :Parameters: - value : string - The initial Object Identifier (e.g. "1.2.0.0.6.2"). - implicit : integer - The IMPLICIT tag to use for the encoded object. - It overrides the universal tag for OBJECT ID (6). - """ - DerObject.__init__(self, 0x06, b(''), implicit, False) - self.value = value #: The Object ID, a dot separated list of integers - - def encode(self): - """Return the DER OBJECT ID, fully encoded as a - binary string.""" - - comps = map(int,self.value.split(".")) - if len(comps)<2: - raise ValueError("Not a valid Object Identifier string") - self.payload = bchr(40*comps[0]+comps[1]) - for v in comps[2:]: - enc = [] - while v: - enc.insert(0, (v & 0x7F) | 0x80) - v >>= 7 - enc[-1] &= 0x7F - self.payload += b('').join(map(bchr, enc)) - return DerObject.encode(self) - - def decode(self, derEle): - """Decode a complete DER OBJECT ID, and re-initializes this - object with it. - - :Parameters: - derEle : byte string - A complete DER OBJECT ID. - - :Raise ValueError: - In case of parsing errors. - :Raise EOFError: - If the DER element is too short. - """ - - DerObject.decode(self, derEle) - - def _decodeFromStream(self, s): - """Decode a complete DER OBJECT ID from a file.""" - - # Fill up self.payload - DerObject._decodeFromStream(self, s) - - # Derive self.value from self.payload - p = BytesIO_EOF(self.payload) - comps = list(map(str, divmod(bord(p.read_byte()),40))) - v = 0 - try: - while True: - c = p.read_byte() - v = v*128 + (bord(c) & 0x7F) - if not (bord(c) & 0x80): - comps.append(str(v)) - v = 0 - except EOFError: - pass - self.value = '.'.join(comps) - -def newDerObjectId(dottedstring): - """Create a DerObjectId object, already initialized with the given Object - Identifier (a dotted string).""" - - der = DerObjectId(dottedstring) - return der - -class DerBitString(DerObject): - """Class to model a DER BIT STRING. - - An example of encoding is: - - >>> from Crypto.Util.asn1 import DerBitString - >>> from binascii import hexlify, unhexlify - >>> bs_der = DerBitString(b'\\xaa') - >>> bs_der.value += b'\\xbb' - >>> print hexlify(bs_der.encode()) - - which will show ``040300aabb``, the DER encoding for the bit string - ``b'\\xAA\\xBB'``. - - For decoding: - - >>> s = unhexlify(b'040300aabb') - >>> try: - >>> bs_der = DerBitString() - >>> bs_der.decode(s) - >>> print hexlify(bs_der.value) - >>> except (ValueError, EOFError): - >>> print "Not a valid DER OCTET STRING" - - the output will be ``aabb``. - """ - - def __init__(self, value=b(''), implicit=None): - """Initialize the DER object as a BIT STRING. - - :Parameters: - value : byte string - The initial, packed bit string. - If not specified, the bit string is empty. - implicit : integer - The IMPLICIT tag to use for the encoded object. - It overrides the universal tag for OCTET STRING (3). - """ - DerObject.__init__(self, 0x03, b(''), implicit, False) - self.value = value #: The bitstring value (packed) - - def encode(self): - """Return the DER BIT STRING, fully encoded as a - binary string.""" - - # Add padding count byte - self.payload = b('\x00') + self.value - return DerObject.encode(self) - - def decode(self, derEle): - """Decode a complete DER BIT STRING, and re-initializes this - object with it. - - :Parameters: - derEle : byte string - A complete DER BIT STRING. - - :Raise ValueError: - In case of parsing errors. - :Raise EOFError: - If the DER element is too short. - """ - - DerObject.decode(self, derEle) - - def _decodeFromStream(self, s): - """Decode a complete DER BIT STRING DER from a file.""" - - # Fill-up self.payload - DerObject._decodeFromStream(self, s) - - if self.payload and bord(self.payload[0])!=0: - raise ValueError("Not a valid BIT STRING") - - # Fill-up self.value - self.value = b('') - # Remove padding count byte - if self.payload: - self.value = self.payload[1:] - -def newDerBitString(binstring): - """Create a DerStringString object, already initialized with the binary - string.""" - - if isinstance(binstring, DerObject): - der = DerBitString(binstring.encode()) - else: - der = DerBitString(binstring) - return der - -class DerSetOf(DerObject): - """Class to model a DER SET OF. - - An example of encoding is: - - >>> from Crypto.Util.asn1 import DerBitString - >>> from binascii import hexlify, unhexlify - >>> so_der = DerSetOf([4,5]) - >>> so_der.add(6) - >>> print hexlify(so_der.encode()) - - which will show ``3109020104020105020106``, the DER encoding - of a SET OF with items 4,5, and 6. - - For decoding: - - >>> s = unhexlify(b'3109020104020105020106') - >>> try: - >>> so_der = DerSetOf() - >>> so_der.decode(s) - >>> print [x for x in so_der] - >>> except (ValueError, EOFError): - >>> print "Not a valid DER SET OF" - - the output will be ``[4L, 5L, 6L]``. - """ - - def __init__(self, startSet=None, implicit=None): - """Initialize the DER object as a SET OF. - - :Parameters: - startSet : container - The initial set of integers or DER encoded objects. - implicit : integer - The IMPLICIT tag to use for the encoded object. - It overrides the universal tag for SET OF (17). - """ - DerObject.__init__(self, 0x11, b(''), implicit, True) - self._seq = [] - self._elemOctet = None - if startSet: - for e in startSet: - self.add(e) - - def __getitem__(self, n): - return self._seq[n] - - def __iter__(self): - return iter(self._seq) - - def __len__(self): - return len(self._seq) - - def add(self, elem): - """Add an element to the set. - - :Parameters: - elem : byte string or integer - An element of the same type of objects already in the set. - It can be an integer or a DER encoded object. - """ - if _isInt(elem): - eo = 0x02 - else: - eo = bord(elem[0]) - if self._elemOctet != eo: - if self._elemOctet: - raise ValueError("New element does not belong to the set") - self._elemOctet = eo - if not elem in self._seq: - self._seq.append(elem) - - def decode(self, derEle): - """Decode a complete SET OF DER element, and re-initializes this - object with it. - - DER INTEGERs are decoded into Python integers. Any other DER - element is left undecoded; its validity is not checked. - - :Parameters: - derEle : byte string - A complete DER BIT SET OF. - - :Raise ValueError: - In case of parsing errors. - :Raise EOFError: - If the DER element is too short. - """ - - DerObject.decode(self, derEle) - - def _decodeFromStream(self, s): - """Decode a complete DER SET OF from a file.""" - - self._seq = [] - - # Fill up self.payload - DerObject._decodeFromStream(self, s) - - # Add one item at a time to self.seq, by scanning self.payload - p = BytesIO_EOF(self.payload) - setIdOctet = -1 - while True: - try: - p.setRecord(True) - der = DerObject() - der._decodeFromStream(p) - - # Verify that all members are of the same type - if setIdOctet < 0: - setIdOctet = der._idOctet - else: - if setIdOctet != der._idOctet: - raise ValueError("Not all elements are of the same DER type") - - # Parse INTEGERs differently - if setIdOctet != 0x02: - self._seq.append(p._recording) - else: - derInt = DerInteger() - derInt.decode(p._recording) - self._seq.append(derInt.value) + def __init__(self): + DerObject.__init__(self, 'OBJECT IDENTIFIER') - except _NoDerElementError: - break - # end + def decode(self, derEle, noLeftOvers=0): + p = DerObject.decode(derEle, noLeftOvers) + if not self.isType("OBJECT IDENTIFIER"): + raise ValueError("Not a valid OBJECT IDENTIFIER.") + return p - def encode(self): - """Return this SET OF DER element, fully encoded as a - binary string. - """ +def isInt(x): + test = 0 + try: + test += x + except TypeError: + return 0 + return 1 - # Elements in the set must be ordered in lexicographic order - ordered = [] - for item in self._seq: - if _isInt(item): - bys = DerInteger(item).encode() - else: - bys = item - ordered.append(bys) - ordered.sort() - self.payload = b('').join(ordered) - return DerObject.encode(self) - -def newDerSetOf(*der_objs): - """Create a DerSequence object, already initialized with all objects - passed as parameters.""" - - der = DerSetOf() - for obj in der_objs: - if isinstance(obj, DerObject): - der.add(obj.encode()) - else: - der.add(obj) - return der diff --git a/lib/Crypto/Util/py21compat.py b/lib/Crypto/Util/py21compat.py index 658fd363..624408bd 100644 --- a/lib/Crypto/Util/py21compat.py +++ b/lib/Crypto/Util/py21compat.py @@ -81,21 +81,4 @@ def isinstance(obj, t): return True return False -# -# Python 2.2 introduces the built-in staticmethod(). Python 2.4 turns -# it into a function decorator (@staticmethod). -# -# The following recipe for achieving the same thing in Python 2.1 comes -# from the Python Cookbok ("Implementanting Static Methods"). -# -try: - class A: - def a(): pass - a = staticmethod(a) -except NameError: - class staticmethod: - def __init__(self, anycallable): - self.__call__ = anycallable - __all__ += ['staticmethod'] - # vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/lib/Crypto/Util/py3compat.py b/lib/Crypto/Util/py3compat.py index 7aa2bee5..34e5224f 100644 --- a/lib/Crypto/Util/py3compat.py +++ b/lib/Crypto/Util/py3compat.py @@ -63,8 +63,6 @@ import sys if sys.version_info[0] == 2: - from types import UnicodeType as _UnicodeType # In Python 2.1, 'unicode' is a function, not a type. - def b(s): return s def bchr(s): @@ -73,15 +71,18 @@ def bstr(s): return str(s) def bord(s): return ord(s) - def tobytes(s): - if isinstance(s, _UnicodeType): - return s.encode("latin-1") - else: - return ''.join(s) - def tostr(bs): - return unicode(bs, 'latin-1') - # In Pyton 2.x, StringIO is a stand-alone module - from StringIO import StringIO as BytesIO + if sys.version_info[1] == 1: + def tobytes(s): + try: + return s.encode('latin-1') + except: + return ''.join(s) + else: + def tobytes(s): + if isinstance(s, unicode): + return s.encode("latin-1") + else: + return ''.join(s) else: def b(s): return s.encode("latin-1") # utf-8 would cause some side-effects we don't want @@ -102,9 +103,5 @@ def tobytes(s): return s.encode("latin-1") else: return bytes(s) - def tostr(bs): - return bs.decode("latin-1") - # In Pyton 3.x, StringIO is a sub-module of io - from io import BytesIO - + # vim:set ts=4 sw=4 sts=4 expandtab: diff --git a/lib/Crypto/__init__.py b/lib/Crypto/__init__.py index c27402e3..46121db1 100644 --- a/lib/Crypto/__init__.py +++ b/lib/Crypto/__init__.py @@ -43,7 +43,7 @@ __all__ = ['Cipher', 'Hash', 'Protocol', 'PublicKey', 'Util', 'Signature'] -__version__ = '2.6.1' # See also below and setup.py +__version__ = '2.6.1.post2' # See also below and setup.py __revision__ = "$Id$" # New software should look at this instead of at __version__ above. diff --git a/lib/Crypto/pct_warnings.py b/lib/Crypto/pct_warnings.py index d6adc5bb..9b4361e4 100644 --- a/lib/Crypto/pct_warnings.py +++ b/lib/Crypto/pct_warnings.py @@ -49,9 +49,6 @@ class ClockRewindWarning(CryptoRuntimeWarning): class GetRandomNumber_DeprecationWarning(CryptoDeprecationWarning): """Issued when Crypto.Util.number.getRandomNumber is invoked.""" -class DisableShortcut_DeprecationWarning(CryptoDeprecationWarning): - """Issued when Counter.new(disable_shortcut=...) is invoked.""" - class PowmInsecureWarning(CryptoRuntimeWarning): """Warning for when _fastmath is built without mpz_powm_sec""" diff --git a/pct-speedtest.py b/pct-speedtest.py index c7b893a8..daed1052 100644 --- a/pct-speedtest.py +++ b/pct-speedtest.py @@ -28,61 +28,31 @@ import sys from Crypto.PublicKey import RSA -from Crypto.Cipher import PKCS1_OAEP, PKCS1_v1_5 as RSAES_PKCS1_v1_5 -from Crypto.Signature import PKCS1_PSS, PKCS1_v1_5 as RSASSA_PKCS1_v1_5 from Crypto.Cipher import AES, ARC2, ARC4, Blowfish, CAST, DES3, DES, XOR -from Crypto.Hash import HMAC, MD2, MD4, MD5, SHA224, SHA256, SHA384, SHA512, CMAC -from Crypto.Random import get_random_bytes -import Crypto.Util.Counter -from Crypto.Util.number import bytes_to_long +from Crypto.Hash import MD2, MD4, MD5, SHA256, SHA try: - from Crypto.Hash import SHA1 -except ImportError: - # Maybe it's called SHA - from Crypto.Hash import SHA as SHA1 -try: - from Crypto.Hash import RIPEMD160 -except ImportError: - # Maybe it's called RIPEMD - try: - from Crypto.Hash import RIPEMD as RIPEMD160 - except ImportError: - # Some builds of PyCrypto don't have the RIPEMD module - RIPEMD160 = None - -try: - import hashlib - import hmac -except ImportError: # Some builds/versions of Python don't have a hashlib module - hashlib = hmac = None - -# os.urandom() is less noisy when profiling, but it doesn't exist in Python < 2.4 -try: - urandom = os.urandom -except AttributeError: - urandom = get_random_bytes - -from Crypto.Random import random as pycrypto_random -import random as stdlib_random + from Crypto.Hash import RIPEMD +except ImportError: # Some builds of PyCrypto don't have the RIPEMD module + RIPEMD = None class Benchmark: def __init__(self): self.__random_data = None - def random_keys(self, bytes, n=10**5): + def random_keys(self, bytes): """Return random keys of the specified number of bytes. If this function has been called before with the same number of bytes, cached keys are used instead of randomly generating new ones. """ - return self.random_blocks(bytes, n) + return self.random_blocks(bytes, 10**5) # 100k def random_blocks(self, bytes_per_block, blocks): bytes = bytes_per_block * blocks data = self.random_data(bytes) retval = [] - for i in range(blocks): + for i in xrange(blocks): p = i * bytes_per_block retval.append(data[p:p+bytes_per_block]) return retval @@ -100,7 +70,7 @@ def random_data(self, bytes): return self.__random_data def _random_bytes(self, b): - return urandom(b) + return os.urandom(b) def announce_start(self, test_name): sys.stdout.write("%s: " % (test_name,)) @@ -110,16 +80,6 @@ def announce_result(self, value, units): sys.stdout.write("%.2f %s\n" % (value, units)) sys.stdout.flush() - def test_random_module(self, module_name, module): - self.announce_start("%s.choice" % (module_name,)) - alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" - t0 = time.time() - for i in range(5000): - module.choice(alphabet) - t = time.time() - invocations_per_second = 5000 / (t - t0) - self.announce_result(invocations_per_second, "invocations/sec") - def test_pubkey_setup(self, pubkey_name, module, key_bytes): self.announce_start("%s pubkey setup" % (pubkey_name,)) keys = self.random_keys(key_bytes)[:5] @@ -135,12 +95,7 @@ def test_key_setup(self, cipher_name, module, key_bytes, mode): self.announce_start("%s key setup" % (cipher_name,)) # Generate random keys for use with the tests - keys = self.random_keys(key_bytes, n=5000) - - if hasattr(module, "MODE_CCM") and mode==module.MODE_CCM: - iv = b"\xAA"*8 - else: - iv = b"\xAA"*module.block_size + keys = self.random_keys(key_bytes) # Perform key setups if mode is None: @@ -150,15 +105,8 @@ def test_key_setup(self, cipher_name, module, key_bytes, mode): t = time.time() else: t0 = time.time() - - if mode==module.MODE_CTR: - for k in keys: - ctr = Crypto.Util.Counter.new(module.block_size*8, - initial_value=bytes_to_long(iv)) - module.new(k, module.MODE_CTR, counter=ctr) - else: - for k in keys: - module.new(k, mode, iv) + for k in keys: + module.new(k, module.MODE_ECB) t = time.time() key_setups_per_second = len(keys) / (t - t0) @@ -173,21 +121,6 @@ def test_encryption(self, cipher_name, module, key_bytes, mode): blocks = self.random_blocks(16384, 1000) if mode is None: cipher = module.new(key) - elif mode == "CTR-BE": - from Crypto.Util import Counter - cipher = module.new(key, module.MODE_CTR, counter=Counter.new(module.block_size*8, little_endian=False)) - elif mode == "CTR-LE": - from Crypto.Util import Counter - cipher = module.new(key, module.MODE_CTR, counter=Counter.new(module.block_size*8, little_endian=True)) - elif hasattr(module, 'MODE_CCM') and mode==module.MODE_CCM: - cipher = module.new(key, mode, iv[:8], msg_len=len(rand)*len(blocks)) - elif mode==module.MODE_CTR: - ctr = Crypto.Util.Counter.new(module.block_size*8, - initial_value=bytes_to_long(iv), - allow_wraparound=True) - cipher = module.new(key, module.MODE_CTR, counter=ctr) - elif mode==module.MODE_ECB: - cipher = module.new(key, module.MODE_ECB) else: cipher = module.new(key, mode, iv) @@ -200,28 +133,28 @@ def test_encryption(self, cipher_name, module, key_bytes, mode): encryption_speed = (len(blocks) * len(blocks[0])) / (t - t0) self.announce_result(encryption_speed / 10**6, "MBps") - def test_hash_small(self, hash_name, hash_constructor, digest_size): - self.announce_start("%s (%d-byte inputs)" % (hash_name, digest_size)) + def test_hash_small(self, hash_name, module): + self.announce_start("%s (%d-byte inputs)" % (hash_name, module.digest_size)) - blocks = self.random_blocks(digest_size, 10000) + blocks = self.random_blocks(module.digest_size, 10000) # Initialize hashes t0 = time.time() for b in blocks: - hash_constructor(b).digest() + module.new(b).digest() t = time.time() hashes_per_second = len(blocks) / (t - t0) self.announce_result(hashes_per_second / 1000, "kHashes/sec") - def test_hash_large(self, hash_name, hash_constructor, digest_size): + def test_hash_large(self, hash_name, module): self.announce_start("%s (single large input)" % (hash_name,)) blocks = self.random_blocks(16384, 10000) # Perform hashing t0 = time.time() - h = hash_constructor() + h = module.new() for b in blocks: h.update(b) h.digest() @@ -230,90 +163,11 @@ def test_hash_large(self, hash_name, hash_constructor, digest_size): hash_speed = len(blocks) * len(blocks[0]) / (t - t0) self.announce_result(hash_speed / 10**6, "MBps") - def test_hmac_small(self, mac_name, hmac_constructor, digestmod, digest_size): - keys = iter(self.random_keys(digest_size)) - if sys.version_info[0] == 2: - mac_constructor = lambda data=None: hmac_constructor(keys.next(), data, digestmod) - else: - mac_constructor = lambda data=None: hmac_constructor(keys.__next__(), data, digestmod) - self.test_hash_small(mac_name, mac_constructor, digest_size) - - def test_hmac_large(self, mac_name, hmac_constructor, digestmod, digest_size): - key = self.random_keys(digest_size)[0] - mac_constructor = lambda data=None: hmac_constructor(key, data, digestmod) - self.test_hash_large(mac_name, mac_constructor, digest_size) - - def test_cmac_small(self, mac_name, cmac_constructor, ciphermod, key_size): - keys = iter(self.random_keys(key_size)) - if sys.version_info[0] == 2: - mac_constructor = lambda data=None: cmac_constructor(keys.next(), data, ciphermod) - else: - mac_constructor = lambda data=None: cmac_constructor(keys.__next__(), data, ciphermod) - self.test_hash_small(mac_name, mac_constructor, ciphermod.block_size) - - def test_cmac_large(self, mac_name, cmac_constructor, ciphermod, key_size): - key = self.random_keys(key_size)[0] - mac_constructor = lambda data=None: cmac_constructor(key, data, ciphermod) - self.test_hash_large(mac_name, mac_constructor, ciphermod.block_size) - - def test_pkcs1_sign(self, scheme_name, scheme_constructor, hash_name, hash_constructor, digest_size): - self.announce_start("%s signing %s (%d-byte inputs)" % (scheme_name, hash_name, digest_size)) - - # Make a key - k = RSA.generate(2048) - sigscheme = scheme_constructor(k) - - # Make some hashes - blocks = self.random_blocks(digest_size, 50) - hashes = [] - for b in blocks: - hashes.append(hash_constructor(b)) - - # Perform signing - t0 = time.time() - for h in hashes: - sigscheme.sign(h) - t = time.time() - - speed = len(hashes) / (t - t0) - self.announce_result(speed, "sigs/sec") - - def test_pkcs1_verify(self, scheme_name, scheme_constructor, hash_name, hash_constructor, digest_size): - self.announce_start("%s verification %s (%d-byte inputs)" % (scheme_name, hash_name, digest_size)) - - # Make a key - k = RSA.generate(2048) - sigscheme = scheme_constructor(k) - - # Make some hashes - blocks = self.random_blocks(digest_size, 50) - hashes = [] - for b in blocks: - hashes.append(hash_constructor(b)) - - # Make some signatures - signatures = [] - for h in hashes: - signatures.append(sigscheme.sign(h)) - - # Double the list, to make timing better - hashes = hashes + hashes - signatures = signatures + signatures - - # Perform verification - t0 = time.time() - for h, s in zip(hashes, signatures): - sigscheme.verify(h, s) - t = time.time() - - speed = len(hashes) / (t - t0) - self.announce_result(speed, "sigs/sec") - def run(self): pubkey_specs = [ - ("RSA(1024)", RSA, int(1024/8)), - ("RSA(2048)", RSA, int(2048/8)), - ("RSA(4096)", RSA, int(4096/8)), + ("RSA(1024)", RSA, 1024/8), + ("RSA(2048)", RSA, 2048/8), + ("RSA(4096)", RSA, 4096/8), ] block_specs = [ ("DES", DES, 8), @@ -336,106 +190,30 @@ def run(self): ("MD2", MD2), ("MD4", MD4), ("MD5", MD5), - ("SHA1", SHA1), - ("SHA224", SHA224), + ("SHA", SHA), ("SHA256", SHA256), - ("SHA384", SHA384), - ("SHA512", SHA512), ] - if RIPEMD160 is not None: - hash_specs += [("RIPEMD160", RIPEMD160)] + if RIPEMD is not None: + hash_specs += [("RIPEMD", RIPEMD)] - hashlib_specs = [] - if hashlib is not None: - if hasattr(hashlib, 'md5'): hashlib_specs.append(("hashlib.md5", hashlib.md5)) - if hasattr(hashlib, 'sha1'): hashlib_specs.append(("hashlib.sha1", hashlib.sha1)) - if hasattr(hashlib, 'sha224'): hashlib_specs.append(("hashlib.sha224", hashlib.sha224)) - if hasattr(hashlib, 'sha256'): hashlib_specs.append(("hashlib.sha256", hashlib.sha256)) - if hasattr(hashlib, 'sha384'): hashlib_specs.append(("hashlib.sha384", hashlib.sha384)) - if hasattr(hashlib, 'sha512'): hashlib_specs.append(("hashlib.sha512", hashlib.sha512)) - - # stdlib random - self.test_random_module("stdlib random", stdlib_random) - - # Crypto.Random.random - self.test_random_module("Crypto.Random.random", pycrypto_random) - - # Crypto.PublicKey for pubkey_name, module, key_bytes in pubkey_specs: self.test_pubkey_setup(pubkey_name, module, key_bytes) - # Crypto.Cipher (block ciphers) for cipher_name, module, key_bytes in block_specs: - self.test_key_setup("%s-CBC" % (cipher_name,), module, key_bytes, module.MODE_CBC) + self.test_key_setup(cipher_name, module, key_bytes, module.MODE_CBC) self.test_encryption("%s-CBC" % (cipher_name,), module, key_bytes, module.MODE_CBC) self.test_encryption("%s-CFB-8" % (cipher_name,), module, key_bytes, module.MODE_CFB) self.test_encryption("%s-OFB" % (cipher_name,), module, key_bytes, module.MODE_OFB) self.test_encryption("%s-ECB" % (cipher_name,), module, key_bytes, module.MODE_ECB) - - self.test_key_setup("%s-CTR" % (cipher_name,), module, key_bytes, module.MODE_CTR) - self.test_encryption("%s-CTR" % (cipher_name,), module, key_bytes, module.MODE_CTR) - self.test_encryption("%s-OPENPGP" % (cipher_name,), module, key_bytes, module.MODE_OPENPGP) - self.test_encryption("%s-CTR-BE" % (cipher_name,), module, key_bytes, "CTR-BE") - self.test_encryption("%s-CTR-LE" % (cipher_name,), module, key_bytes, "CTR-LE") - - if hasattr(module, "MODE_CCM"): - self.test_key_setup("%s-CCM" % (cipher_name,), module, key_bytes, module.MODE_CCM) - self.test_encryption("%s-CCM" % (cipher_name,), module, key_bytes, module.MODE_CCM) - - if hasattr(module, "MODE_EAX"): - self.test_key_setup("%s-EAX" % (cipher_name,), module, key_bytes, module.MODE_EAX) - self.test_encryption("%s-EAX" % (cipher_name,), module, key_bytes, module.MODE_EAX) - if hasattr(module, "MODE_GCM"): - self.test_key_setup("%s-GCM" % (cipher_name,), module, key_bytes, module.MODE_GCM) - self.test_encryption("%s-GCM" % (cipher_name,), module, key_bytes, module.MODE_GCM) - - # Crypto.Cipher (stream ciphers) for cipher_name, module, key_bytes in stream_specs: self.test_key_setup(cipher_name, module, key_bytes, None) self.test_encryption(cipher_name, module, key_bytes, None) - # Crypto.Hash - for hash_name, module in hash_specs: - self.test_hash_small(hash_name, module.new, module.digest_size) - self.test_hash_large(hash_name, module.new, module.digest_size) - - # standard hashlib - for hash_name, func in hashlib_specs: - self.test_hash_small(hash_name, func, func().digest_size) - self.test_hash_large(hash_name, func, func().digest_size) - - # PyCrypto HMAC - for hash_name, module in hash_specs: - self.test_hmac_small("HMAC-"+hash_name, HMAC.new, module, module.digest_size) - self.test_hmac_large("HMAC-"+hash_name, HMAC.new, module, module.digest_size) - - # standard hmac + hashlib - for hash_name, func in hashlib_specs: - self.test_hmac_small("hmac+"+hash_name, hmac.HMAC, func, func().digest_size) - self.test_hmac_large("hmac+"+hash_name, hmac.HMAC, func, func().digest_size) - - # CMAC - for cipher_name, module, key_size in (("AES128", AES, 16),): - self.test_cmac_small(cipher_name+"-CMAC", CMAC.new, module, key_size) - self.test_cmac_large(cipher_name+"-CMAC", CMAC.new, module, key_size) - - # PKCS1_v1_5 (sign) + Crypto.Hash - for hash_name, module in hash_specs: - self.test_pkcs1_sign("PKCS#1-v1.5", RSASSA_PKCS1_v1_5.new, hash_name, module.new, module.digest_size) - - # PKCS1_PSS (sign) + Crypto.Hash - for hash_name, module in hash_specs: - self.test_pkcs1_sign("PKCS#1-PSS", PKCS1_PSS.new, hash_name, module.new, module.digest_size) - - # PKCS1_v1_5 (verify) + Crypto.Hash - for hash_name, module in hash_specs: - self.test_pkcs1_verify("PKCS#1-v1.5", RSASSA_PKCS1_v1_5.new, hash_name, module.new, module.digest_size) - - # PKCS1_PSS (verify) + Crypto.Hash for hash_name, module in hash_specs: - self.test_pkcs1_verify("PKCS#1-PSS", PKCS1_PSS.new, hash_name, module.new, module.digest_size) + self.test_hash_small(hash_name, module) + self.test_hash_large(hash_name, module) if __name__ == '__main__': Benchmark().run() diff --git a/pyproject.toml b/pyproject.toml index 86bc9ae0..e5d3c571 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "pycrypto" -version = "2.6.1" +version = "2.6.1.post2" description = "Cryptographic modules for Python." authors = ["Darsey Litzenberger "] license = "Public Domain" diff --git a/src/AES.c b/src/AES.c index 1e705daf..0aeaeda7 100644 --- a/src/AES.c +++ b/src/AES.c @@ -24,9 +24,9 @@ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "pycrypto_common.h" #include #include +#include "Python.h" #define MODULE_NAME _AES #define BLOCK_SIZE 16 @@ -36,9 +36,9 @@ #define MAXKB (256/8) #define MAXNR 14 -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned int u32; typedef struct { u32 ek[ 4*(MAXNR+1) ]; @@ -1446,10 +1446,6 @@ static void block_init(block_state *state, unsigned char *key, rijndaelKeySetupDec(state->dk, key, keylen*8); } -static void block_finalize(block_state* self) -{ -} - static void block_encrypt(block_state *self, u8 *in, u8 *out) { rijndaelEncrypt(self->ek, self->rounds, in, out); diff --git a/src/AESNI.c b/src/AESNI.c deleted file mode 100644 index 3f1e061f..00000000 --- a/src/AESNI.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * AESNI.c: AES using AES-NI instructions - * - * Written in 2013 by Sebastian Ramacher - * - * =================================================================== - * The contents of this file are dedicated to the public domain. To - * the extent that dedication to the public domain is not available, - * everyone is granted a worldwide, perpetual, royalty-free, - * non-exclusive license to exercise all rights associated with the - * contents of this file for any purpose whatsoever. - * No rights are reserved. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * =================================================================== - */ - -#include "pycrypto_common.h" -#include -#include -#if defined(HAVE__ALIGNED_MALLOC) -#include -#endif - -#define MODULE_NAME _AESNI -#define BLOCK_SIZE 16 -#define KEY_SIZE 0 - -#define MAXKC (256/32) -#define MAXKB (256/8) -#define MAXNR 14 - -typedef unsigned char u8; - -typedef struct { - __m128i* ek; - __m128i* dk; - int rounds; -} block_state; - -/* Wrapper functions for malloc and free with memory alignment */ -#if defined(HAVE_ALIGNED_ALLOC) /* aligned_alloc is defined by C11 */ -# define aligned_malloc_wrapper aligned_alloc -# define aligned_free_wrapper free -#elif defined(HAVE_POSIX_MEMALIGN) /* posix_memalign is defined by POSIX */ -static void* aligned_malloc_wrapper(size_t alignment, size_t size) -{ - void* tmp = NULL; - int err = posix_memalign(&tmp, alignment, size); - if (err != 0) { - /* posix_memalign does NOT set errno on failure; the error is returned */ - errno = err; - return NULL; - } - return tmp; -} -# define aligned_free_wrapper free -#elif defined(HAVE__ALIGNED_MALLOC) /* _aligned_malloc is available on Windows */ -static void* aligned_malloc_wrapper(size_t alignment, size_t size) -{ - /* NB: _aligned_malloc takes its args in the opposite order from aligned_alloc */ - return _aligned_malloc(size, alignment); -} -# define aligned_free_wrapper _aligned_free -#else -# error "No function to allocate/free aligned memory is available." -#endif - -/* Helper functions to expand keys */ - -static __m128i aes128_keyexpand(__m128i key) -{ - key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); - key = _mm_xor_si128(key, _mm_slli_si128(key, 4)); - return _mm_xor_si128(key, _mm_slli_si128(key, 4)); -} - -static __m128i aes192_keyexpand_2(__m128i key, __m128i key2) -{ - key = _mm_shuffle_epi32(key, 0xff); - key2 = _mm_xor_si128(key2, _mm_slli_si128(key2, 4)); - return _mm_xor_si128(key, key2); -} - -#define KEYEXP128_H(K1, K2, I, S) _mm_xor_si128(aes128_keyexpand(K1), \ - _mm_shuffle_epi32(_mm_aeskeygenassist_si128(K2, I), S)) - -#define KEYEXP128(K, I) KEYEXP128_H(K, K, I, 0xff) -#define KEYEXP192(K1, K2, I) KEYEXP128_H(K1, K2, I, 0x55) -#define KEYEXP192_2(K1, K2) aes192_keyexpand_2(K1, K2) -#define KEYEXP256(K1, K2, I) KEYEXP128_H(K1, K2, I, 0xff) -#define KEYEXP256_2(K1, K2) KEYEXP128_H(K1, K2, 0x00, 0xaa) - -/* Encryption key setup */ -static void aes_key_setup_enc(__m128i rk[], const u8* cipherKey, int keylen) -{ - switch (keylen) { - case 16: - { - /* 128 bit key setup */ - rk[0] = _mm_loadu_si128((const __m128i*) cipherKey); - rk[1] = KEYEXP128(rk[0], 0x01); - rk[2] = KEYEXP128(rk[1], 0x02); - rk[3] = KEYEXP128(rk[2], 0x04); - rk[4] = KEYEXP128(rk[3], 0x08); - rk[5] = KEYEXP128(rk[4], 0x10); - rk[6] = KEYEXP128(rk[5], 0x20); - rk[7] = KEYEXP128(rk[6], 0x40); - rk[8] = KEYEXP128(rk[7], 0x80); - rk[9] = KEYEXP128(rk[8], 0x1B); - rk[10] = KEYEXP128(rk[9], 0x36); - break; - } - case 24: - { - /* 192 bit key setup */ - __m128i temp[2]; - rk[0] = _mm_loadu_si128((const __m128i*) cipherKey); - rk[1] = _mm_loadu_si128((const __m128i*) (cipherKey+16)); - temp[0] = KEYEXP192(rk[0], rk[1], 0x01); - temp[1] = KEYEXP192_2(temp[0], rk[1]); - rk[1] = (__m128i)_mm_shuffle_pd((__m128d)rk[1], (__m128d)temp[0], 0); - rk[2] = (__m128i)_mm_shuffle_pd((__m128d)temp[0], (__m128d)temp[1], 1); - rk[3] = KEYEXP192(temp[0], temp[1], 0x02); - rk[4] = KEYEXP192_2(rk[3], temp[1]); - temp[0] = KEYEXP192(rk[3], rk[4], 0x04); - temp[1] = KEYEXP192_2(temp[0], rk[4]); - rk[4] = (__m128i)_mm_shuffle_pd((__m128d)rk[4], (__m128d)temp[0], 0); - rk[5] = (__m128i)_mm_shuffle_pd((__m128d)temp[0], (__m128d)temp[1], 1); - rk[6] = KEYEXP192(temp[0], temp[1], 0x08); - rk[7] = KEYEXP192_2(rk[6], temp[1]); - temp[0] = KEYEXP192(rk[6], rk[7], 0x10); - temp[1] = KEYEXP192_2(temp[0], rk[7]); - rk[7] = (__m128i)_mm_shuffle_pd((__m128d)rk[7], (__m128d)temp[0], 0); - rk[8] = (__m128i)_mm_shuffle_pd((__m128d)temp[0], (__m128d)temp[1], 1); - rk[9] = KEYEXP192(temp[0], temp[1], 0x20); - rk[10] = KEYEXP192_2(rk[9], temp[1]); - temp[0] = KEYEXP192(rk[9], rk[10], 0x40); - temp[1] = KEYEXP192_2(temp[0], rk[10]); - rk[10] = (__m128i)_mm_shuffle_pd((__m128d)rk[10], (__m128d) temp[0], 0); - rk[11] = (__m128i)_mm_shuffle_pd((__m128d)temp[0],(__m128d) temp[1], 1); - rk[12] = KEYEXP192(temp[0], temp[1], 0x80); - break; - } - case 32: - { - /* 256 bit key setup */ - rk[0] = _mm_loadu_si128((const __m128i*) cipherKey); - rk[1] = _mm_loadu_si128((const __m128i*) (cipherKey+16)); - rk[2] = KEYEXP256(rk[0], rk[1], 0x01); - rk[3] = KEYEXP256_2(rk[1], rk[2]); - rk[4] = KEYEXP256(rk[2], rk[3], 0x02); - rk[5] = KEYEXP256_2(rk[3], rk[4]); - rk[6] = KEYEXP256(rk[4], rk[5], 0x04); - rk[7] = KEYEXP256_2(rk[5], rk[6]); - rk[8] = KEYEXP256(rk[6], rk[7], 0x08); - rk[9] = KEYEXP256_2(rk[7], rk[8]); - rk[10] = KEYEXP256(rk[8], rk[9], 0x10); - rk[11] = KEYEXP256_2(rk[9], rk[10]); - rk[12] = KEYEXP256(rk[10], rk[11], 0x20); - rk[13] = KEYEXP256_2(rk[11], rk[12]); - rk[14] = KEYEXP256(rk[12], rk[13], 0x40); - break; - } - } -} - -/* Decryption key setup */ -static void aes_key_setup_dec(__m128i dk[], const __m128i ek[], int rounds) -{ - dk[rounds] = ek[0]; - for (int i = 1; i < rounds; ++i) { - dk[rounds - i] = _mm_aesimc_si128(ek[i]); - } - dk[0] = ek[rounds]; -} - -static void block_init(block_state* self, unsigned char* key, int keylen) -{ - int nr = 0; - switch (keylen) { - case 16: nr = 10; break; - case 24: nr = 12; break; - case 32: nr = 14; break; - default: - PyErr_SetString(PyExc_ValueError, - "AES key must be either 16, 24, or 32 bytes long"); - return; - } - - /* ensure that self->ek and self->dk are aligned to 16 byte boundaries */ - void* tek = aligned_malloc_wrapper(16, (nr + 1) * sizeof(__m128i)); - void* tdk = aligned_malloc_wrapper(16, (nr + 1) * sizeof(__m128i)); - if (!tek || !tdk) { - aligned_free_wrapper(tek); - aligned_free_wrapper(tdk); - PyErr_SetString(PyExc_MemoryError, - "failed to allocate memory for keys"); - return; - } - - self->ek = tek; - self->dk = tdk; - - self->rounds = nr; - aes_key_setup_enc(self->ek, key, keylen); - aes_key_setup_dec(self->dk, self->ek, nr); -} - -static void block_finalize(block_state* self) -{ - /* overwrite contents of ek and dk */ - memset(self->ek, 0, (self->rounds + 1) * sizeof(__m128i)); - memset(self->dk, 0, (self->rounds + 1) * sizeof(__m128i)); - - aligned_free_wrapper(self->ek); - aligned_free_wrapper(self->dk); -} - -static void block_encrypt(block_state* self, const u8* in, u8* out) -{ - __m128i m = _mm_loadu_si128((const __m128i*) in); - /* first 9 rounds */ - m = _mm_xor_si128(m, self->ek[0]); - m = _mm_aesenc_si128(m, self->ek[1]); - m = _mm_aesenc_si128(m, self->ek[2]); - m = _mm_aesenc_si128(m, self->ek[3]); - m = _mm_aesenc_si128(m, self->ek[4]); - m = _mm_aesenc_si128(m, self->ek[5]); - m = _mm_aesenc_si128(m, self->ek[6]); - m = _mm_aesenc_si128(m, self->ek[7]); - m = _mm_aesenc_si128(m, self->ek[8]); - m = _mm_aesenc_si128(m, self->ek[9]); - if (self->rounds != 10) { - /* two additional rounds for AES-192/256 */ - m = _mm_aesenc_si128(m, self->ek[10]); - m = _mm_aesenc_si128(m, self->ek[11]); - if (self->rounds == 14) { - /* another two additional rounds for AES-256 */ - m = _mm_aesenc_si128(m, self->ek[12]); - m = _mm_aesenc_si128(m, self->ek[13]); - } - } - m = _mm_aesenclast_si128(m, self->ek[self->rounds]); - _mm_storeu_si128((__m128i*) out, m); -} - -static void block_decrypt(block_state* self, const u8* in, u8* out) -{ - __m128i m = _mm_loadu_si128((const __m128i*) in); - /* first 9 rounds */ - m = _mm_xor_si128(m, self->dk[0]); - m = _mm_aesdec_si128(m, self->dk[1]); - m = _mm_aesdec_si128(m, self->dk[2]); - m = _mm_aesdec_si128(m, self->dk[3]); - m = _mm_aesdec_si128(m, self->dk[4]); - m = _mm_aesdec_si128(m, self->dk[5]); - m = _mm_aesdec_si128(m, self->dk[6]); - m = _mm_aesdec_si128(m, self->dk[7]); - m = _mm_aesdec_si128(m, self->dk[8]); - m = _mm_aesdec_si128(m, self->dk[9]); - if (self->rounds != 10) { - /* two additional rounds for AES-192/256 */ - m = _mm_aesdec_si128(m, self->dk[10]); - m = _mm_aesdec_si128(m, self->dk[11]); - if (self->rounds == 14) { - /* another two additional rounds for AES-256 */ - m = _mm_aesdec_si128(m, self->dk[12]); - m = _mm_aesdec_si128(m, self->dk[13]); - } - } - m = _mm_aesdeclast_si128(m, self->dk[self->rounds]); - _mm_storeu_si128((__m128i*) out, m); -} - -#include "block_template.c" diff --git a/src/ARC2.c b/src/ARC2.c index 71858f68..49b5dafd 100644 --- a/src/ARC2.c +++ b/src/ARC2.c @@ -41,17 +41,17 @@ * */ -#include "pycrypto_common.h" -#include +#include +#include "Python.h" #define MODULE_NAME _ARC2 #define BLOCK_SIZE 8 #define KEY_SIZE 0 #define PCT_ARC2_MODULE /* Defined to get ARC2's additional keyword arguments */ -typedef uint32_t U32; -typedef uint16_t U16; -typedef uint8_t U8; +typedef unsigned int U32; +typedef unsigned short U16; +typedef unsigned char U8; typedef struct { @@ -216,9 +216,5 @@ block_init(block_state *self, U8 *key, int keylength) } while (i--); } -static void -block_finalize(block_state* self) -{ -} #include "block_template.c" diff --git a/src/ARC4.c b/src/ARC4.c index a125fabf..28dc4a36 100644 --- a/src/ARC4.c +++ b/src/ARC4.c @@ -26,8 +26,6 @@ * */ -#include "pycrypto_common.h" - #define MODULE_NAME _ARC4 #define BLOCK_SIZE 1 #define KEY_SIZE 0 diff --git a/src/Blowfish.c b/src/Blowfish.c index f1ab55a0..94562bb1 100644 --- a/src/Blowfish.c +++ b/src/Blowfish.c @@ -26,10 +26,19 @@ * http://www.schneier.com/paper-blowfish-fse.html */ -#include "pycrypto_common.h" -#include "Blowfish-tables.h" +#include "config.h" +#if HAVE_STDINT_H +# include +#elif defined(__sun) || defined(__sun__) +# include +#else +# error "stdint.h not found" +#endif #include #include +#include "Python.h" + +#include "Blowfish-tables.h" #define MODULE_NAME _Blowfish #define BLOCK_SIZE 8 /* 64-bit block size */ @@ -231,10 +240,6 @@ static void Blowfish_init(Blowfish_state *self, const unsigned char *key, int ke #define block_encrypt Blowfish_encrypt #define block_decrypt Blowfish_decrypt -static void block_finalize(block_state *self) -{ -} - #include "block_template.c" /* vim:set ts=4 sw=4 sts=4 expandtab: */ diff --git a/src/CAST.c b/src/CAST.c index d7b00f39..9ff98622 100644 --- a/src/CAST.c +++ b/src/CAST.c @@ -42,7 +42,7 @@ */ -#include "pycrypto_common.h" +#include "Python.h" #define MODULE_NAME _CAST #define BLOCK_SIZE 8 @@ -50,8 +50,8 @@ /* adjust these according to your compiler/platform. On some machines uint32 will have to be a long. It's OK if uint32 is more than 32 bits. */ -typedef uint32_t uint32; -typedef uint8_t uint8; +typedef unsigned int uint32; +typedef unsigned char uint8; /* this struct probably belongs in cast.h */ typedef struct { @@ -434,11 +434,6 @@ block_init(block_state *self, unsigned char *key, int keylength) castschedulekeys(self, key, keylength); } -static void -block_finalize(block_state* self) -{ -} - static void block_encrypt(block_state *self, unsigned char *in, unsigned char *out) diff --git a/src/DES.c b/src/DES.c index 2987956b..96a93352 100644 --- a/src/DES.c +++ b/src/DES.c @@ -24,8 +24,6 @@ * Country of origin: Canada */ -#include "pycrypto_common.h" - /* Setting this will cause LibTomCrypt to return CRYPT_INVALID_ARG when its * assert-like LTC_ARGCHK macro fails. */ #define ARGTYPE 4 @@ -33,7 +31,10 @@ /* Include the actial DES implementation */ #include "libtom/tomcrypt_des.c" +#undef DES /* this is needed because tomcrypt_custom.h defines DES to an empty string */ + #include +#include "Python.h" typedef struct { symmetric_key sk; @@ -48,11 +49,7 @@ static void ltcseterr(int rc) break; case CRYPT_INVALID_KEYSIZE: -#ifdef PCT_DES3_MODULE PyErr_SetString(PyExc_ValueError, "Invalid key size (must be either 16 or 24 bytes long)"); -#else - PyErr_SetString(PyExc_ValueError, "Invalid key size (must be 8 bytes long)"); -#endif break; case CRYPT_INVALID_ROUNDS: @@ -69,23 +66,7 @@ static void block_init(block_state *self, unsigned char *key, int keylen) { int rc; #ifdef PCT_DES3_MODULE - int i; - unsigned char keybuf[24]; - if (keylen == 16) { - /* "Two-key 3DES" mode, where the 3DES key is K1,K2,K1 */ - for (i = 0; i < 16; i++) { - keybuf[i] = key[i]; - } - for (i = 0; i < 8; i++) { - keybuf[i+16] = key[i]; - } - rc = des3_setup(keybuf, 24, 0, &self->sk); - for (i = 0; i < 24; i++) { /* TODO: securely zeroize this */ - keybuf[i] = 0; - } - } else { - rc = des3_setup(key, keylen, 0, &self->sk); - } + rc = des3_setup(key, keylen, 0, &self->sk); #else rc = des_setup(key, keylen, 0, &self->sk); #endif @@ -94,10 +75,6 @@ static void block_init(block_state *self, unsigned char *key, int keylen) } } -static void block_finalize(block_state *self) -{ -} - static void block_encrypt(block_state *self, unsigned char *in, unsigned char *out) { int rc; diff --git a/src/MD2.c b/src/MD2.c index 86ea8591..3054fb22 100644 --- a/src/MD2.c +++ b/src/MD2.c @@ -27,42 +27,31 @@ */ -#include "pycrypto_common.h" #include +#include "Python.h" +#include "pycrypto_compat.h" -#define MODULE_NAME MD2 +#define MODULE_NAME _MD2 #define DIGEST_SIZE 16 #define BLOCK_SIZE 64 -static char MODULE__doc__[] = - "MD2 cryptographic hash algorithm.\n" - "\n" - "MD2 is specified in RFC1319_ and it produces the 128 bit digest of a message.\n" - "\n" - " >>> from Crypto.Hash import MD2\n" - " >>>\n" - " >>> h = MD2.new()\n" - " >>> h.update(b'Hello')\n" - " >>> print h.hexdigest()\n" - "\n" - "MD2 stand for Message Digest version 2, and it was invented by Rivest in 1989.\n" - "\n" - "This algorithm is both slow and insecure. Do not use it for new designs.\n" - "\n" - ".. _RFC1319: http://tools.ietf.org/html/rfc1319\n" - "\n" - ":Variables:\n" - " block_size\n" - " The internal block size of the hash algorithm in bytes.\n" - " digest_size\n" - " The size of the resulting hash in bytes.\n"; +/** + * id-md2 OBJECT IDENTIFIER ::= { + * iso(1) member-body(2) us(840) rsadsi(113549) + * digestAlgorithm(2) 2 + * } + */ +static const char md2_oid[] = { 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x02 }; + +#define DER_OID ((void*)&md2_oid) +#define DER_OID_SIZE (sizeof md2_oid) -typedef uint8_t U8; -typedef uint32_t U32; +typedef unsigned char U8; +typedef unsigned int U32; typedef struct { U8 C[16], X[48]; - unsigned int count; + int count; U8 buf[16]; } hash_state; @@ -145,7 +134,7 @@ hash_digest (const hash_state *self) U8 padding[16]; U32 padlen; hash_state temp; - unsigned int i; + int i; memcpy(&temp, self, sizeof(hash_state)); padlen= 16-self->count; diff --git a/src/MD4.c b/src/MD4.c index 2d383391..2c0a984f 100644 --- a/src/MD4.c +++ b/src/MD4.c @@ -25,39 +25,18 @@ * =================================================================== * */ + -#include "pycrypto_common.h" #include +#include "Python.h" +#include "pycrypto_compat.h" -#define MODULE_NAME MD4 +#define MODULE_NAME _MD4 #define DIGEST_SIZE 16 #define BLOCK_SIZE 64 -static char MODULE__doc__[] = - "MD4 cryptographic hash algorithm.\n" - "\n" - "MD4 is specified in RFC1320_ and produces the 128 bit digest of a message.\n" - "\n" - " >>> from Crypto.Hash import MD4\n" - " >>>\n" - " >>> h = MD4.new()\n" - " >>> h.update(b'Hello')\n" - " >>> print h.hexdigest()\n" - "\n" - "MD4 stand for Message Digest version 4, and it was invented by Rivest in 1990.\n" - "\n" - "This algorithm is insecure. Do not use it for new designs.\n" - "\n" - ".. _RFC1320: http://tools.ietf.org/html/rfc1320\n" - "\n" - ":Variables:\n" - " block_size\n" - " The internal block size of the hash algorithm in bytes.\n" - " digest_size\n" - " The size of the resulting hash in bytes.\n"; - -typedef uint32_t U32; -typedef uint8_t U8; +typedef unsigned int U32; +typedef unsigned char U8; #define U32_MAX (U32)4294967295 typedef struct { diff --git a/src/RIPEMD160.c b/src/RIPEMD160.c index 8b33bab9..9786af81 100644 --- a/src/RIPEMD160.c +++ b/src/RIPEMD160.c @@ -43,39 +43,23 @@ * "RIPEMD-160 is big-bit-endian, little-byte-endian, and left-justified." */ -#include "pycrypto_common.h" +#include "config.h" +#if HAVE_STDINT_H +# include +#elif defined(__sun) || defined(__sun__) +# include +#else +# error "stdint.h not found" +#endif + #include #include +#include "Python.h" +#include "pycrypto_compat.h" #define RIPEMD160_DIGEST_SIZE 20 #define BLOCK_SIZE 64 -static char MODULE__doc__[] = - "RIPEMD-160 cryptographic hash algorithm.\n" - "\n" - "RIPEMD-160_ produces the 160 bit digest of a message.\n" - "\n" - " >>> from Crypto.Hash import RIPEMD160\n" - " >>>\n" - " >>> h = RIPEMD160.new()\n" - " >>> h.update(b'Hello')\n" - " >>> print h.hexdigest()\n" - "\n" - "RIPEMD-160 stands for RACE Integrity Primitives Evaluation Message Digest\n" - "with a 160 bit digest. It was invented by Dobbertin, Bosselaers, and Preneel.\n" - "\n" - "This algorithm is considered secure, although it has not been scrutinized as\n" - "extensively as SHA-1. Moreover, it provides an informal security level of just\n" - "80bits.\n" - "\n" - ".. _RIPEMD-160: http://homes.esat.kuleuven.be/~bosselae/ripemd160.html\n" - "\n" - ":Variables:\n" - " block_size\n" - " The internal block size of the hash algorithm in bytes.\n" - " digest_size\n" - " The size of the resulting hash in bytes.\n"; - #define RIPEMD160_MAGIC 0x9f19dd68u typedef struct { uint32_t magic; @@ -416,7 +400,7 @@ static int ripemd160_digest(const ripemd160_state *self, unsigned char *out) } /* Template definitions */ -#define MODULE_NAME RIPEMD160 +#define MODULE_NAME _RIPEMD160 #define DIGEST_SIZE RIPEMD160_DIGEST_SIZE #define hash_state ripemd160_state #define hash_init ripemd160_init diff --git a/src/SHA224.c b/src/SHA224.c index 2a31c2d8..ca70fbd5 100644 --- a/src/SHA224.c +++ b/src/SHA224.c @@ -27,36 +27,12 @@ * */ -#include "pycrypto_common.h" - -#define MODULE_NAME SHA224 +#define MODULE_NAME _SHA224 #define DIGEST_SIZE (224/8) #define BLOCK_SIZE (512/8) #define WORD_SIZE 4 #define SCHEDULE_SIZE 64 -static char MODULE__doc__[] = - "SHA-224 cryptographic hash algorithm.\n" - "\n" - "SHA-224 belongs to the SHA-2_ family of cryptographic hashes.\n" - "It produces the 224 bit digest of a message.\n" - "\n" - " >>> from Crypto.Hash import SHA224\n" - " >>>\n" - " >>> h = SHA224.new()\n" - " >>> h.update(b'Hello')\n" - " >>> print h.hexdigest()\n" - "\n" - "*SHA* stands for Secure Hash Algorithm.\n" - "\n" - ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf\n" - "\n" - ":Variables:\n" - " block_size\n" - " The internal block size of the hash algorithm in bytes.\n" - " digest_size\n" - " The size of the resulting hash in bytes.\n"; - #include "hash_SHA2.h" /* Initial Values H */ diff --git a/src/SHA256.c b/src/SHA256.c index effae6e7..61a2d746 100644 --- a/src/SHA256.c +++ b/src/SHA256.c @@ -26,37 +26,12 @@ * =================================================================== * */ - -#include "pycrypto_common.h" - -#define MODULE_NAME SHA256 +#define MODULE_NAME _SHA256 #define DIGEST_SIZE (256/8) #define BLOCK_SIZE (512/8) #define WORD_SIZE 4 #define SCHEDULE_SIZE 64 - -static char MODULE__doc__[] = - "SHA-256 cryptographic hash algorithm.\n" - "\n" - "SHA-256 belongs to the SHA-2_ family of cryptographic hashes.\n" - "It produces the 256 bit digest of a message.\n" - "\n" - " >>> from Crypto.Hash import SHA256\n" - " >>>\n" - " >>> h = SHA256.new()\n" - " >>> h.update(b'Hello')\n" - " >>> print h.hexdigest()\n" - "\n" - "*SHA* stands for Secure Hash Algorithm.\n" - "\n" - ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf\n" - "\n" - ":Variables:\n" - " block_size\n" - " The internal block size of the hash algorithm in bytes.\n" - " digest_size\n" - " The size of the resulting hash in bytes.\n"; - + #include "hash_SHA2.h" /* Initial Values H */ diff --git a/src/SHA384.c b/src/SHA384.c index a7c527bf..05dfe250 100644 --- a/src/SHA384.c +++ b/src/SHA384.c @@ -27,36 +27,12 @@ * */ -#include "pycrypto_common.h" - -#define MODULE_NAME SHA384 +#define MODULE_NAME _SHA384 #define DIGEST_SIZE (384/8) #define BLOCK_SIZE (1024/8) #define WORD_SIZE 8 #define SCHEDULE_SIZE 80 -static char MODULE__doc__[] = - "SHA-384 cryptographic hash algorithm.\n" - "\n" - "SHA-384 belongs to the SHA-2_ family of cryptographic hashes.\n" - "It produces the 384 bit digest of a message.\n" - "\n" - " >>> from Crypto.Hash import SHA384\n" - " >>>\n" - " >>> h = SHA384.new()\n" - " >>> h.update(b'Hello')\n" - " >>> print h.hexdigest()\n" - "\n" - "*SHA* stands for Secure Hash Algorithm.\n" - "\n" - ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf\n" - "\n" - ":Variables:\n" - " block_size\n" - " The internal block size of the hash algorithm in bytes.\n" - " digest_size\n" - " The size of the resulting hash in bytes.\n"; - #include "hash_SHA2.h" /* Initial Values H */ diff --git a/src/SHA512.c b/src/SHA512.c index f2afefb6..3370e8e6 100644 --- a/src/SHA512.c +++ b/src/SHA512.c @@ -27,36 +27,12 @@ * */ -#include "pycrypto_common.h" - -#define MODULE_NAME SHA512 +#define MODULE_NAME _SHA512 #define DIGEST_SIZE (512/8) #define BLOCK_SIZE (1024/8) #define WORD_SIZE 8 #define SCHEDULE_SIZE 80 -static char MODULE__doc__[] = - "SHA-512 cryptographic hash algorithm.\n" - "\n" - "SHA-512 belongs to the SHA-2_ family of cryptographic hashes.\n" - "It produces the 512 bit digest of a message.\n" - "\n" - " >>> from Crypto.Hash import SHA512\n" - " >>>\n" - " >>> h = SHA512.new()\n" - " >>> h.update(b'Hello')\n" - " >>> print h.hexdigest()\n" - "\n" - "*SHA* stands for Secure Hash Algorithm.\n" - "\n" - ".. _SHA-2: http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf\n" - "\n" - ":Variables:\n" - " block_size\n" - " The internal block size of the hash algorithm in bytes.\n" - " digest_size\n" - " The size of the resulting hash in bytes.\n"; - #include "hash_SHA2.h" /* Initial Values H */ diff --git a/src/XOR.c b/src/XOR.c index d9947498..985e94f5 100644 --- a/src/XOR.c +++ b/src/XOR.c @@ -24,7 +24,7 @@ * ======================================================================= */ -#include "pycrypto_common.h" +#include "Python.h" #define MODULE_NAME _XOR #define BLOCK_SIZE 1 diff --git a/src/_counter.c b/src/_counter.c index 59ceb542..9b396e44 100644 --- a/src/_counter.c +++ b/src/_counter.c @@ -22,22 +22,32 @@ * =================================================================== */ -#include "pycrypto_common.h" #include #include #include +#include "Python.h" +#include "pycrypto_compat.h" #include "_counter.h" +#ifndef IS_PY3K +#define PyLong_FromLong PyInt_FromLong +#endif + /* NB: This can be called multiple times for a given object, via the __init__ method. Be careful. */ static int CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) { +#ifdef IS_PY3K PyBytesObject *prefix=NULL, *suffix=NULL, *initval=NULL; +#else + PyStringObject *prefix=NULL, *suffix=NULL, *initval=NULL; +#endif int allow_wraparound = 0; + int disable_shortcut = 0; Py_ssize_t size; - static char *kwlist[] = {"prefix", "suffix", "initval", "allow_wraparound", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "SSS|i", kwlist, &prefix, &suffix, &initval, &allow_wraparound)) + static char *kwlist[] = {"prefix", "suffix", "initval", "allow_wraparound", "disable_shortcut", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "SSS|ii", kwlist, &prefix, &suffix, &initval, &allow_wraparound, &disable_shortcut)) return -1; /* Check string size and set nbytes */ @@ -96,7 +106,6 @@ CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) /* Sanity-check pointers */ assert(self->val <= self->p); - assert(self->buf_size >= 0); assert(self->p + self->nbytes <= self->val + self->buf_size); assert(self->val + PyBytes_GET_SIZE(self->prefix) == self->p); assert(PyBytes_GET_SIZE(self->prefix) + self->nbytes + PyBytes_GET_SIZE(self->suffix) == self->buf_size); @@ -106,7 +115,8 @@ CounterObject_init(PCT_CounterObject *self, PyObject *args, PyObject *kwargs) memcpy(self->p, PyBytes_AS_STRING(initval), self->nbytes); memcpy(self->p + self->nbytes, PyBytes_AS_STRING(suffix), PyBytes_GET_SIZE(suffix)); - /* Set allow_wraparound */ + /* Set shortcut_disabled and allow_wraparound */ + self->shortcut_disabled = disable_shortcut; self->allow_wraparound = allow_wraparound; /* Clear the carry flag */ @@ -151,7 +161,7 @@ _CounterObject_next_value(PCT_CounterObject *self, int little_endian) goto err_out; } - eight = PyInt_FromLong(8); + eight = PyLong_FromLong(8); if (!eight) goto err_out; @@ -176,7 +186,7 @@ _CounterObject_next_value(PCT_CounterObject *self, int little_endian) /* ch = ord(p) */ Py_CLEAR(ch); /* delete old ch */ - ch = PyInt_FromLong((long) *p); + ch = PyLong_FromLong((long) *p); if (!ch) goto err_out; @@ -296,59 +306,92 @@ static PyMethodDef CounterBEObject_methods[] = { * so we hack it here. */ static PyObject * +#ifdef IS_PY3K CounterLEObject_getattro(PyObject *s, PyObject *attr) +#else +CounterLEObject_getattr(PyObject *s, char *name) +#endif { PCT_CounterObject *self = (PCT_CounterObject *)s; - if (!PyString_Check(attr)) - goto generic; +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; - if (PyString_CompareWithASCIIString(attr, "carry") == 0) { - return PyInt_FromLong((long)self->carry); + if (PyUnicode_CompareWithASCIIString(attr, "carry") == 0) { +#else + if (strcmp(name, "carry") == 0) { +#endif + return PyLong_FromLong((long)self->carry); +#ifdef IS_PY3K + } else if (!self->shortcut_disabled && PyUnicode_CompareWithASCIIString(attr, "__PCT_CTR_SHORTCUT__") == 0) { +#else + } else if (!self->shortcut_disabled && strcmp(name, "__PCT_CTR_SHORTCUT__") == 0) { +#endif + /* Shortcut hack - See block_template.c */ + Py_INCREF(Py_True); + return Py_True; } +#ifdef IS_PY3K generic: -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ - return PyObject_GenericGetAttr(s, attr); + return PyObject_GenericGetAttr(s, attr); #else - if (PyString_Check(attr) < 0) { - PyErr_SetObject(PyExc_AttributeError, attr); - return NULL; - } - return Py_FindMethod(CounterLEObject_methods, (PyObject *)self, PyString_AsString(attr)); + return Py_FindMethod(CounterLEObject_methods, (PyObject *)self, name); #endif } static PyObject * +#ifdef IS_PY3K CounterBEObject_getattro(PyObject *s, PyObject *attr) +#else +CounterBEObject_getattr(PyObject *s, char *name) +#endif { PCT_CounterObject *self = (PCT_CounterObject *)s; - if (!PyString_Check(attr)) - goto generic; +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) + goto generic; - if (PyString_CompareWithASCIIString(attr, "carry") == 0) { - return PyInt_FromLong((long)self->carry); + if (PyUnicode_CompareWithASCIIString(attr, "carry") == 0) { +#else + if (strcmp(name, "carry") == 0) { +#endif + return PyLong_FromLong((long)self->carry); +#ifdef IS_PY3K + } else if (!self->shortcut_disabled && PyUnicode_CompareWithASCIIString(attr, "__PCT_CTR_SHORTCUT__") == 0) { +#else + } else if (!self->shortcut_disabled && strcmp(name, "__PCT_CTR_SHORTCUT__") == 0) { +#endif + /* Shortcut hack - See block_template.c */ + Py_INCREF(Py_True); + return Py_True; } +#ifdef IS_PY3K generic: -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ - return PyObject_GenericGetAttr(s, attr); + return PyObject_GenericGetAttr(s, attr); #else - if (PyString_Check(attr) < 0) { - PyErr_SetObject(PyExc_AttributeError, attr); - return NULL; - } - return Py_FindMethod(CounterBEObject_methods, (PyObject *)self, PyString_AsString(attr)); + return Py_FindMethod(CounterBEObject_methods, (PyObject *)self, name); #endif } static PyTypeObject -PCT_CounterLEType = { +my_CounterLEType = { +#ifdef IS_PY3K PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ +#endif "_counter.CounterLE", /* tp_name */ sizeof(PCT_CounterObject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ (destructor)CounterObject_dealloc, /* tp_dealloc */ 0, /* tp_print */ - 0, /* tp_getattr */ +#ifdef IS_PY3K + 0, /* tp_getattr */ +#else + CounterLEObject_getattr, /* tp_getattr */ +#endif 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -358,16 +401,20 @@ PCT_CounterLEType = { 0, /* tp_hash */ (ternaryfunc)CounterObject_call, /* tp_call */ 0, /* tp_str */ - CounterLEObject_getattro, /* tp_getattro */ +#ifdef IS_PY3K + CounterLEObject_getattro, /* tp_getattro */ +#else + 0, /* tp_getattro */ +#endif 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Counter (little endian)", /* tp_doc */ +#ifdef IS_PY3K 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ 0, /*tp_iter*/ 0, /*tp_iternext*/ CounterLEObject_methods, /*tp_methods*/ @@ -375,14 +422,23 @@ PCT_CounterLEType = { }; static PyTypeObject -PCT_CounterBEType = { +my_CounterBEType = { +#ifdef IS_PY3K PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else + PyObject_HEAD_INIT(NULL) + 0, /* ob_size */ +#endif "_counter.CounterBE", /* tp_name */ sizeof(PCT_CounterObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)CounterObject_dealloc, /* tp_dealloc */ 0, /* tp_print */ - 0, /* tp_getattr */ +#ifdef IS_PY3K + 0, /* tp_getattr */ +#else + CounterBEObject_getattr, /* tp_getattr */ +#endif 0, /* tp_setattr */ 0, /* tp_compare */ 0, /* tp_repr */ @@ -392,16 +448,20 @@ PCT_CounterBEType = { 0, /* tp_hash */ (ternaryfunc)CounterObject_call, /* tp_call */ 0, /* tp_str */ - CounterBEObject_getattro, /* tp_getattro */ +#ifdef IS_PY3K + CounterBEObject_getattro, /* tp_getattro */ +#else + 0, /* tp_getattro */ +#endif 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ "Counter (big endian)", /* tp_doc */ +#ifdef IS_PY3K 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ 0, /*tp_iter*/ 0, /*tp_iternext*/ CounterBEObject_methods, /*tp_methods*/ @@ -418,7 +478,7 @@ CounterLE_new(PyObject *self, PyObject *args, PyObject *kwargs) PCT_CounterObject *obj = NULL; /* Create the new object */ - obj = PyObject_New(PCT_CounterObject, &PCT_CounterLEType); + obj = PyObject_New(PCT_CounterObject, &my_CounterLEType); if (obj == NULL) { return NULL; } @@ -444,7 +504,7 @@ CounterBE_new(PyObject *self, PyObject *args, PyObject *kwargs) PCT_CounterObject *obj = NULL; /* Create the new object */ - obj = PyObject_New(PCT_CounterObject, &PCT_CounterBEType); + obj = PyObject_New(PCT_CounterObject, &my_CounterBEType); if (obj == NULL) { return NULL; } @@ -495,51 +555,30 @@ PyInit__counter(void) init_counter(void) #endif { - PyObject *m = NULL; + PyObject *m; - if (PyType_Ready(&PCT_CounterLEType) < 0) - goto errout; - if (PyType_Ready(&PCT_CounterBEType) < 0) - goto errout; + /* TODO - Is the error handling here correct? */ +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&my_CounterLEType) < 0) + return NULL; + if (PyType_Ready(&my_CounterBEType) < 0) + return NULL; /* Initialize the module */ -#ifdef IS_PY3K m = PyModule_Create(&moduledef); -#else - m = Py_InitModule("_counter", module_methods); -#endif if (m == NULL) - goto errout; - - /* Add the counter types to the module so that epydoc can see them, and so - * that we can access them in the block cipher modules. */ - PyObject_SetAttrString(m, "CounterBE", (PyObject *)&PCT_CounterBEType); - PyObject_SetAttrString(m, "CounterLE", (PyObject *)&PCT_CounterLEType); - - /* Allow block_template.c to do an ABI check */ - PyModule_AddIntConstant(m, "_PCT_CTR_ABI_VERSION", PCT_CTR_ABI_VERSION); - - -out: - /* Final error check */ - if (m == NULL && !PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "can't initialize module"); - goto errout; - } - - /* Free local objects here */ + return NULL; - /* Return */ -#ifdef IS_PY3K - return m; + return m; #else - return; + m = Py_InitModule("_counter", module_methods); + if (m == NULL) + return; + + my_CounterLEType.ob_type = &PyType_Type; + my_CounterBEType.ob_type = &PyType_Type; #endif - -errout: - /* Free the module and other global objects here */ - Py_CLEAR(m); - goto out; } /* vim:set ts=4 sw=4 sts=4 expandtab: */ diff --git a/src/_counter.h b/src/_counter.h index df2091f7..fc3e24e8 100644 --- a/src/_counter.h +++ b/src/_counter.h @@ -24,19 +24,25 @@ #ifndef PCT__COUNTER_H #define PCT__COUNTER_H -#include "pycrypto_common.h" - -#define PCT_CTR_ABI_VERSION 1 /* Bump this whenever the structure below changes */ +#include "config.h" +#if HAVE_STDINT_H +# include +#elif defined(__sun) || defined(__sun__) +# include +#else +# error "stdint.h not found" +#endif typedef struct { PyObject_HEAD PyBytesObject *prefix; /* Prefix (useful for a nonce) */ PyBytesObject *suffix; /* Suffix (useful for a nonce) */ uint8_t *val; /* Buffer for our output string */ - Py_ssize_t buf_size;/* Size of the buffer */ + uint32_t buf_size; /* Size of the buffer */ uint8_t *p; /* Pointer to the part of the buffer that we're allowed to update */ uint16_t nbytes; /* The number of bytes that from .p that are part of the counter */ void (*inc_func)(void *); /* Pointer to the counter increment function */ + int shortcut_disabled; /* This gets set to a non-zero value when the shortcut mechanism is disabled */ int carry; /* This gets set by Counter*Object_increment when the counter wraps around */ int allow_wraparound; /* When this is false, we raise OverflowError on next_value() or __call__() when the counter wraps around */ } PCT_CounterObject; diff --git a/src/_fastmath.c b/src/_fastmath.c index e369f5a7..b8b24b63 100644 --- a/src/_fastmath.c +++ b/src/_fastmath.c @@ -26,10 +26,12 @@ * $Id$ */ -#include "pycrypto_common.h" #include #include +#include "Python.h" +#include "pycrypto_compat.h" #include /* for conversions */ +#include "config.h" #if HAVE_LIBGMP # include #elif HAVE_LIBMPIR @@ -51,10 +53,10 @@ #define SIEVE_BASE_SIZE (sizeof (sieve_base) / sizeof (sieve_base[0])) -#ifdef IS_PY3K -#define OB_SIZE(p) ((p)->ob_base.ob_size) +#ifdef _MSC_VER +#define INLINE __inline #else -#define OB_SIZE(p) ((p)->ob_size) +#define INLINE inline #endif static unsigned int sieve_base[10000]; @@ -68,18 +70,32 @@ longObjToMPZ (mpz_t m, PyLongObject * p) mpz_t temp, temp2; mpz_init (temp); mpz_init (temp2); - if (OB_SIZE(p) > 0) { - size = OB_SIZE(p); +#ifdef IS_PY3K + if (p->ob_base.ob_size > 0) { + size = p->ob_base.ob_size; + negative = 1; + } else { + size = -p->ob_base.ob_size; + negative = -1; + } +#else + if (p->ob_size > 0) { + size = p->ob_size; negative = 1; } else { - size = -OB_SIZE(p); + size = -p->ob_size; negative = -1; } +#endif mpz_set_ui (m, 0); for (i = 0; i < size; i++) { mpz_set_ui (temp, p->ob_digit[i]); +#ifdef IS_PY3K mpz_mul_2exp (temp2, temp, PyLong_SHIFT * i); +#else + mpz_mul_2exp (temp2, temp, SHIFT * i); +#endif mpz_add (m, m, temp2); } mpz_mul_si(m, m, negative); @@ -91,7 +107,11 @@ static PyObject * mpzToLongObj (mpz_t m) { /* borrowed from gmpy */ +#ifdef IS_PY3K int size = (mpz_sizeinbase (m, 2) + PyLong_SHIFT - 1) / PyLong_SHIFT; +#else + int size = (mpz_sizeinbase (m, 2) + SHIFT - 1) / SHIFT; +#endif int sgn; int i; mpz_t temp; @@ -103,13 +123,22 @@ mpzToLongObj (mpz_t m) mpz_mul_si(temp, m, sgn); for (i = 0; i < size; i++) { +#ifdef IS_PY3K l->ob_digit[i] = (digit) (mpz_get_ui (temp) & PyLong_MASK); mpz_fdiv_q_2exp (temp, temp, PyLong_SHIFT); +#else + l->ob_digit[i] = (digit) (mpz_get_ui (temp) & MASK); + mpz_fdiv_q_2exp (temp, temp, SHIFT); +#endif } i = size; while ((i > 0) && (l->ob_digit[i - 1] == 0)) i--; - OB_SIZE(l) = i * sgn; +#ifdef IS_PY3K + l->ob_base.ob_size = i * sgn; +#else + l->ob_size = i * sgn; +#endif mpz_clear (temp); return (PyObject *) l; } @@ -139,14 +168,22 @@ static PyObject *rsaKey_new (PyObject *, PyObject *); static PyObject *dsaKey_new (PyObject *, PyObject *); static void dsaKey_dealloc (dsaKey *); +#ifdef IS_PY3K static PyObject *dsaKey_getattro (dsaKey *, PyObject *); +#else +static PyObject *dsaKey_getattr (dsaKey *, char *); +#endif static PyObject *dsaKey__sign (dsaKey *, PyObject *); static PyObject *dsaKey__verify (dsaKey *, PyObject *); static PyObject *dsaKey_size (dsaKey *, PyObject *); static PyObject *dsaKey_has_private (dsaKey *, PyObject *); static void rsaKey_dealloc (rsaKey *); +#ifdef IS_PY3K static PyObject *rsaKey_getattro (rsaKey *, PyObject *); +#else +static PyObject *rsaKey_getattr (rsaKey *, char *); +#endif static PyObject *rsaKey__encrypt (rsaKey *, PyObject *); static PyObject *rsaKey__decrypt (rsaKey *, PyObject *); static PyObject *rsaKey__verify (rsaKey *, PyObject *); @@ -156,28 +193,22 @@ static PyObject *rsaKey_size (rsaKey *, PyObject *); static PyObject *rsaKey_has_private (rsaKey *, PyObject *); static int -dsaSign (dsaKey * key, mpz_t m, mpz_t k, mpz_t blind, mpz_t r, mpz_t s) +dsaSign (dsaKey * key, mpz_t m, mpz_t k, mpz_t r, mpz_t s) { mpz_t temp; - mpz_t temp2; if (mpz_cmp_ui (k, 2) < 0 || mpz_cmp (k, key->q) >= 0) { return 1; } mpz_init (temp); - mpz_init (temp2); MPZ_POWM (r, key->g, k, key->p); mpz_mod (r, r, key->q); - mpz_mul (temp, blind, key->x); - mpz_mul (temp, temp, r); - mpz_mul (temp2, m, blind); - mpz_add (temp, temp2, temp); - mpz_mul (s, k, blind); - mpz_invert (s, s, key->q); + mpz_invert (s, k, key->q); + mpz_mul (temp, key->x, r); + mpz_add (temp, m, temp); mpz_mul (s, s, temp); mpz_mod (s, s, key->q); mpz_clear (temp); - mpz_clear (temp2); return 0; } @@ -351,13 +382,22 @@ static PyMethodDef rsaKey__methods__[] = { static PyObject *fastmathError; /* raised on errors */ static PyTypeObject dsaKeyType = { +#ifdef IS_PY3K PyVarObject_HEAD_INIT (NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else + PyObject_HEAD_INIT (NULL) + 0, /*ob_size*/ +#endif "dsaKey", sizeof (dsaKey), 0, (destructor) dsaKey_dealloc, /* dealloc */ 0, /* print */ +#ifdef IS_PY3K 0, /* getattr */ +#else + (getattrfunc) dsaKey_getattr, /* getattr */ +#endif 0, /* setattr */ 0, /* compare */ 0, /* repr */ @@ -366,6 +406,7 @@ static PyTypeObject dsaKeyType = { 0, /* as_mapping */ 0, /* hash */ 0, /* call */ +#ifdef IS_PY3K 0, /*tp_str*/ (getattrofunc) dsaKey_getattro, /*tp_getattro*/ 0, /*tp_setattro*/ @@ -376,7 +417,6 @@ static PyTypeObject dsaKeyType = { 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ 0, /*tp_iter*/ 0, /*tp_iternext*/ dsaKey__methods__, /*tp_methods*/ @@ -384,14 +424,23 @@ static PyTypeObject dsaKeyType = { }; static PyTypeObject rsaKeyType = { +#ifdef IS_PY3K PyVarObject_HEAD_INIT (NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else + PyObject_HEAD_INIT (NULL) + 0, /*ob_size*/ +#endif "rsaKey", /*tp_name*/ sizeof (rsaKey), /*tp_size*/ 0, /*tp_itemsize*/ /* methods */ (destructor) rsaKey_dealloc, /* dealloc */ 0, /* print */ +#ifdef IS_PY3K 0, /* getattr */ +#else + (getattrfunc) rsaKey_getattr, /* getattr */ +#endif 0, /* setattr */ 0, /* compare */ 0, /* repr */ @@ -400,6 +449,7 @@ static PyTypeObject rsaKeyType = { 0, /* as_mapping */ 0, /* hash */ 0, /* call */ +#ifdef IS_PY3K 0, /*tp_str*/ (getattrofunc) rsaKey_getattro, /*tp_getattro*/ 0, /*tp_setattro*/ @@ -410,7 +460,6 @@ static PyTypeObject rsaKeyType = { 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ 0, /*tp_iter*/ 0, /*tp_iternext*/ rsaKey__methods__, /*tp_methods*/ @@ -458,19 +507,43 @@ dsaKey_dealloc (dsaKey * key) } static PyObject * +#ifdef IS_PY3K dsaKey_getattro (dsaKey * key, PyObject *attr) +#else +dsaKey_getattr (dsaKey * key, char *attr) +#endif { - if (!PyString_Check(attr)) +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) goto generic; - if (PyString_CompareWithASCIIString(attr,"y") == 0) + if (PyUnicode_CompareWithASCIIString(attr,"y") == 0) +#else + if (strcmp (attr, "y") == 0) +#endif return mpzToLongObj (key->y); - else if (PyString_CompareWithASCIIString(attr, "g") == 0) +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "g") == 0) +#else + else if (strcmp (attr, "g") == 0) +#endif return mpzToLongObj (key->g); - else if (PyString_CompareWithASCIIString(attr, "p") == 0) +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "p") == 0) +#else + else if (strcmp (attr, "p") == 0) +#endif return mpzToLongObj (key->p); - else if (PyString_CompareWithASCIIString(attr, "q") == 0) +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "q") == 0) +#else + else if (strcmp (attr, "q") == 0) +#endif return mpzToLongObj (key->q); - else if (PyString_CompareWithASCIIString(attr, "x") == 0) +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "x") == 0) +#else + else if (strcmp (attr, "x") == 0) +#endif { if (mpz_size (key->x) == 0) { @@ -481,39 +554,32 @@ dsaKey_getattro (dsaKey * key, PyObject *attr) return mpzToLongObj (key->x); } else +#ifdef IS_PY3K generic: -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ return PyObject_GenericGetAttr((PyObject *) key, attr); #else - if (PyString_Check(attr) < 0) { - PyErr_SetObject(PyExc_AttributeError, attr); - return NULL; - } - return Py_FindMethod(dsaKey__methods__, (PyObject *)key, PyString_AsString(attr)); + return Py_FindMethod (dsaKey__methods__, (PyObject *) key, attr); #endif } static PyObject * dsaKey__sign (dsaKey * key, PyObject * args) { - PyObject *lm, *lk, *lblind, *lr, *ls, *retval; - mpz_t m, k, blind, r, s; + PyObject *lm, *lk, *lr, *ls, *retval; + mpz_t m, k, r, s; int result; - if (!PyArg_ParseTuple (args, "O!O!O!", &PyLong_Type, &lm, - &PyLong_Type, &lk, - &PyLong_Type, &lblind)) + if (!PyArg_ParseTuple (args, "O!O!", &PyLong_Type, &lm, + &PyLong_Type, &lk)) { return NULL; } mpz_init (m); mpz_init (k); - mpz_init (blind); mpz_init (r); mpz_init (s); longObjToMPZ (m, (PyLongObject *) lm); longObjToMPZ (k, (PyLongObject *) lk); - longObjToMPZ (blind, (PyLongObject *) lblind); - result = dsaSign (key, m, k, blind, r, s); + result = dsaSign (key, m, k, r, s); if (result == 1) { PyErr_SetString (PyExc_ValueError, "K not between 2 and q"); @@ -524,7 +590,6 @@ dsaKey__sign (dsaKey * key, PyObject * args) if (lr == NULL || ls == NULL) goto errout; mpz_clear (m); mpz_clear (k); - mpz_clear (blind); mpz_clear (r); mpz_clear (s); retval = Py_BuildValue ("(NN)", lr, ls); @@ -616,7 +681,7 @@ static int factorize_N_from_D(rsaKey *key) cnt = mpz_scan1(t, 0); mpz_fdiv_q_2exp(t,t,cnt); mpz_set_ui(a, 2); - for (spotted=0; (!spotted) && (mpz_cmp_ui(a,1000)<0); mpz_add_ui(a,a,2)) { + for (spotted=0; (!spotted) && (mpz_cmp_ui(a,100)<0); mpz_add_ui(a,a,2)) { mpz_set(k, t); for (; (mpz_cmp(k,ktot)<0); mpz_mul_ui(k,k,2)) { mpz_powm(cand,a,k,key->n); @@ -681,7 +746,6 @@ rsaKey_new (PyObject * self, PyObject * args) } else { if (factorize_N_from_D(key)) { - Py_DECREF(key); PyErr_SetString(PyExc_ValueError, "Unable to compute factors p and q from exponent d."); return NULL; @@ -708,15 +772,31 @@ rsaKey_dealloc (rsaKey * key) } static PyObject * +#ifdef IS_PY3K rsaKey_getattro (rsaKey * key, PyObject *attr) +#else +rsaKey_getattr (rsaKey * key, char *attr) +#endif { - if (!PyString_Check(attr)) +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) goto generic; - if (PyString_CompareWithASCIIString(attr, "n") == 0) + if (PyUnicode_CompareWithASCIIString(attr, "n") == 0) +#else + if (strcmp (attr, "n") == 0) +#endif return mpzToLongObj (key->n); - else if (PyString_CompareWithASCIIString(attr, "e") == 0) +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "e") == 0) +#else + else if (strcmp (attr, "e") == 0) +#endif return mpzToLongObj (key->e); - else if (PyString_CompareWithASCIIString(attr, "d") == 0) +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "d") == 0) +#else + else if (strcmp (attr, "d") == 0) +#endif { if (mpz_size (key->d) == 0) { @@ -726,7 +806,11 @@ rsaKey_getattro (rsaKey * key, PyObject *attr) } return mpzToLongObj (key->d); } - else if (PyString_CompareWithASCIIString(attr, "p") == 0) +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "p") == 0) +#else + else if (strcmp (attr, "p") == 0) +#endif { if (mpz_size (key->p) == 0) { @@ -736,7 +820,11 @@ rsaKey_getattro (rsaKey * key, PyObject *attr) } return mpzToLongObj (key->p); } - else if (PyString_CompareWithASCIIString(attr, "q") == 0) +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "q") == 0) +#else + else if (strcmp (attr, "q") == 0) +#endif { if (mpz_size (key->q) == 0) { @@ -746,7 +834,11 @@ rsaKey_getattro (rsaKey * key, PyObject *attr) } return mpzToLongObj (key->q); } - else if (PyString_CompareWithASCIIString(attr, "u") == 0) +#ifdef IS_PY3K + else if (PyUnicode_CompareWithASCIIString(attr, "u") == 0) +#else + else if (strcmp (attr, "u") == 0) +#endif { if (mpz_size (key->u) == 0) { @@ -757,15 +849,12 @@ rsaKey_getattro (rsaKey * key, PyObject *attr) return mpzToLongObj (key->u); } else +#ifdef IS_PY3K generic: -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ return PyObject_GenericGetAttr((PyObject *) key, attr); #else - if (PyString_Check(attr) < 0) { - PyErr_SetObject(PyExc_AttributeError, attr); - return NULL; - } - return Py_FindMethod(rsaKey__methods__, (PyObject *)key, PyString_AsString(attr)); + return Py_FindMethod (rsaKey__methods__, + (PyObject *) key, attr); #endif } @@ -1008,9 +1097,8 @@ isPrime (PyObject * self, PyObject * args, PyObject * kwargs) mpz_clear (n); Py_END_ALLOW_THREADS; - if (result < 0) { - return NULL; - } else if (result == 0) { + if (result == 0) + { Py_INCREF(Py_False); return Py_False; } else { @@ -1021,14 +1109,14 @@ isPrime (PyObject * self, PyObject * args, PyObject * kwargs) -inline size_t size (mpz_t n) +INLINE size_t size (mpz_t n) { return mpz_sizeinbase (n, 2); } void bytes_to_mpz (mpz_t result, const unsigned char *bytes, size_t size) { - unsigned long i; + unsigned long int i; mpz_t tmp; mpz_init (tmp); Py_BEGIN_ALLOW_THREADS; @@ -1036,7 +1124,7 @@ void bytes_to_mpz (mpz_t result, const unsigned char *bytes, size_t size) for (i = 0; i < size; ++i) { /* get current byte */ - mpz_set_ui (tmp, (unsigned long)bytes[i]); + mpz_set_ui (tmp, (unsigned long int)bytes[i]); /* left shift and add */ mpz_mul_2exp (tmp, tmp, 8 * i); mpz_add (result, result, tmp); @@ -1085,12 +1173,12 @@ getRNG (void) * support 2.1) */ static int -getRandomInteger (mpz_t n, unsigned long bits, PyObject *randfunc_) +getRandomInteger (mpz_t n, unsigned long int bits, PyObject *randfunc_) { - PyObject *arglist=NULL, *randfunc=NULL, *rng=NULL, *rand_bytes=NULL; + PyObject *arglist, *randfunc=NULL, *rng=NULL, *rand_bytes=NULL; int return_val = 1; - unsigned long bytes = bits / 8; - unsigned long odd_bits = bits % 8; + unsigned long int bytes = bits / 8; + unsigned long int odd_bits = bits % 8; /* generate 1 to 8 bits too many. we will remove them later by right-shifting */ bytes++; @@ -1117,7 +1205,7 @@ getRandomInteger (mpz_t n, unsigned long bits, PyObject *randfunc_) goto cleanup; } - arglist = Py_BuildValue ("(l)", (long)bytes); + arglist = Py_BuildValue ("(l)", (long int)bytes); if (arglist == NULL) { return_val = 0; goto cleanup; @@ -1127,6 +1215,7 @@ getRandomInteger (mpz_t n, unsigned long bits, PyObject *randfunc_) return_val = 0; goto cleanup; } + Py_DECREF (arglist); if (!PyBytes_Check (rand_bytes)) { PyErr_SetString (PyExc_TypeError, @@ -1140,7 +1229,6 @@ getRandomInteger (mpz_t n, unsigned long bits, PyObject *randfunc_) mpz_fdiv_q_2exp (n, n, 8 - odd_bits); cleanup: - Py_XDECREF (arglist); Py_XDECREF (rand_bytes); if (rng) { @@ -1161,7 +1249,7 @@ getRandomInteger (mpz_t n, unsigned long bits, PyObject *randfunc_) * support 2.1) */ static int -getRandomNBitInteger (mpz_t n, unsigned long bits, PyObject *randfunc) +getRandomNBitInteger (mpz_t n, unsigned long int bits, PyObject *randfunc) { if (!getRandomInteger (n, bits, randfunc)) return 0; @@ -1171,7 +1259,7 @@ getRandomNBitInteger (mpz_t n, unsigned long bits, PyObject *randfunc) } -/* Sets n to a random number so that lower_bound <= n < upper_bound . +/* Sets n to a rangom number so that lower_bound <= n < upper_bound . * If randfunc is provided it should be a callable which takes a single int * parameter and return as many random bytes as a python string. * Returns 1 on success @@ -1208,7 +1296,7 @@ getRandomRange (mpz_t n, mpz_t lower_bound, mpz_t upper_bound, static void -sieve_field (char *field, unsigned long field_size, mpz_t start) +sieve_field (char *field, unsigned long int field_size, mpz_t start) { mpz_t mpz_offset; unsigned int offset; @@ -1235,7 +1323,6 @@ sieve_field (char *field, unsigned long field_size, mpz_t start) /* Tests if n is prime. * Returns 0 when n is definitly composite. * Returns 1 when n is probably prime. - * Returns -1 when there is an error. * every round reduces the chance of a false positive be at least 1/4. * * If randfunc is omitted, then the python version Random.new().read is used. @@ -1248,8 +1335,7 @@ static int rabinMillerTest (mpz_t n, int rounds, PyObject *randfunc) { int base_was_tested; - unsigned long i, j, b, composite; - int return_val = 1; + unsigned long int i, j, b, composite, return_val=1; mpz_t a, m, z, n_1, tmp; mpz_t tested[MAX_RABIN_MILLER_ROUNDS]; @@ -1283,9 +1369,9 @@ rabinMillerTest (mpz_t n, int rounds, PyObject *randfunc) b = mpz_scan1 (n_1, 0); mpz_fdiv_q_2exp (m, n_1, b); - if (mpz_fits_ulong_p (n) && (mpz_get_ui (n) - 2 < (unsigned long)rounds)) + if (mpz_fits_ulong_p (n) && (mpz_get_ui (n) - 2 < rounds)) rounds = mpz_get_ui (n) - 2; - for (i = 0; i < (unsigned long)rounds; ++i) + for (i = 0; i < rounds; ++i) { mpz_set_ui (tmp, 2); do @@ -1363,17 +1449,17 @@ rabinMillerTest (mpz_t n, int rounds, PyObject *randfunc) static PyObject * getStrongPrime (PyObject *self, PyObject *args, PyObject *kwargs) { - unsigned long i, j, bits, x, e=0; + unsigned long int i, j, result, bits, x, e=0; mpz_t p[2], y[2], R, X; mpz_t tmp[2], lower_bound, upper_bound, range, increment; mpf_t tmp_bound; char *field; - double false_positive_prob = 1e-6; - int rabin_miller_rounds, is_possible_prime, error = 0, result; + double false_positive_prob; + int rabin_miller_rounds, is_possible_prime, error = 0; PyObject *prime, *randfunc=NULL; static char *kwlist[] = {"N", "e", "false_positive_prob", "randfunc", NULL}; - unsigned long base_size = SIEVE_BASE_SIZE; - unsigned long field_size = 5 * base_size; + unsigned long int base_size = SIEVE_BASE_SIZE; + unsigned long int field_size = 5 * base_size; int res; if (!PyArg_ParseTupleAndKeywords (args, kwargs, "l|ldO:getStrongPrime", @@ -1601,57 +1687,44 @@ static struct PyModuleDef moduledef = { }; #endif -PyMODINIT_FUNC #ifdef IS_PY3K +PyMODINIT_FUNC PyInit__fastmath (void) #else +void init_fastmath (void) #endif { - PyObject *m = NULL; - + PyObject *_fastmath_module; + PyObject *_fastmath_dict; + +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ if (PyType_Ready(&rsaKeyType) < 0) - goto errout; + return NULL; if (PyType_Ready(&dsaKeyType) < 0) - goto errout; - - /* Initialize the module */ -#ifdef IS_PY3K - m = PyModule_Create(&moduledef); + return NULL; + + _fastmath_module = PyModule_Create(&moduledef); + if (_fastmath_module == NULL) + return NULL; #else - m = Py_InitModule ("_fastmath", _fastmath__methods__); + rsaKeyType.ob_type = &PyType_Type; + dsaKeyType.ob_type = &PyType_Type; + _fastmath_module = Py_InitModule ("_fastmath", _fastmath__methods__); #endif - if (m == NULL) - goto errout; - + _fastmath_dict = PyModule_GetDict (_fastmath_module); fastmathError = PyErr_NewException ("_fastmath.error", NULL, NULL); - if (fastmathError == NULL) - goto errout; - PyObject_SetAttrString(m, "error", fastmathError); - - PyModule_AddIntConstant(m, "HAVE_DECL_MPZ_POWM_SEC", HAVE_DECL_MPZ_POWM_SEC); - -out: - /* Final error check */ - if (m == NULL && !PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "can't initialize module"); - goto errout; - } +#ifdef IS_PY3K + if (fastmathError == NULL) return NULL; +#endif + PyDict_SetItemString (_fastmath_dict, "error", fastmathError); - /* Free local objects here */ + PyModule_AddIntConstant(_fastmath_module, "HAVE_DECL_MPZ_POWM_SEC", HAVE_DECL_MPZ_POWM_SEC); - /* Return */ #ifdef IS_PY3K - return m; -#else - return; + return _fastmath_module; #endif - -errout: - /* Free the module and other global objects here */ - Py_CLEAR(m); - Py_CLEAR(fastmathError); - goto out; } /* The first 10000 primes to be used as a base for sieving */ diff --git a/src/block_template.c b/src/block_template.c index 99aee43a..c36b3162 100644 --- a/src/block_template.c +++ b/src/block_template.c @@ -24,9 +24,19 @@ * =================================================================== */ -#include "pycrypto_common.h" -#include "modsupport.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef _HAVE_STDC_HEADERS #include +#endif + +#include "Python.h" +#include "pycrypto_compat.h" +#include "modsupport.h" + #include "_counter.h" /* Cipher operation modes */ @@ -49,11 +59,6 @@ #endif #define _MODULE_STRING _XSTR(MODULE_NAME) -/* Object references for the counter_shortcut */ -static PyObject *_counter_module = NULL; -static PyTypeObject *PCT_CounterBEType = NULL; -static PyTypeObject *PCT_CounterLEType = NULL; - typedef struct { PyObject_HEAD @@ -67,7 +72,14 @@ typedef struct /* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C. * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize */ +#ifdef IS_PY3K +static PyTypeObject ALGtype; +#define is_ALGobject(v) (Py_TYPE(v) == &ALGtype) +#else staticforward PyTypeObject ALGtype; +#define is_ALGobject(v) ((v)->ob_type == &ALGtype) +#define PyLong_FromLong PyInt_FromLong /* For Python 2.x */ +#endif static ALGobject * newALGobject(void) @@ -84,7 +96,6 @@ static void ALGdealloc(PyObject *ptr) { ALGobject *self = (ALGobject *)ptr; - block_finalize(&self->st); /* Overwrite the contents of the object */ Py_XDECREF(self->counter); @@ -159,17 +170,6 @@ ALGnew(PyObject *self, PyObject *args, PyObject *kwdict) "Key cannot be the null string"); return NULL; } - if (IVlen != 0 && mode == MODE_ECB) - { - PyErr_Format(PyExc_ValueError, "ECB mode does not use IV"); - return NULL; - } - if (IVlen != 0 && mode == MODE_CTR) - { - PyErr_Format(PyExc_ValueError, - "CTR mode needs counter parameter, not IV"); - return NULL; - } if (IVlen != BLOCK_SIZE && mode != MODE_ECB && mode != MODE_CTR) { PyErr_Format(PyExc_ValueError, @@ -192,7 +192,11 @@ ALGnew(PyObject *self, PyObject *args, PyObject *kwdict) PyErr_SetString(PyExc_TypeError, "'counter' keyword parameter is required with CTR mode"); return NULL; - } else if (Py_TYPE(counter) == PCT_CounterBEType || Py_TYPE(counter) == PCT_CounterLEType) { +#ifdef IS_PY3K + } else if (PyObject_HasAttr(counter, PyUnicode_FromString("__PCT_CTR_SHORTCUT__"))) { +#else + } else if (PyObject_HasAttrString(counter, "__PCT_CTR_SHORTCUT__")) { +#endif counter_shortcut = 1; } else if (!PyCallable_Check(counter)) { PyErr_SetString(PyExc_ValueError, @@ -260,7 +264,6 @@ ALG_Encrypt(ALGobject *self, PyObject *args) } if ( (len % BLOCK_SIZE) !=0 && (self->mode!=MODE_CFB) && - (self->mode!=MODE_OFB) && (self->mode!=MODE_CTR)) { PyErr_Format(PyExc_ValueError, @@ -335,48 +338,15 @@ ALG_Encrypt(ALGobject *self, PyObject *args) break; case(MODE_OFB): - /* OFB mode is a stream cipher whose keystream is generated by encrypting the previous ciphered output. - * - self->IV stores the current keystream block - * - self->count indicates the current offset within the current keystream block - * - str stores the input string - * - buffer stores the output string - * - len indicates the length of the input and output strings - * - i indicates the current offset within the input and output strings - * (len-i) is the number of bytes remaining to encrypt - * (BLOCK_SIZE-self->count) is the number of bytes remaining in the current keystream block - */ - i = 0; - while(i < len) + for(i=0; icount) { /* remaining_bytes_to_encrypt <= remaining_bytes_in_IV */ - /* XOR until the input is used up */ - for(j=0; j<(len-i); j++) { - assert(i+j < len); - assert(self->count+j < BLOCK_SIZE); - buffer[i+j] = self->IV[self->count+j] ^ str[i+j]; - } - self->count += len-i; - i = len; - continue; - } - - /* Use up the current keystream block */ - for(j=0; jcount; j++) { - assert(i+j < len); - assert(self->count+j < BLOCK_SIZE); - buffer[i+j] = self->IV[self->count+j] ^ str[i+j]; - } - i += BLOCK_SIZE-self->count; - self->count = BLOCK_SIZE; - - /* Generate a new keystream block */ block_encrypt(&(self->st), self->IV, temp); memcpy(self->IV, temp, BLOCK_SIZE); - - /* Move the pointer to the start of the keystream */ - self->count = 0; - } + for(j=0; jbuf_size, BLOCK_SIZE); + "string not of length %i", + BLOCK_SIZE); free(buffer); return NULL; } @@ -454,7 +424,11 @@ ALG_Encrypt(ALGobject *self, PyObject *args) if (!PyBytes_Check(ctr)) { PyErr_SetString(PyExc_TypeError, - "CTR counter function didn't return a bytestring"); +#ifdef IS_PY3K + "CTR counter function didn't return bytes"); +#else + "CTR counter function didn't return a string"); +#endif Py_DECREF(ctr); free(buffer); return NULL; @@ -462,7 +436,11 @@ ALG_Encrypt(ALGobject *self, PyObject *args) if (PyBytes_Size(ctr) != BLOCK_SIZE) { PyErr_Format(PyExc_TypeError, "CTR counter function returned " - "bytestring not of length %i", +#ifdef IS_PY3K + "bytes not of length %i", +#else + "string not of length %i", +#endif BLOCK_SIZE); Py_DECREF(ctr); free(buffer); @@ -510,8 +488,8 @@ ALG_Decrypt(ALGobject *self, PyObject *args) int i, j, len; PyObject *result; - /* CTR and OFB mode decryption is identical to encryption */ - if (self->mode == MODE_CTR || self->mode == MODE_OFB) + /* CTR mode decryption is identical to encryption */ + if (self->mode == MODE_CTR) return ALG_Encrypt(self, args); if (!PyArg_Parse(args, "s#", &str, &len)) @@ -593,6 +571,18 @@ ALG_Decrypt(ALGobject *self, PyObject *args) } break; + case (MODE_OFB): + for(i=0; ist), self->IV, temp); + memcpy(self->IV, temp, BLOCK_SIZE); + for(j=0; jIV[j]; + } + } + break; + default: Py_BLOCK_THREADS; PyErr_Format(PyExc_SystemError, @@ -611,8 +601,13 @@ ALG_Decrypt(ALGobject *self, PyObject *args) /* ALG object methods */ static PyMethodDef ALGmethods[] = { +#ifdef IS_PY3K {"encrypt", (PyCFunction) ALG_Encrypt, METH_O, ALG_Encrypt__doc__}, {"decrypt", (PyCFunction) ALG_Decrypt, METH_O, ALG_Decrypt__doc__}, +#else + {"encrypt", (PyCFunction) ALG_Encrypt, 0, ALG_Encrypt__doc__}, + {"decrypt", (PyCFunction) ALG_Decrypt, 0, ALG_Decrypt__doc__}, +#endif {NULL, NULL} /* sentinel */ }; @@ -636,7 +631,11 @@ ALGsetattr(PyObject *ptr, char *name, PyObject *v) if (!PyBytes_Check(v)) { PyErr_SetString(PyExc_TypeError, - "IV attribute of block cipher object must be bytestring"); +#ifdef IS_PY3K + "IV attribute of block cipher object must be bytes"); +#else + "IV attribute of block cipher object must be string"); +#endif return -1; } if (PyBytes_Size(v)!=BLOCK_SIZE) @@ -651,38 +650,54 @@ ALGsetattr(PyObject *ptr, char *name, PyObject *v) } static PyObject * +#ifdef IS_PY3K ALGgetattro(PyObject *s, PyObject *attr) +#else +ALGgetattr(PyObject *s, char *name) +#endif { ALGobject *self = (ALGobject*)s; - if (!PyString_Check(attr)) +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) goto generic; - if (PyString_CompareWithASCIIString(attr, "IV") == 0) + if (PyUnicode_CompareWithASCIIString(attr, "IV") == 0) +#else + if (strcmp(name, "IV") == 0) +#endif { return(PyBytes_FromStringAndSize((char *) self->IV, BLOCK_SIZE)); } - if (PyString_CompareWithASCIIString(attr, "mode") == 0) +#ifdef IS_PY3K + if (PyUnicode_CompareWithASCIIString(attr, "mode") == 0) +#else + if (strcmp(name, "mode") == 0) +#endif { - return(PyInt_FromLong((long)(self->mode))); + return(PyLong_FromLong((long)(self->mode))); } - if (PyString_CompareWithASCIIString(attr, "block_size") == 0) +#ifdef IS_PY3K + if (PyUnicode_CompareWithASCIIString(attr, "block_size") == 0) +#else + if (strcmp(name, "block_size") == 0) +#endif { - return PyInt_FromLong(BLOCK_SIZE); + return PyLong_FromLong(BLOCK_SIZE); } - if (PyString_CompareWithASCIIString(attr, "key_size") == 0) +#ifdef IS_PY3K + if (PyUnicode_CompareWithASCIIString(attr, "key_size") == 0) +#else + if (strcmp(name, "key_size") == 0) +#endif { - return PyInt_FromLong(KEY_SIZE); + return PyLong_FromLong(KEY_SIZE); } +#ifdef IS_PY3K generic: -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ return PyObject_GenericGetAttr(s, attr); #else - if (PyString_Check(attr) < 0) { - PyErr_SetObject(PyExc_AttributeError, attr); - return NULL; - } - return Py_FindMethod(ALGmethods, (PyObject *)self, PyString_AsString(attr)); + return Py_FindMethod(ALGmethods, (PyObject *) self, name); #endif } @@ -696,18 +711,28 @@ static struct PyMethodDef modulemethods[] = static PyTypeObject ALGtype = { +#ifdef IS_PY3K PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ +#endif _MODULE_STRING, /*tp_name*/ sizeof(ALGobject), /*tp_size*/ 0, /*tp_itemsize*/ /* methods */ (destructor) ALGdealloc, /*tp_dealloc*/ 0, /*tp_print*/ +#ifdef IS_PY3K 0, /*tp_getattr*/ +#else + ALGgetattr, /*tp_getattr*/ +#endif ALGsetattr, /*tp_setattr*/ 0, /*tp_compare*/ (reprfunc) 0, /*tp_repr*/ 0, /*tp_as_number*/ +#ifdef IS_PY3K 0, /*tp_as_sequence */ 0, /*tp_as_mapping */ 0, /*tp_hash*/ @@ -722,7 +747,6 @@ static PyTypeObject ALGtype = 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ 0, /*tp_iter*/ 0, /*tp_iternext*/ ALGmethods, /*tp_methods*/ @@ -744,30 +768,39 @@ static struct PyModuleDef moduledef = { #endif /* Initialization function for the module */ + +/* Deal with old API in Python 2.1 */ +#if PYTHON_API_VERSION < 1011 +#define PyModule_AddIntConstant(m,n,v) {PyObject *o=PyInt_FromLong(v); \ + if (o!=NULL) \ + {PyDict_SetItemString(PyModule_GetDict(m),n,o); Py_DECREF(o);}} +#endif + + +#ifdef IS_PY3K PyMODINIT_FUNC +#else +void +#endif _MODULE_NAME (void) { - PyObject *m = NULL; - PyObject *abiver = NULL; - PyObject *__all__ = NULL; + PyObject *m; +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ if (PyType_Ready(&ALGtype) < 0) - goto errout; + return NULL; /* Create the module and add the functions */ -#ifdef IS_PY3K m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; #else + ALGtype.ob_type = &PyType_Type; + /* Create the module and add the functions */ m = Py_InitModule("Crypto.Cipher." _MODULE_STRING, modulemethods); #endif - if (m == NULL) - goto errout; - /* Add the type object to the module (using the name of the module itself), - * so that its methods docstrings are discoverable by introspection tools. */ - PyObject_SetAttrString(m, _MODULE_STRING, (PyObject *)&ALGtype); - - /* Add some symbolic constants to the module */ PyModule_AddIntConstant(m, "MODE_ECB", MODE_ECB); PyModule_AddIntConstant(m, "MODE_CBC", MODE_CBC); PyModule_AddIntConstant(m, "MODE_CFB", MODE_CFB); @@ -777,65 +810,12 @@ _MODULE_NAME (void) PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE); PyModule_AddIntConstant(m, "key_size", KEY_SIZE); - /* Import CounterBE and CounterLE from the _counter module */ - Py_CLEAR(_counter_module); - _counter_module = PyImport_ImportModule("Crypto.Util._counter"); - if (_counter_module == NULL) - goto errout; - PCT_CounterBEType = (PyTypeObject *)PyObject_GetAttrString(_counter_module, "CounterBE"); - PCT_CounterLEType = (PyTypeObject *)PyObject_GetAttrString(_counter_module, "CounterLE"); - - /* Simple ABI version check in case the user doesn't re-compile all of - * the modules during an upgrade. */ - abiver = PyObject_GetAttrString(_counter_module, "_PCT_CTR_ABI_VERSION"); - if (PCT_CounterBEType == NULL || PyType_Check((PyObject *)PCT_CounterBEType) < 0 || - PCT_CounterLEType == NULL || PyType_Check((PyObject *)PCT_CounterLEType) < 0 || - abiver == NULL || PyInt_CheckExact(abiver) < 0 || PyInt_AS_LONG(abiver) != PCT_CTR_ABI_VERSION) - { - PyErr_SetString(PyExc_ImportError, "Crypto.Util._counter ABI mismatch. Was PyCrypto incorrectly compiled?"); - goto errout; - } - - /* Create __all__ (to help generate documentation) */ - __all__ = PyList_New(10); - if (__all__ == NULL) - goto errout; - PyList_SetItem(__all__, 0, PyString_FromString(_MODULE_STRING)); /* This is the ALGType object */ - PyList_SetItem(__all__, 1, PyString_FromString("new")); - PyList_SetItem(__all__, 2, PyString_FromString("MODE_ECB")); - PyList_SetItem(__all__, 3, PyString_FromString("MODE_CBC")); - PyList_SetItem(__all__, 4, PyString_FromString("MODE_CFB")); - PyList_SetItem(__all__, 5, PyString_FromString("MODE_PGP")); - PyList_SetItem(__all__, 6, PyString_FromString("MODE_OFB")); - PyList_SetItem(__all__, 7, PyString_FromString("MODE_CTR")); - PyList_SetItem(__all__, 8, PyString_FromString("block_size")); - PyList_SetItem(__all__, 9, PyString_FromString("key_size")); - PyObject_SetAttrString(m, "__all__", __all__); - -out: - /* Final error check */ - if (m == NULL && !PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "can't initialize module"); - goto errout; - } - - /* Free local objects here */ - Py_CLEAR(abiver); - Py_CLEAR(__all__); + /* Check for errors */ + if (PyErr_Occurred()) + Py_FatalError("can't initialize module " _MODULE_STRING); - /* Return */ #ifdef IS_PY3K return m; -#else - return; #endif - -errout: - /* Free the module and other global objects here */ - Py_CLEAR(m); - Py_CLEAR(_counter_module); - Py_CLEAR(PCT_CounterBEType); - Py_CLEAR(PCT_CounterLEType); - goto out; } /* vim:set ts=4 sw=4 sts=0 noexpandtab: */ diff --git a/src/cast5.c b/src/cast5.c index a86615e1..0843b98d 100644 --- a/src/cast5.c +++ b/src/cast5.c @@ -2,7 +2,6 @@ These are the S-boxes for CAST5 as given in RFC 2144. */ -#include "pycrypto_common.h" static const uint32 S1[256] = { 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, diff --git a/src/config.h.in b/src/config.h.in index f18fcb08..514c060e 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -1,11 +1,5 @@ /* src/config.h.in. Generated from configure.ac by autoheader. */ -/* Define to 1 if you have the `aligned_alloc' function. */ -#undef HAVE_ALIGNED_ALLOC - -/* Define to 1 if you have the header file. */ -#undef HAVE_CPUID_H - /* Define to 1 if you have the declaration of `mpz_powm', and to 0 if you don't. */ #undef HAVE_DECL_MPZ_POWM @@ -26,9 +20,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_LIMITS_H -/* Define if CC supports -maes */ -#undef HAVE_MAES - /* Define to 1 if your system has a GNU libc compatible `malloc' function, and to 0 otherwise. */ #undef HAVE_MALLOC @@ -42,9 +33,6 @@ /* Define to 1 if you have the `memset' function. */ #undef HAVE_MEMSET -/* Define to 1 if you have the `posix_memalign' function. */ -#undef HAVE_POSIX_MEMALIGN - /* Define to 1 if you have the header file. */ #undef HAVE_STDDEF_H @@ -60,30 +48,18 @@ /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_INTTYPES_H - /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H -/* Define to 1 if the system has the type `uintptr_t'. */ -#undef HAVE_UINTPTR_T - /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_WCHAR_H -/* Define to 1 if you have the header file. */ -#undef HAVE_WMMINTRIN_H - -/* Define to 1 if you have the `_aligned_malloc' function. */ -#undef HAVE__ALIGNED_MALLOC - /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT @@ -163,7 +139,3 @@ /* Define to the type of an unsigned integer type of width exactly 8 bits if such a type exists and the standard includes do not define it. */ #undef uint8_t - -/* Define to the type of an unsigned integer type wide enough to hold a - pointer, if such a type exists, and if the system does not define it. */ -#undef uintptr_t diff --git a/src/cpuid.c b/src/cpuid.c deleted file mode 100644 index 46ece7df..00000000 --- a/src/cpuid.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * cpuid.c: check CPU capabilities - * - * Written in 2013 by Sebastian Ramacher - * - * =================================================================== - * The contents of this file are dedicated to the public domain. To - * the extent that dedication to the public domain is not available, - * everyone is granted a worldwide, perpetual, royalty-free, - * non-exclusive license to exercise all rights associated with the - * contents of this file for any purpose whatsoever. - * No rights are reserved. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * =================================================================== - */ -#include "Python.h" -#include -#include "config.h" - -#ifdef HAVE_CPUID_H -#include - -/* it's bit_AES with gcc */ -#ifndef bit_AES -/* but some versions of clang provide bit_AESNI instead */ -#ifdef bit_AESNI -#define bit_AES bit_AESNI -/* and others do not provide any define at all */ -#else -#define bit_AES 0x02000000 -#endif -#endif - -#endif - -#include "pycrypto_compat.h" - -/* - * The have_aes_ni Python function - */ - -static char have_aes_ni__doc__[] = -"have_aes_ni() -> bool\n" -"\n" -"Return whether AES-NI instructions are available.\n"; - -static PyObject * -have_aes_ni(PyObject *self, PyObject *args) -{ - if (!PyArg_ParseTuple(args, "")) - return NULL; - -#ifndef HAVE_CPUID_H - Py_INCREF(Py_False); - return Py_False; -#else - uint32_t eax, ebx, ecx, edx; - /* call cpuid to check if AES-NI instructions are available */ - if (__get_cpuid(1, &eax, &ebx, &ecx, &edx)) { - if (ecx & bit_AES) { - Py_INCREF(Py_True); - return Py_True; - } - } - Py_INCREF(Py_False); - return Py_False; -#endif -} - -/* - * Module-level method table and module initialization function - */ - -static PyMethodDef cpuid_methods[] = { - {"have_aes_ni", have_aes_ni, METH_VARARGS, have_aes_ni__doc__}, - {NULL, NULL, 0, NULL} /* end-of-list sentinel value */ -}; - -#ifdef IS_PY3K -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "cpuid", - NULL, - -1, - cpuid_methods, - NULL, - NULL, - NULL, - NULL -}; -#endif - -PyMODINIT_FUNC -#ifdef IS_PY3K -PyInit_cpuid(void) -#else -initcpuid(void) -#endif -{ - /* Initialize the module */ -#ifdef IS_PY3K - return PyModule_Create(&moduledef); -#else - Py_InitModule("cpuid", cpuid_methods); -#endif -} - -/* vim:set ts=4 sw=4 sts=4 expandtab: */ diff --git a/src/galois.c b/src/galois.c deleted file mode 100644 index 80d2d9b5..00000000 --- a/src/galois.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * galois.c: arithmetic in Galois Fields - * - * =================================================================== - * The contents of this file are dedicated to the public domain. To - * the extent that dedication to the public domain is not available, - * everyone is granted a worldwide, perpetual, royalty-free, - * non-exclusive license to exercise all rights associated with the - * contents of this file for any purpose whatsoever. - * No rights are reserved. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * =================================================================== - */ - -#include "pycrypto_common.h" -#include -#include -#include - -#define ALIGNMENT 32 - -/** - * A V table is a 4096 bytes table that will contain the expanded - * GHASH key (H). It is used to speed up the GF(128) multiplication Z = X*H. - * - * The table contains 128 entries, one for each bit of X. - * Each entry takes 32 bytes and can fit into the cache line of a modern - * processor. If we assume that access to memory mapped to the same - * cache line is somewhat constant, we can make GHASH robust again - * cache timing attacks. - */ -typedef uint64_t t_v_tables[128][2][2]; - -/** - * To ensure that the V table is aligned to a 32-byte memory boundary, - * we allocate a larger piece of memory and carve the V table from there. - */ -typedef struct { - uint8_t buffer[sizeof(t_v_tables)+ALIGNMENT]; - int offset; -} t_exp_key; - -/** - * Big Endian to word conversions - */ -static uint64_t be_to_word(const uint8_t fb[8]) -{ - uint64_t tmp; - int i; - tmp = 0; - for (i=0; i<8; i++) - tmp = tmp<<8 ^ *fb++; - return tmp; -} - -/** - * Word to Big Endian conversions - */ -static void word_to_be(uint8_t fb[8], uint64_t w) -{ - int i; - for (i=0; i<8; i++) { - fb[7-i] = (uint8_t) w; - w >>= 8; - } -} - -/** - * Create a V table. V[i] is the value H*x^i (i=0..127). - * \param h The 16 byte GHASH key - * \param tables A pointer to an allocated V table - */ -static void make_v_tables(const uint8_t h[16], t_v_tables *tables) -{ - uint64_t (*cur)[2]; - int i; - - memset(tables, 0, sizeof(t_v_tables)); - - cur = &((*tables)[0][1]); - - (*cur)[0] = be_to_word(&h[0]); - (*cur)[1] = be_to_word(&h[8]); - - for (i=1; i<128; i++) { - uint64_t c; - uint64_t (*next)[2]; - - next = &((*tables)[i][1]); - - /** v = (v&1)*0xE1000000000000000000000000000000L ^ (v>>1) **/ - c = (*cur)[1]&1 ? 0xE100000000000000 : 0; - (*next)[1] = (*cur)[1]>>1 | (*cur)[0]<<63; - (*next)[0] = (*cur)[0]>>1 ^ c; - - cur = next; - } -} - -/** - * Multiply two elements of GF(2**128) using the reducing polynomial - * (x^128 + x^7 + x^2 + x + 1). - * - * \param out The 16 byte buffer that will receive the result - * \param key_tables One factor, expanded into a V table - * \param x The other factor (16 bytes) - */ -static void gcm_mult2(uint8_t out[16], const t_v_tables *key_tables, const uint8_t x[16]) -{ - int i, bit_scan_128; - uint64_t z[2]; - - z[0] = z[1] = 0; - bit_scan_128 = 0; - for (i=0; i<16; i++) { - uint8_t xi; - int j; - - xi = x[i]; - for (j=0; j<8; j++) { - int bit; - - bit = xi>>7 & 1; /** Constant time */ - z[0] ^= (*key_tables)[bit_scan_128][bit][0]; - z[1] ^= (*key_tables)[bit_scan_128][bit][1]; - - xi <<= 1; - bit_scan_128++; - } - } - - word_to_be(out, z[0]); - word_to_be(out+8, z[1]); -} - - -/** - * Compute the GHASH of a piece of data given an arbitrary Y_0, - * as specified in NIST SP 800 38D. - * - * \param y_out The resulting GHASH (16 bytes). - * \param block_data Pointer to the data to hash. - * \param len Length of the data to hash (multiple of 16). - * \param y_in The initial Y (Y_0, 16 bytes). - * \param key_tables The expanded hash key (16*256*16 bytes). - */ -static void ghash( - uint8_t y_out[16], - const uint8_t block_data[], - int len, - const uint8_t y_in[16], - const t_v_tables *key_tables - ) -{ - int i; - - memcpy(y_out, y_in, 16); - for (i=0; ibuffer & (ALIGNMENT-1)); - if (new_offset != exp_key->offset) { - memmove(exp_key->buffer+new_offset, - exp_key->buffer+exp_key->offset, - sizeof(t_v_tables)); - exp_key->offset = new_offset; - } -} - -static char ghash_expand__doc__[] = -"ghash_expand(h:str) -> str\n" -"\n" -"Return an expanded GHASH key.\n"; - -/** - * Expand the AES key into a Python (byte) string object. - */ -static PyObject * -ghash_expand_function(PyObject *self, PyObject *args) -{ - PyObject *h; - PyObject *retval = NULL; - Py_ssize_t len_h; - t_exp_key *exp_key; - - if (!PyArg_ParseTuple(args, "S", &h)) { - goto out; - } - - len_h = PyBytes_GET_SIZE(h); - - if (len_h!=16) { - PyErr_SetString(PyExc_ValueError, "Length of h must be 16 bytes."); - goto out; - } - - exp_key = calloc(1, sizeof(t_exp_key)); - if (!exp_key) { - goto out; - } - - Py_BEGIN_ALLOW_THREADS; - - exp_key->offset = ALIGNMENT - ((uintptr_t)exp_key->buffer & (ALIGNMENT-1)); - make_v_tables((uint8_t*)PyBytes_AS_STRING(h), - (t_v_tables*)(exp_key->buffer + exp_key->offset)); - - Py_END_ALLOW_THREADS; - - retval = PyBytes_FromStringAndSize((const char*)exp_key, sizeof *exp_key); - free(exp_key); - -out: - return retval; -} - - -static char ghash__doc__[] = -"ghash(data:str, y:str, exp_key:str) -> str\n" -"\n" -"Return a GHASH.\n"; - -static PyObject * -ghash_function(PyObject *self, PyObject *args) -{ - PyObject *data, *y, *exp_key_serial; - PyObject *retval = NULL; - Py_ssize_t len_data, len_y, len_exp_key_serial; - const t_v_tables *v_tables; - t_exp_key *exp_key; - - if (!PyArg_ParseTuple(args, "SSS", &data, &y, &exp_key_serial)) { - goto out; - } - - len_data = PyBytes_GET_SIZE(data); - len_y = PyBytes_GET_SIZE(y); - len_exp_key_serial = PyBytes_GET_SIZE(exp_key_serial); - - if (len_data%16!=0) { - PyErr_SetString(PyExc_ValueError, "Length of data must be a multiple of 16 bytes."); - goto out; - } - - if (len_y!=16) { - PyErr_SetString(PyExc_ValueError, "Length of y must be 16 bytes."); - goto out; - } - - if (len_exp_key_serial!=sizeof(t_exp_key)) { - PyErr_SetString(PyExc_ValueError, "Length of expanded key is incorrect."); - goto out; - } - - /* Create return string */ - retval = PyBytes_FromStringAndSize(NULL, 16); - if (!retval) { - goto out; - } - - Py_BEGIN_ALLOW_THREADS; - -#define PyBytes_Buffer(a) (uint8_t*)PyBytes_AS_STRING(a) - - exp_key = (t_exp_key *)PyBytes_AS_STRING(exp_key_serial); - realign_v_tables(exp_key); - v_tables = (const t_v_tables*)(exp_key->buffer + exp_key->offset); - ghash( PyBytes_Buffer(retval), PyBytes_Buffer(data), len_data, - PyBytes_Buffer(y), v_tables); - -#undef PyBytes_Buffer - - Py_END_ALLOW_THREADS; - -out: - return retval; -} - -/* - * Module-level method table and module initialization function - */ - -static PyMethodDef galois_methods[] = { - {"ghash_expand", ghash_expand_function, METH_VARARGS, ghash_expand__doc__}, - {"ghash", ghash_function, METH_VARARGS, ghash__doc__}, - {NULL, NULL, 0, NULL} /* end-of-list sentinel value */ -}; - -#ifdef IS_PY3K - -static struct PyModuleDef moduledef = { - PyModuleDef_HEAD_INIT, - "_galois", - "Arithmetic in Galois Fields", - -1, - galois_methods, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit__galois(void) -{ - PyObject *m; - - /* Initialize the module */ - m = PyModule_Create(&moduledef); - if (m == NULL) - return NULL; - return m; -} - -#else - -PyMODINIT_FUNC -init_galois(void) -{ - PyObject *m; - - /* Initialize the module */ - m = Py_InitModule("_galois", galois_methods); - if (m == NULL) - return; -} - -#endif diff --git a/src/hash_SHA2.h b/src/hash_SHA2.h index a3b633da..58671916 100644 --- a/src/hash_SHA2.h +++ b/src/hash_SHA2.h @@ -26,8 +26,6 @@ #ifndef __HASH_SHA2_H #define __HASH_SHA2_H -#include "pycrypto_common.h" - /* check if implementation set the correct macros */ #ifndef MODULE_NAME #error SHA2 Implementation must define MODULE_NAME before including this header @@ -69,10 +67,22 @@ #define ROTR(x, n) (((x)>>((n)&(WORD_SIZE_BITS-1)))|((x)<<(WORD_SIZE_BITS-((n)&(WORD_SIZE_BITS-1))))) #define SHR(x, n) ((x)>>(n)) -/* define fixed size types */ +/* determine fixed size types */ +#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +#include typedef uint8_t U8; typedef uint32_t U32; typedef uint64_t U64; +#elif defined(_MSC_VER) +typedef unsigned char U8; +typedef unsigned __int64 U64; +typedef unsigned int U32; +#elif defined(__sun) || defined(__sun__) +#include +typedef uint8_t U8; +typedef uint32_t U32; +typedef uint64_t U64; +#endif /* typedef a sha2_word_t type of appropriate size */ #if (WORD_SIZE_BITS == 64) diff --git a/src/hash_SHA2_template.c b/src/hash_SHA2_template.c index c7b8a13c..81b1ea67 100644 --- a/src/hash_SHA2_template.c +++ b/src/hash_SHA2_template.c @@ -30,7 +30,8 @@ * */ -#include "pycrypto_common.h" +#include "Python.h" +#include "pycrypto_compat.h" /* compress one block */ static void sha_compress(hash_state * hs) @@ -86,7 +87,7 @@ static void sha_compress(hash_state * hs) * return 1 on success * return 0 if the length overflows */ -static int add_length(hash_state *hs, sha2_word_t inc) { +int add_length(hash_state *hs, sha2_word_t inc) { sha2_word_t overflow_detector; overflow_detector = hs->length_lower; hs->length_lower += inc; diff --git a/src/hash_template.c b/src/hash_template.c index fa5a1b6f..eb27e9f0 100644 --- a/src/hash_template.c +++ b/src/hash_template.c @@ -24,8 +24,14 @@ /* Basic object type */ -#include "pycrypto_common.h" +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef _HAVE_STDC_HEADERS #include +#endif +#include "Python.h" +#include "pycrypto_compat.h" #define _STR(x) #x #define _XSTR(x) _STR(x) @@ -46,10 +52,14 @@ typedef struct { /* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C. * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize */ +#ifdef IS_PY3K +static PyTypeObject ALGtype; +#define is_ALGobject(v) (Py_TYPE(v) == &ALGtype) +#else staticforward PyTypeObject ALGtype; - -static char ALG__doc__[] = -"Class that implements a " _MODULE_STRING " hash."; +#define is_ALGobject(v) ((v)->ob_type == &ALGtype) +#define PyLong_FromLong PyInt_FromLong /* For Python 2.x */ +#endif static ALGobject * newALGobject(void) @@ -75,16 +85,8 @@ ALG_dealloc(PyObject *ptr) /* External methods for a hashing object */ -static char ALG_copy__doc__[] = -"copy()\n" -"Return a copy (\"clone\") of the hash object.\n" -"\n" -"The copy will have the same internal state as the original hash\n" -"object.\n" -"This can be used to efficiently compute the digests of strings that\n" -"share a common initial substring.\n" -"\n" -":Return: A hash object of the same type\n"; +static char ALG_copy__doc__[] = +"copy(): Return a copy of the hashing object."; static PyObject * ALG_copy(ALGobject *self, PyObject *args) @@ -102,15 +104,8 @@ ALG_copy(ALGobject *self, PyObject *args) return((PyObject *)newobj); } -static char ALG_digest__doc__[] = -"digest()\n" -"Return the **binary** (non-printable) digest of the message that has been hashed so far.\n" -"\n" -"This method does not change the state of the hash object.\n" -"You can continue updating the object after calling this function.\n" -"\n" -":Return: A byte string of `digest_size` bytes. It may contain non-ASCII\n" -"characters, including null bytes.\n"; +static char ALG_digest__doc__[] = +"digest(): Return the digest value as a string of binary data."; static PyObject * ALG_digest(ALGobject *self, PyObject *args) @@ -121,14 +116,8 @@ ALG_digest(ALGobject *self, PyObject *args) return (PyObject *)hash_digest(&(self->st)); } -static char ALG_hexdigest__doc__[] = -"hexdigest()\n" -"Return the **printable** digest of the message that has been hashed so far.\n" -"\n" -"This method does not change the state of the hash object.\n" -"\n" -":Return: A string of 2* `digest_size` characters. It contains only\n" -"hexadecimal ASCII digits.\n"; +static char ALG_hexdigest__doc__[] = +"hexdigest(): Return the digest value as a string of hexadecimal digits."; static PyObject * ALG_hexdigest(ALGobject *self, PyObject *args) @@ -167,22 +156,8 @@ ALG_hexdigest(ALGobject *self, PyObject *args) return retval; } -static char ALG_update__doc__[] = -"update(data)\n" -"Continue hashing of a message by consuming the next chunk of data.\n" -"\n" -"Repeated calls are equivalent to a single call with the concatenation\n" -"of all the arguments. In other words:\n" -"\n" -" >>> m.update(a); m.update(b)\n" -"\n" -"is equivalent to:\n" -"\n" -" >>> m.update(a+b)\n" -"\n" -":Parameters:\n" -" data : byte string\n" -" The next chunk of the message being hashed.\n"; +static char ALG_update__doc__[] = +"update(string): Update this hashing object's state with the provided string."; static PyObject * ALG_update(ALGobject *self, PyObject *args) @@ -205,16 +180,10 @@ ALG_update(ALGobject *self, PyObject *args) /** Forward declaration for this module's new() method **/ static char ALG_new__doc__[] = -"new(data=None)\n" -"Return a fresh instance of the hash object.\n" -"\n" -":Parameters:\n" -" data : byte string\n" -" The very first chunk of the message to hash.\n" -" It is equivalent to an early call to `" _MODULE_STRING ".update()`.\n" -" Optional.\n" -"\n" -":Return: A `" _MODULE_STRING "` object\n"; +"new([string]): Return a new " _MODULE_STRING +" hashing object. An optional string " +"argument may be provided; if present, this string will be " +"automatically hashed into the initial state of the object."; static PyObject *ALG_new(PyObject*, PyObject*); @@ -228,41 +197,54 @@ static PyMethodDef ALG_methods[] = { }; static PyObject * +#ifdef IS_PY3K ALG_getattro(PyObject *self, PyObject *attr) +#else +ALG_getattr(PyObject *self, char *name) +#endif { - if (!PyString_Check(attr)) +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) goto generic; - - if (PyString_CompareWithASCIIString(attr, "digest_size")==0) + + if (PyUnicode_CompareWithASCIIString(attr, "digest_size")==0) + return PyLong_FromLong(DIGEST_SIZE); +#else + if (strcmp(name, "digest_size")==0) return PyInt_FromLong(DIGEST_SIZE); - if (PyString_CompareWithASCIIString(attr, "name")==0) - return PyString_FromString(_MODULE_STRING); /* we should try to be compatible with hashlib here */ +#endif +#ifdef IS_PY3K generic: -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ return PyObject_GenericGetAttr(self, attr); #else - if (PyString_Check(attr) < 0) { - PyErr_SetObject(PyExc_AttributeError, attr); - return NULL; - } - return Py_FindMethod(ALG_methods, (PyObject *)self, PyString_AsString(attr)); + return Py_FindMethod(ALG_methods, self, name); #endif } static PyTypeObject ALGtype = { +#ifdef IS_PY3K PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ +#endif _MODULE_STRING, /*tp_name*/ sizeof(ALGobject), /*tp_size*/ 0, /*tp_itemsize*/ /* methods */ (destructor) ALG_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ - 0, /*tp_getattr*/ +#ifdef IS_PY3K + 0, /*tp_getattr*/ +#else + ALG_getattr, /*tp_getattr*/ +#endif 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ +#ifdef IS_PY3K 0, /*tp_as_sequence */ 0, /*tp_as_mapping */ 0, /*tp_hash*/ @@ -272,12 +254,11 @@ static PyTypeObject ALGtype = { 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ - ALG__doc__, /*tp_doc*/ + 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ 0, /*tp_iter*/ 0, /*tp_iternext*/ ALG_methods, /*tp_methods*/ @@ -328,74 +309,58 @@ static struct PyMethodDef ALG_functions[] = { #ifdef IS_PY3K static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, - "Crypto.Hash." _MODULE_STRING, /* m_name */ - MODULE__doc__, /* m_doc */ - -1, /* m_size */ - ALG_functions, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL /* m_free */ + "Crypto.Hash." _MODULE_STRING, + NULL, + -1, + ALG_functions, + NULL, + NULL, + NULL, + NULL }; #endif /* Initialize this module. */ +/* Deal with old API in Python 2.1 */ +#if PYTHON_API_VERSION < 1011 +#define PyModule_AddIntConstant(m,n,v) {PyObject *o=PyInt_FromLong(v); \ + if (o!=NULL) \ + {PyDict_SetItemString(PyModule_GetDict(m),n,o); Py_DECREF(o);}} +#endif + +#ifdef IS_PY3K PyMODINIT_FUNC +#else +void +#endif _MODULE_NAME (void) { - PyObject *m = NULL; - PyObject *__all__ = NULL; + PyObject *m; +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ if (PyType_Ready(&ALGtype) < 0) - goto errout; + return NULL; /* Create the module and add the functions */ -#ifdef IS_PY3K m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; #else - m = Py_InitModule3("Crypto.Hash." _MODULE_STRING, ALG_functions, MODULE__doc__); + ALGtype.ob_type = &PyType_Type; + m = Py_InitModule("Crypto.Hash." _MODULE_STRING, ALG_functions); #endif - if (m == NULL) - goto errout; - - /* Add the type object to the module (using the name of the module itself), - * so that its methods docstrings are discoverable by introspection tools. */ - PyObject_SetAttrString(m, _MODULE_STRING, (PyObject *)&ALGtype); /* Add some symbolic constants to the module */ PyModule_AddIntConstant(m, "digest_size", DIGEST_SIZE); PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE); - /* Create __all__ (to help generate documentation) */ - __all__ = PyList_New(4); - if (__all__ == NULL) - goto errout; - PyList_SetItem(__all__, 0, PyString_FromString(_MODULE_STRING)); /* This is the ALGType object */ - PyList_SetItem(__all__, 1, PyString_FromString("new")); - PyList_SetItem(__all__, 2, PyString_FromString("digest_size")); - PyList_SetItem(__all__, 3, PyString_FromString("block_size")); - PyObject_SetAttrString(m, "__all__", __all__); - -out: - /* Final error check, then return */ - if (m == NULL && !PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "can't initialize module"); - goto errout; - } - - /* Free local objects here */ - Py_CLEAR(__all__); - - /* Return */ + /* Check for errors */ + if (PyErr_Occurred()) + Py_FatalError("can't initialize module " + _MODULE_STRING); #ifdef IS_PY3K return m; -#else - return; #endif - -errout: - /* Free the module and other global objects here */ - Py_CLEAR(m); - goto out; } diff --git a/src/inc-msvc/config.h b/src/inc-msvc/config.h index 2485df91..2b7a626f 100644 --- a/src/inc-msvc/config.h +++ b/src/inc-msvc/config.h @@ -14,10 +14,3 @@ /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to `__inline__' or `__inline' if that's what the C compiler - * calls it, or to nothing if 'inline' is not supported under any name. */ -#define inline __inline diff --git a/src/libtom/tomcrypt.h b/src/libtom/tomcrypt.h index 72ebdcb4..5e127dc6 100644 --- a/src/libtom/tomcrypt.h +++ b/src/libtom/tomcrypt.h @@ -16,8 +16,8 @@ extern "C" { #endif /* version */ -#define CRYPT 0x0117 -#define SCRYPT "1.17" +#define CRYPT 0x0116 +#define SCRYPT "1.16" /* max size of either a cipher/hash block or symmetric key [largest of the two] */ #define MAXBLOCKSIZE 128 @@ -83,5 +83,5 @@ enum { /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt.h,v $ */ -/* $Revision: 1.21 $ */ -/* $Date: 2006/12/16 19:34:05 $ */ +/* $Revision: 1.20 $ */ +/* $Date: 2006/11/26 01:45:14 $ */ diff --git a/src/libtom/tomcrypt_cipher.h b/src/libtom/tomcrypt_cipher.h index a4b3dcf3..e0cf94dc 100644 --- a/src/libtom/tomcrypt_cipher.h +++ b/src/libtom/tomcrypt_cipher.h @@ -3,41 +3,41 @@ * We put each of the ciphers scheduled keys in their own structs then we put all of * the key formats in one union. This makes the function prototypes easier to use. */ -#ifdef LTC_BLOWFISH +#ifdef BLOWFISH struct blowfish_key { ulong32 S[4][256]; ulong32 K[18]; }; #endif -#ifdef LTC_RC5 +#ifdef RC5 struct rc5_key { int rounds; ulong32 K[50]; }; #endif -#ifdef LTC_RC6 +#ifdef RC6 struct rc6_key { ulong32 K[44]; }; #endif -#ifdef LTC_SAFERP +#ifdef SAFERP struct saferp_key { unsigned char K[33][16]; long rounds; }; #endif -#ifdef LTC_RIJNDAEL +#ifdef RIJNDAEL struct rijndael_key { ulong32 eK[60], dK[60]; int Nr; }; #endif -#ifdef LTC_KSEED +#ifdef KSEED struct kseed_key { ulong32 K[32], dK[32]; }; @@ -51,14 +51,14 @@ struct kasumi_key { }; #endif -#ifdef LTC_XTEA +#ifdef XTEA struct xtea_key { unsigned long A[32], B[32]; }; #endif -#ifdef LTC_TWOFISH -#ifndef LTC_TWOFISH_SMALL +#ifdef TWOFISH +#ifndef TWOFISH_SMALL struct twofish_key { ulong32 S[4][256], K[40]; }; @@ -70,24 +70,24 @@ struct xtea_key { #endif #endif -#ifdef LTC_SAFER -#define LTC_SAFER_K64_DEFAULT_NOF_ROUNDS 6 -#define LTC_SAFER_K128_DEFAULT_NOF_ROUNDS 10 -#define LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS 8 -#define LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS 10 -#define LTC_SAFER_MAX_NOF_ROUNDS 13 -#define LTC_SAFER_BLOCK_LEN 8 -#define LTC_SAFER_KEY_LEN (1 + LTC_SAFER_BLOCK_LEN * (1 + 2 * LTC_SAFER_MAX_NOF_ROUNDS)) -typedef unsigned char safer_block_t[LTC_SAFER_BLOCK_LEN]; -typedef unsigned char safer_key_t[LTC_SAFER_KEY_LEN]; +#ifdef SAFER +#define SAFER_K64_DEFAULT_NOF_ROUNDS 6 +#define SAFER_K128_DEFAULT_NOF_ROUNDS 10 +#define SAFER_SK64_DEFAULT_NOF_ROUNDS 8 +#define SAFER_SK128_DEFAULT_NOF_ROUNDS 10 +#define SAFER_MAX_NOF_ROUNDS 13 +#define SAFER_BLOCK_LEN 8 +#define SAFER_KEY_LEN (1 + SAFER_BLOCK_LEN * (1 + 2 * SAFER_MAX_NOF_ROUNDS)) +typedef unsigned char safer_block_t[SAFER_BLOCK_LEN]; +typedef unsigned char safer_key_t[SAFER_KEY_LEN]; struct safer_key { safer_key_t key; }; #endif -#ifdef LTC_RC2 +#ifdef RC2 struct rc2_key { unsigned xkey[64]; }; #endif -#ifdef LTC_DES +#ifdef DES struct des_key { ulong32 ek[32], dk[32]; }; @@ -97,32 +97,32 @@ struct des3_key { }; #endif -#ifdef LTC_CAST5 +#ifdef CAST5 struct cast5_key { ulong32 K[32], keylen; }; #endif -#ifdef LTC_NOEKEON +#ifdef NOEKEON struct noekeon_key { ulong32 K[4], dK[4]; }; #endif -#ifdef LTC_SKIPJACK +#ifdef SKIPJACK struct skipjack_key { unsigned char key[10]; }; #endif -#ifdef LTC_KHAZAD +#ifdef KHAZAD struct khazad_key { ulong64 roundKeyEnc[8 + 1]; ulong64 roundKeyDec[8 + 1]; }; #endif -#ifdef LTC_ANUBIS +#ifdef ANUBIS struct anubis_key { int keyBits; int R; @@ -131,69 +131,59 @@ struct anubis_key { }; #endif -#ifdef LTC_MULTI2 -struct multi2_key { - int N; - ulong32 uk[8]; -}; -#endif - typedef union Symmetric_key { -#ifdef LTC_DES +#ifdef DES struct des_key des; struct des3_key des3; #endif -#ifdef LTC_RC2 +#ifdef RC2 struct rc2_key rc2; #endif -#ifdef LTC_SAFER +#ifdef SAFER struct safer_key safer; #endif -#ifdef LTC_TWOFISH +#ifdef TWOFISH struct twofish_key twofish; #endif -#ifdef LTC_BLOWFISH +#ifdef BLOWFISH struct blowfish_key blowfish; #endif -#ifdef LTC_RC5 +#ifdef RC5 struct rc5_key rc5; #endif -#ifdef LTC_RC6 +#ifdef RC6 struct rc6_key rc6; #endif -#ifdef LTC_SAFERP +#ifdef SAFERP struct saferp_key saferp; #endif -#ifdef LTC_RIJNDAEL +#ifdef RIJNDAEL struct rijndael_key rijndael; #endif -#ifdef LTC_XTEA +#ifdef XTEA struct xtea_key xtea; #endif -#ifdef LTC_CAST5 +#ifdef CAST5 struct cast5_key cast5; #endif -#ifdef LTC_NOEKEON +#ifdef NOEKEON struct noekeon_key noekeon; #endif -#ifdef LTC_SKIPJACK +#ifdef SKIPJACK struct skipjack_key skipjack; #endif -#ifdef LTC_KHAZAD +#ifdef KHAZAD struct khazad_key khazad; #endif -#ifdef LTC_ANUBIS +#ifdef ANUBIS struct anubis_key anubis; #endif -#ifdef LTC_KSEED +#ifdef KSEED struct kseed_key kseed; #endif #ifdef LTC_KASUMI struct kasumi_key kasumi; #endif -#ifdef LTC_MULTI2 - struct multi2_key multi2; -#endif void *data; } symmetric_key; @@ -267,11 +257,8 @@ typedef struct { blocklen, /** The padding offset */ padlen, - /** The mode (endianess) of the CTR, 0==little, 1==big */ - mode, - /** counter width */ - ctrlen; - + /** The mode (endianess) of the CTR, 0==little, 1==big */ + mode; /** The counter */ unsigned char ctr[MAXBLOCKSIZE], /** The pad used to encrypt/decrypt */ @@ -328,7 +315,7 @@ typedef struct { /** cipher descriptor table, last entry has "name == NULL" to mark the end of table */ -static struct ltc_cipher_descriptor { +extern struct ltc_cipher_descriptor { /** name of cipher */ char *name; /** internal ID */ @@ -501,7 +488,7 @@ static struct ltc_cipher_descriptor { unsigned char *tag, unsigned long *taglen, int direction); - /** Accelerated one shot LTC_OMAC + /** Accelerated one shot OMAC @param key The secret key @param keylen The key length (octets) @param in The message @@ -545,7 +532,7 @@ static struct ltc_cipher_descriptor { unsigned char *out, unsigned long *outlen); } cipher_descriptor[]; -#ifdef LTC_BLOWFISH +#ifdef BLOWFISH int blowfish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int blowfish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int blowfish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -555,7 +542,7 @@ int blowfish_keysize(int *keysize); extern const struct ltc_cipher_descriptor blowfish_desc; #endif -#ifdef LTC_RC5 +#ifdef RC5 int rc5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int rc5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int rc5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -565,7 +552,7 @@ int rc5_keysize(int *keysize); extern const struct ltc_cipher_descriptor rc5_desc; #endif -#ifdef LTC_RC6 +#ifdef RC6 int rc6_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int rc6_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int rc6_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -575,7 +562,7 @@ int rc6_keysize(int *keysize); extern const struct ltc_cipher_descriptor rc6_desc; #endif -#ifdef LTC_RC2 +#ifdef RC2 int rc2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int rc2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int rc2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -585,7 +572,7 @@ int rc2_keysize(int *keysize); extern const struct ltc_cipher_descriptor rc2_desc; #endif -#ifdef LTC_SAFERP +#ifdef SAFERP int saferp_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int saferp_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int saferp_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -595,7 +582,7 @@ int saferp_keysize(int *keysize); extern const struct ltc_cipher_descriptor saferp_desc; #endif -#ifdef LTC_SAFER +#ifdef SAFER int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); @@ -611,7 +598,7 @@ int safer_128_keysize(int *keysize); extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer_sk64_desc, safer_sk128_desc; #endif -#ifdef LTC_RIJNDAEL +#ifdef RIJNDAEL /* make aes an alias */ #define aes_setup rijndael_setup @@ -639,7 +626,7 @@ extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc; extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc; #endif -#ifdef LTC_XTEA +#ifdef XTEA int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int xtea_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int xtea_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -649,7 +636,7 @@ int xtea_keysize(int *keysize); extern const struct ltc_cipher_descriptor xtea_desc; #endif -#ifdef LTC_TWOFISH +#ifdef TWOFISH int twofish_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int twofish_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int twofish_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -659,7 +646,7 @@ int twofish_keysize(int *keysize); extern const struct ltc_cipher_descriptor twofish_desc; #endif -#ifdef LTC_DES +#ifdef DES static int des_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); static int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); static int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -672,10 +659,10 @@ static int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetri static int des3_test(void); static void des3_done(symmetric_key *skey); static int des3_keysize(int *keysize); -static const struct ltc_cipher_descriptor des_desc, des3_desc; +/* extern const struct ltc_cipher_descriptor des_desc, des3_desc; */ #endif -#ifdef LTC_CAST5 +#ifdef CAST5 int cast5_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int cast5_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int cast5_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -685,7 +672,7 @@ int cast5_keysize(int *keysize); extern const struct ltc_cipher_descriptor cast5_desc; #endif -#ifdef LTC_NOEKEON +#ifdef NOEKEON int noekeon_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int noekeon_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int noekeon_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -695,7 +682,7 @@ int noekeon_keysize(int *keysize); extern const struct ltc_cipher_descriptor noekeon_desc; #endif -#ifdef LTC_SKIPJACK +#ifdef SKIPJACK int skipjack_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int skipjack_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int skipjack_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -705,7 +692,7 @@ int skipjack_keysize(int *keysize); extern const struct ltc_cipher_descriptor skipjack_desc; #endif -#ifdef LTC_KHAZAD +#ifdef KHAZAD int khazad_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int khazad_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int khazad_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -715,7 +702,7 @@ int khazad_keysize(int *keysize); extern const struct ltc_cipher_descriptor khazad_desc; #endif -#ifdef LTC_ANUBIS +#ifdef ANUBIS int anubis_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int anubis_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int anubis_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -725,7 +712,7 @@ int anubis_keysize(int *keysize); extern const struct ltc_cipher_descriptor anubis_desc; #endif -#ifdef LTC_KSEED +#ifdef KSEED int kseed_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); int kseed_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); int kseed_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); @@ -745,17 +732,6 @@ int kasumi_keysize(int *keysize); extern const struct ltc_cipher_descriptor kasumi_desc; #endif - -#ifdef LTC_MULTI2 -int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); -int multi2_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric_key *skey); -int multi2_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric_key *skey); -int multi2_test(void); -void multi2_done(symmetric_key *skey); -int multi2_keysize(int *keysize); -extern const struct ltc_cipher_descriptor multi2_desc; -#endif - #ifdef LTC_ECB_MODE int ecb_start(int cipher, const unsigned char *key, int keylen, int num_rounds, symmetric_ECB *ecb); @@ -796,9 +772,9 @@ int cbc_done(symmetric_CBC *cbc); #ifdef LTC_CTR_MODE -#define CTR_COUNTER_LITTLE_ENDIAN 0x0000 -#define CTR_COUNTER_BIG_ENDIAN 0x1000 -#define LTC_CTR_RFC3686 0x2000 +#define CTR_COUNTER_LITTLE_ENDIAN 0 +#define CTR_COUNTER_BIG_ENDIAN 1 +#define LTC_CTR_RFC3686 2 int ctr_start( int cipher, const unsigned char *IV, @@ -848,34 +824,6 @@ int f8_done(symmetric_F8 *f8); int f8_test_mode(void); #endif -#ifdef LTC_XTS_MODE -typedef struct { - symmetric_key key1, key2; - int cipher; -} symmetric_xts; - -int xts_start( int cipher, - const unsigned char *key1, - const unsigned char *key2, - unsigned long keylen, - int num_rounds, - symmetric_xts *xts); - -int xts_encrypt( - const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - const unsigned char *tweak, - symmetric_xts *xts); -int xts_decrypt( - const unsigned char *ct, unsigned long ptlen, - unsigned char *pt, - const unsigned char *tweak, - symmetric_xts *xts); - -void xts_done(symmetric_xts *xts); -int xts_test(void); -void xts_mult_x(unsigned char *I); -#endif int find_cipher(const char *name); int find_cipher_any(const char *name, int blocklen, int keylen); @@ -887,5 +835,5 @@ int cipher_is_valid(int idx); LTC_MUTEX_PROTO(ltc_cipher_mutex) /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_cipher.h,v $ */ -/* $Revision: 1.54 $ */ -/* $Date: 2007/05/12 14:37:41 $ */ +/* $Revision: 1.46 $ */ +/* $Date: 2006/11/13 23:09:38 $ */ diff --git a/src/libtom/tomcrypt_custom.h b/src/libtom/tomcrypt_custom.h index 73ceaa05..e08bc924 100644 --- a/src/libtom/tomcrypt_custom.h +++ b/src/libtom/tomcrypt_custom.h @@ -69,10 +69,10 @@ /* Easy button? */ #ifdef LTC_EASY #define LTC_NO_CIPHERS - #define LTC_RIJNDAEL - #define LTC_BLOWFISH - #define LTC_DES - #define LTC_CAST5 + #define RIJNDAEL + #define BLOWFISH + #define DES + #define CAST5 #define LTC_NO_MODES #define LTC_ECB_MODE @@ -80,26 +80,26 @@ #define LTC_CTR_MODE #define LTC_NO_HASHES - #define LTC_SHA1 - #define LTC_SHA512 - #define LTC_SHA384 - #define LTC_SHA256 - #define LTC_SHA224 + #define SHA1 + #define SHA512 + #define SHA384 + #define SHA256 + #define SHA224 #define LTC_NO_MACS - #define LTC_HMAC - #define LTC_OMAC - #define LTC_CCM_MODE + #define HMAC + #define OMAC + #define CCM_MODE #define LTC_NO_PRNGS - #define LTC_SPRNG - #define LTC_YARROW - #define LTC_DEVRANDOM + #define SPRNG + #define YARROW + #define DEVRANDOM #define TRY_URANDOM_FIRST #define LTC_NO_PK - #define LTC_MRSA - #define LTC_MECC + #define MRSA + #define MECC #endif /* Use small code where possible */ @@ -128,33 +128,33 @@ /* ---> Symmetric Block Ciphers <--- */ #ifndef LTC_NO_CIPHERS -#define LTC_BLOWFISH -#define LTC_RC2 -#define LTC_RC5 -#define LTC_RC6 -#define LTC_SAFERP -#define LTC_RIJNDAEL -#define LTC_XTEA +#define BLOWFISH +#define RC2 +#define RC5 +#define RC6 +#define SAFERP +#define RIJNDAEL +#define XTEA /* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format * (saves 4KB of ram), _ALL_TABLES enables all tables during setup */ -#define LTC_TWOFISH +#define TWOFISH #ifndef LTC_NO_TABLES - #define LTC_TWOFISH_TABLES - /* #define LTC_TWOFISH_ALL_TABLES */ + #define TWOFISH_TABLES + /* #define TWOFISH_ALL_TABLES */ #else - #define LTC_TWOFISH_SMALL + #define TWOFISH_SMALL #endif -/* #define LTC_TWOFISH_SMALL */ -/* LTC_DES includes EDE triple-LTC_DES */ -#define LTC_DES -#define LTC_CAST5 -#define LTC_NOEKEON -#define LTC_SKIPJACK -#define LTC_SAFER -#define LTC_KHAZAD -#define LTC_ANUBIS -#define LTC_ANUBIS_TWEAK -#define LTC_KSEED +/* #define TWOFISH_SMALL */ +/* DES includes EDE triple-DES */ +#define DES +#define CAST5 +#define NOEKEON +#define SKIPJACK +#define SAFER +#define KHAZAD +#define ANUBIS +#define ANUBIS_TWEAK +#define KSEED #define LTC_KASUMI #endif /* LTC_NO_CIPHERS */ @@ -181,29 +181,26 @@ #define LRW_TABLES #endif -/* XTS mode */ -#define LTC_XTS_MODE - #endif /* LTC_NO_MODES */ /* ---> One-Way Hash Functions <--- */ #ifndef LTC_NO_HASHES -#define LTC_CHC_HASH -#define LTC_WHIRLPOOL -#define LTC_SHA512 -#define LTC_SHA384 -#define LTC_SHA256 -#define LTC_SHA224 -#define LTC_TIGER -#define LTC_SHA1 -#define LTC_MD5 -#define LTC_MD4 -#define LTC_MD2 -#define LTC_RIPEMD128 -#define LTC_RIPEMD160 -#define LTC_RIPEMD256 -#define LTC_RIPEMD320 +#define CHC_HASH +#define WHIRLPOOL +#define SHA512 +#define SHA384 +#define SHA256 +#define SHA224 +#define TIGER +#define SHA1 +#define MD5 +#define MD4 +#define MD2 +#define RIPEMD128 +#define RIPEMD160 +#define RIPEMD256 +#define RIPEMD320 #endif /* LTC_NO_HASHES */ @@ -215,69 +212,69 @@ #define LTC_PMAC #define LTC_XCBC #define LTC_F9_MODE -#define LTC_PELICAN +#define PELICAN -#if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL) - #error Pelican-MAC requires LTC_RIJNDAEL +#if defined(PELICAN) && !defined(RIJNDAEL) + #error Pelican-MAC requires RIJNDAEL #endif /* ---> Encrypt + Authenticate Modes <--- */ -#define LTC_EAX_MODE -#if defined(LTC_EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC)) - #error LTC_EAX_MODE requires CTR and LTC_OMAC mode +#define EAX_MODE +#if defined(EAX_MODE) && !(defined(LTC_CTR_MODE) && defined(LTC_OMAC)) + #error EAX_MODE requires CTR and OMAC mode #endif -#define LTC_OCB_MODE -#define LTC_CCM_MODE -#define LTC_GCM_MODE +#define OCB_MODE +#define CCM_MODE +#define GCM_MODE /* Use 64KiB tables */ #ifndef LTC_NO_TABLES - #define LTC_GCM_TABLES + #define GCM_TABLES #endif /* USE SSE2? requires GCC works on x86_32 and x86_64*/ -#ifdef LTC_GCM_TABLES -/* #define LTC_GCM_TABLES_SSE2 */ +#ifdef GCM_TABLES +/* #define GCM_TABLES_SSE2 */ #endif #endif /* LTC_NO_MACS */ /* Various tidbits of modern neatoness */ -#define LTC_BASE64 +#define BASE64 /* --> Pseudo Random Number Generators <--- */ #ifndef LTC_NO_PRNGS /* Yarrow */ -#define LTC_YARROW +#define YARROW /* which descriptor of AES to use? */ /* 0 = rijndael_enc 1 = aes_enc, 2 = rijndael [full], 3 = aes [full] */ -#define LTC_YARROW_AES 0 +#define YARROW_AES 0 -#if defined(LTC_YARROW) && !defined(LTC_CTR_MODE) - #error LTC_YARROW requires LTC_CTR_MODE chaining mode to be defined! +#if defined(YARROW) && !defined(LTC_CTR_MODE) + #error YARROW requires LTC_CTR_MODE chaining mode to be defined! #endif /* a PRNG that simply reads from an available system source */ -#define LTC_SPRNG +#define SPRNG -/* The LTC_RC4 stream cipher */ -#define LTC_RC4 +/* The RC4 stream cipher */ +#define RC4 /* Fortuna PRNG */ -#define LTC_FORTUNA +#define FORTUNA /* reseed every N calls to the read function */ -#define LTC_FORTUNA_WD 10 +#define FORTUNA_WD 10 /* number of pools (4..32) can save a bit of ram by lowering the count */ -#define LTC_FORTUNA_POOLS 32 +#define FORTUNA_POOLS 32 -/* Greg's LTC_SOBER128 PRNG ;-0 */ -#define LTC_SOBER128 +/* Greg's SOBER128 PRNG ;-0 */ +#define SOBER128 /* the *nix style /dev/random device */ -#define LTC_DEVRANDOM +#define DEVRANDOM /* try /dev/urandom before trying /dev/random */ #define TRY_URANDOM_FIRST @@ -287,10 +284,10 @@ #ifndef LTC_NO_MATH /* LibTomMath */ -/* #define LTM_LTC_DESC */ +/* #define LTM_DESC */ /* TomsFastMath */ -/* #define TFM_LTC_DESC */ +/* #define TFM_DESC */ #endif /* LTC_NO_MATH */ @@ -298,37 +295,37 @@ #ifndef LTC_NO_PK /* Include RSA support */ -#define LTC_MRSA +#define MRSA /* Include Katja (a Rabin variant like RSA) */ /* #define MKAT */ /* Digital Signature Algorithm */ -#define LTC_MDSA +#define MDSA /* ECC */ -#define LTC_MECC +#define MECC /* use Shamir's trick for point mul (speeds up signature verification) */ #define LTC_ECC_SHAMIR -#if defined(TFM_LTC_DESC) && defined(LTC_MECC) - #define LTC_MECC_ACCEL +#if defined(TFM_DESC) && defined(MECC) + #define MECC_ACCEL #endif /* do we want fixed point ECC */ -/* #define LTC_MECC_FP */ +/* #define MECC_FP */ /* Timing Resistant? */ /* #define LTC_ECC_TIMING_RESISTANT */ #endif /* LTC_NO_PK */ -/* LTC_PKCS #1 (RSA) and #5 (Password Handling) stuff */ +/* PKCS #1 (RSA) and #5 (Password Handling) stuff */ #ifndef LTC_NO_PKCS -#define LTC_PKCS_1 -#define LTC_PKCS_5 +#define PKCS_1 +#define PKCS_5 /* Include ASN.1 DER (required by DSA/RSA) */ #define LTC_DER @@ -337,7 +334,7 @@ /* cleanup */ -#ifdef LTC_MECC +#ifdef MECC /* Supported ECC Key Sizes */ #ifndef LTC_NO_CURVES #define ECC112 @@ -351,20 +348,20 @@ #endif #endif -#if defined(LTC_MECC) || defined(LTC_MRSA) || defined(LTC_MDSA) || defined(MKATJA) +#if defined(MECC) || defined(MRSA) || defined(MDSA) || defined(MKATJA) /* Include the MPI functionality? (required by the PK algorithms) */ #define MPI #endif -#ifdef LTC_MRSA - #define LTC_PKCS_1 +#ifdef MRSA + #define PKCS_1 #endif #if defined(LTC_DER) && !defined(MPI) #error ASN.1 DER requires MPI functionality #endif -#if (defined(LTC_MDSA) || defined(LTC_MRSA) || defined(LTC_MECC) || defined(MKATJA)) && !defined(LTC_DER) +#if (defined(MDSA) || defined(MRSA) || defined(MECC) || defined(MKATJA)) && !defined(LTC_DER) #error PK requires ASN.1 DER functionality, make sure LTC_DER is enabled #endif @@ -394,7 +391,7 @@ /* Debuggers */ -/* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and LTC_RC4 work (see the code) */ +/* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and RC4 work (see the code) */ /* #define LTC_VALGRIND */ #endif @@ -402,5 +399,5 @@ /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_custom.h,v $ */ -/* $Revision: 1.73 $ */ -/* $Date: 2007/05/12 14:37:41 $ */ +/* $Revision: 1.66 $ */ +/* $Date: 2006/12/04 02:50:11 $ */ diff --git a/src/libtom/tomcrypt_des.c b/src/libtom/tomcrypt_des.c index d921ca58..a9a48396 100644 --- a/src/libtom/tomcrypt_des.c +++ b/src/libtom/tomcrypt_des.c @@ -6,16 +6,16 @@ * The library is free for all purposes without any express * guarantee it works. * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org + * Tom St Denis, tomstdenis@gmail.com, http://libtomcrypt.com */ #include "tomcrypt.h" /** @file des.c - LTC_DES code submitted by Dobes Vandermeer + DES code submitted by Dobes Vandermeer */ -#ifdef LTC_DES +#ifdef DES #define EN0 0 #define DE1 1 @@ -1519,7 +1519,7 @@ static void desfunc(ulong32 *block, const ulong32 *keys) #endif /** - Initialize the LTC_DES block cipher + Initialize the DES block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @@ -1546,7 +1546,7 @@ static int des_setup(const unsigned char *key, int keylen, int num_rounds, symme } /** - Initialize the 3LTC_DES-EDE block cipher + Initialize the 3DES-EDE block cipher @param key The symmetric key you wish to pass @param keylen The key length in bytes @param num_rounds The number of rounds desired (0 for default) @@ -1562,23 +1562,33 @@ static int des3_setup(const unsigned char *key, int keylen, int num_rounds, symm return CRYPT_INVALID_ROUNDS; } - if (keylen != 24) { + if (keylen != 24 && keylen != 16) { return CRYPT_INVALID_KEYSIZE; } deskey(key, EN0, skey->des3.ek[0]); deskey(key+8, DE1, skey->des3.ek[1]); - deskey(key+16, EN0, skey->des3.ek[2]); + if (keylen == 24) { + deskey(key+16, EN0, skey->des3.ek[2]); + } else { + /* two-key 3DES: K3=K1 */ + deskey(key, EN0, skey->des3.ek[2]); + } deskey(key, DE1, skey->des3.dk[2]); deskey(key+8, EN0, skey->des3.dk[1]); - deskey(key+16, DE1, skey->des3.dk[0]); + if (keylen == 24) { + deskey(key+16, DE1, skey->des3.dk[0]); + } else { + /* two-key 3DES: K3=K1 */ + deskey(key, DE1, skey->des3.dk[0]); + } return CRYPT_OK; } /** - Encrypts a block of text with LTC_DES + Encrypts a block of text with DES @param pt The input plaintext (8 bytes) @param ct The output ciphertext (8 bytes) @param skey The key as scheduled @@ -1599,7 +1609,7 @@ static int des_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetric } /** - Decrypts a block of text with LTC_DES + Decrypts a block of text with DES @param ct The input ciphertext (8 bytes) @param pt The output plaintext (8 bytes) @param skey The key as scheduled @@ -1620,7 +1630,7 @@ static int des_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetric } /** - Encrypts a block of text with 3LTC_DES-EDE + Encrypts a block of text with 3DES-EDE @param pt The input plaintext (8 bytes) @param ct The output ciphertext (8 bytes) @param skey The key as scheduled @@ -1644,7 +1654,7 @@ static int des3_ecb_encrypt(const unsigned char *pt, unsigned char *ct, symmetri } /** - Decrypts a block of text with 3LTC_DES-EDE + Decrypts a block of text with 3DES-EDE @param ct The input ciphertext (8 bytes) @param pt The output plaintext (8 bytes) @param skey The key as scheduled @@ -1667,7 +1677,7 @@ static int des3_ecb_decrypt(const unsigned char *ct, unsigned char *pt, symmetri } /** - Performs a self-test of the LTC_DES block cipher + Performs a self-test of the DES block cipher @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled */ static int des_test(void) @@ -1898,5 +1908,5 @@ static int des3_keysize(int *keysize) /* $Source: /cvs/libtom/libtomcrypt/src/ciphers/des.c,v $ */ -/* $Revision: 1.15 $ */ -/* $Date: 2007/05/12 14:20:27 $ */ +/* $Revision: 1.13 $ */ +/* $Date: 2006/11/08 23:01:06 $ */ diff --git a/src/libtom/tomcrypt_hash.h b/src/libtom/tomcrypt_hash.h index ac1e7133..d9916ac2 100644 --- a/src/libtom/tomcrypt_hash.h +++ b/src/libtom/tomcrypt_hash.h @@ -1,5 +1,5 @@ /* ---- HASH FUNCTIONS ---- */ -#ifdef LTC_SHA512 +#ifdef SHA512 struct sha512_state { ulong64 length, state[8]; unsigned long curlen; @@ -7,7 +7,7 @@ struct sha512_state { }; #endif -#ifdef LTC_SHA256 +#ifdef SHA256 struct sha256_state { ulong64 length; ulong32 state[8], curlen; @@ -15,7 +15,7 @@ struct sha256_state { }; #endif -#ifdef LTC_SHA1 +#ifdef SHA1 struct sha1_state { ulong64 length; ulong32 state[5], curlen; @@ -23,7 +23,7 @@ struct sha1_state { }; #endif -#ifdef LTC_MD5 +#ifdef MD5 struct md5_state { ulong64 length; ulong32 state[4], curlen; @@ -31,7 +31,7 @@ struct md5_state { }; #endif -#ifdef LTC_MD4 +#ifdef MD4 struct md4_state { ulong64 length; ulong32 state[4], curlen; @@ -39,7 +39,7 @@ struct md4_state { }; #endif -#ifdef LTC_TIGER +#ifdef TIGER struct tiger_state { ulong64 state[3], length; unsigned long curlen; @@ -47,14 +47,14 @@ struct tiger_state { }; #endif -#ifdef LTC_MD2 +#ifdef MD2 struct md2_state { unsigned char chksum[16], X[48], buf[16]; unsigned long curlen; }; #endif -#ifdef LTC_RIPEMD128 +#ifdef RIPEMD128 struct rmd128_state { ulong64 length; unsigned char buf[64]; @@ -62,7 +62,7 @@ struct rmd128_state { }; #endif -#ifdef LTC_RIPEMD160 +#ifdef RIPEMD160 struct rmd160_state { ulong64 length; unsigned char buf[64]; @@ -70,7 +70,7 @@ struct rmd160_state { }; #endif -#ifdef LTC_RIPEMD256 +#ifdef RIPEMD256 struct rmd256_state { ulong64 length; unsigned char buf[64]; @@ -78,7 +78,7 @@ struct rmd256_state { }; #endif -#ifdef LTC_RIPEMD320 +#ifdef RIPEMD320 struct rmd320_state { ulong64 length; unsigned char buf[64]; @@ -86,7 +86,7 @@ struct rmd320_state { }; #endif -#ifdef LTC_WHIRLPOOL +#ifdef WHIRLPOOL struct whirlpool_state { ulong64 length, state[8]; unsigned char buf[64]; @@ -94,7 +94,7 @@ struct whirlpool_state { }; #endif -#ifdef LTC_CHC_HASH +#ifdef CHC_HASH struct chc_state { ulong64 length; unsigned char state[MAXBLOCKSIZE], buf[MAXBLOCKSIZE]; @@ -104,43 +104,43 @@ struct chc_state { typedef union Hash_state { char dummy[1]; -#ifdef LTC_CHC_HASH +#ifdef CHC_HASH struct chc_state chc; #endif -#ifdef LTC_WHIRLPOOL +#ifdef WHIRLPOOL struct whirlpool_state whirlpool; #endif -#ifdef LTC_SHA512 +#ifdef SHA512 struct sha512_state sha512; #endif -#ifdef LTC_SHA256 +#ifdef SHA256 struct sha256_state sha256; #endif -#ifdef LTC_SHA1 +#ifdef SHA1 struct sha1_state sha1; #endif -#ifdef LTC_MD5 +#ifdef MD5 struct md5_state md5; #endif -#ifdef LTC_MD4 +#ifdef MD4 struct md4_state md4; #endif -#ifdef LTC_MD2 +#ifdef MD2 struct md2_state md2; #endif -#ifdef LTC_TIGER +#ifdef TIGER struct tiger_state tiger; #endif -#ifdef LTC_RIPEMD128 +#ifdef RIPEMD128 struct rmd128_state rmd128; #endif -#ifdef LTC_RIPEMD160 +#ifdef RIPEMD160 struct rmd160_state rmd160; #endif -#ifdef LTC_RIPEMD256 +#ifdef RIPEMD256 struct rmd256_state rmd256; #endif -#ifdef LTC_RIPEMD320 +#ifdef RIPEMD320 struct rmd320_state rmd320; #endif void *data; @@ -191,7 +191,7 @@ extern struct ltc_hash_descriptor { } hash_descriptor[]; -#ifdef LTC_CHC_HASH +#ifdef CHC_HASH int chc_register(int cipher); int chc_init(hash_state * md); int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen); @@ -200,7 +200,7 @@ int chc_test(void); extern const struct ltc_hash_descriptor chc_desc; #endif -#ifdef LTC_WHIRLPOOL +#ifdef WHIRLPOOL int whirlpool_init(hash_state * md); int whirlpool_process(hash_state * md, const unsigned char *in, unsigned long inlen); int whirlpool_done(hash_state * md, unsigned char *hash); @@ -208,7 +208,7 @@ int whirlpool_test(void); extern const struct ltc_hash_descriptor whirlpool_desc; #endif -#ifdef LTC_SHA512 +#ifdef SHA512 int sha512_init(hash_state * md); int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen); int sha512_done(hash_state * md, unsigned char *hash); @@ -216,9 +216,9 @@ int sha512_test(void); extern const struct ltc_hash_descriptor sha512_desc; #endif -#ifdef LTC_SHA384 -#ifndef LTC_SHA512 - #error LTC_SHA512 is required for LTC_SHA384 +#ifdef SHA384 +#ifndef SHA512 + #error SHA512 is required for SHA384 #endif int sha384_init(hash_state * md); #define sha384_process sha512_process @@ -227,16 +227,16 @@ int sha384_test(void); extern const struct ltc_hash_descriptor sha384_desc; #endif -#ifdef LTC_SHA256 +#ifdef SHA256 int sha256_init(hash_state * md); int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen); int sha256_done(hash_state * md, unsigned char *hash); int sha256_test(void); extern const struct ltc_hash_descriptor sha256_desc; -#ifdef LTC_SHA224 -#ifndef LTC_SHA256 - #error LTC_SHA256 is required for LTC_SHA224 +#ifdef SHA224 +#ifndef SHA256 + #error SHA256 is required for SHA224 #endif int sha224_init(hash_state * md); #define sha224_process sha256_process @@ -246,7 +246,7 @@ extern const struct ltc_hash_descriptor sha224_desc; #endif #endif -#ifdef LTC_SHA1 +#ifdef SHA1 int sha1_init(hash_state * md); int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen); int sha1_done(hash_state * md, unsigned char *hash); @@ -254,7 +254,7 @@ int sha1_test(void); extern const struct ltc_hash_descriptor sha1_desc; #endif -#ifdef LTC_MD5 +#ifdef MD5 int md5_init(hash_state * md); int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen); int md5_done(hash_state * md, unsigned char *hash); @@ -262,7 +262,7 @@ int md5_test(void); extern const struct ltc_hash_descriptor md5_desc; #endif -#ifdef LTC_MD4 +#ifdef MD4 int md4_init(hash_state * md); int md4_process(hash_state * md, const unsigned char *in, unsigned long inlen); int md4_done(hash_state * md, unsigned char *hash); @@ -270,7 +270,7 @@ int md4_test(void); extern const struct ltc_hash_descriptor md4_desc; #endif -#ifdef LTC_MD2 +#ifdef MD2 int md2_init(hash_state * md); int md2_process(hash_state * md, const unsigned char *in, unsigned long inlen); int md2_done(hash_state * md, unsigned char *hash); @@ -278,7 +278,7 @@ int md2_test(void); extern const struct ltc_hash_descriptor md2_desc; #endif -#ifdef LTC_TIGER +#ifdef TIGER int tiger_init(hash_state * md); int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen); int tiger_done(hash_state * md, unsigned char *hash); @@ -286,7 +286,7 @@ int tiger_test(void); extern const struct ltc_hash_descriptor tiger_desc; #endif -#ifdef LTC_RIPEMD128 +#ifdef RIPEMD128 int rmd128_init(hash_state * md); int rmd128_process(hash_state * md, const unsigned char *in, unsigned long inlen); int rmd128_done(hash_state * md, unsigned char *hash); @@ -294,7 +294,7 @@ int rmd128_test(void); extern const struct ltc_hash_descriptor rmd128_desc; #endif -#ifdef LTC_RIPEMD160 +#ifdef RIPEMD160 int rmd160_init(hash_state * md); int rmd160_process(hash_state * md, const unsigned char *in, unsigned long inlen); int rmd160_done(hash_state * md, unsigned char *hash); @@ -302,7 +302,7 @@ int rmd160_test(void); extern const struct ltc_hash_descriptor rmd160_desc; #endif -#ifdef LTC_RIPEMD256 +#ifdef RIPEMD256 int rmd256_init(hash_state * md); int rmd256_process(hash_state * md, const unsigned char *in, unsigned long inlen); int rmd256_done(hash_state * md, unsigned char *hash); @@ -310,7 +310,7 @@ int rmd256_test(void); extern const struct ltc_hash_descriptor rmd256_desc; #endif -#ifdef LTC_RIPEMD320 +#ifdef RIPEMD320 int rmd320_init(hash_state * md); int rmd320_process(hash_state * md, const unsigned char *in, unsigned long inlen); int rmd320_done(hash_state * md, unsigned char *hash); @@ -375,5 +375,5 @@ int func_name (hash_state * md, const unsigned char *in, unsigned long inlen) } /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_hash.h,v $ */ -/* $Revision: 1.22 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ +/* $Revision: 1.19 $ */ +/* $Date: 2006/11/05 01:36:43 $ */ diff --git a/src/libtom/tomcrypt_mac.h b/src/libtom/tomcrypt_mac.h index 7ad9516b..42bf6804 100644 --- a/src/libtom/tomcrypt_mac.h +++ b/src/libtom/tomcrypt_mac.h @@ -51,7 +51,7 @@ int omac_file(int cipher, const char *filename, unsigned char *out, unsigned long *outlen); int omac_test(void); -#endif /* LTC_OMAC */ +#endif /* OMAC */ #ifdef LTC_PMAC @@ -96,10 +96,10 @@ void pmac_shift_xor(pmac_state *pmac); #endif /* PMAC */ -#ifdef LTC_EAX_MODE +#ifdef EAX_MODE #if !(defined(LTC_OMAC) && defined(LTC_CTR_MODE)) - #error LTC_EAX_MODE requires LTC_OMAC and CTR + #error EAX_MODE requires OMAC and CTR #endif typedef struct { @@ -137,7 +137,7 @@ int eax_decrypt_verify_memory(int cipher, int eax_test(void); #endif /* EAX MODE */ -#ifdef LTC_OCB_MODE +#ifdef OCB_MODE typedef struct { unsigned char L[MAXBLOCKSIZE], /* L value */ Ls[32][MAXBLOCKSIZE], /* L shifted by i bits to the left */ @@ -191,9 +191,9 @@ int ocb_ntz(unsigned long x); int s_ocb_done(ocb_state *ocb, const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tag, unsigned long *taglen, int mode); -#endif /* LTC_OCB_MODE */ +#endif /* OCB_MODE */ -#ifdef LTC_CCM_MODE +#ifdef CCM_MODE #define CCM_ENCRYPT 0 #define CCM_DECRYPT 1 @@ -210,26 +210,26 @@ int ccm_memory(int cipher, int ccm_test(void); -#endif /* LTC_CCM_MODE */ +#endif /* CCM_MODE */ -#if defined(LRW_MODE) || defined(LTC_GCM_MODE) +#if defined(LRW_MODE) || defined(GCM_MODE) void gcm_gf_mult(const unsigned char *a, const unsigned char *b, unsigned char *c); #endif /* table shared between GCM and LRW */ -#if defined(LTC_GCM_TABLES) || defined(LRW_TABLES) || ((defined(LTC_GCM_MODE) || defined(LTC_GCM_MODE)) && defined(LTC_FAST)) +#if defined(GCM_TABLES) || defined(LRW_TABLES) || ((defined(GCM_MODE) || defined(GCM_MODE)) && defined(LTC_FAST)) extern const unsigned char gcm_shift_table[]; #endif -#ifdef LTC_GCM_MODE +#ifdef GCM_MODE #define GCM_ENCRYPT 0 #define GCM_DECRYPT 1 -#define LTC_GCM_MODE_IV 0 -#define LTC_GCM_MODE_AAD 1 -#define LTC_GCM_MODE_TEXT 2 +#define GCM_MODE_IV 0 +#define GCM_MODE_AAD 1 +#define GCM_MODE_TEXT 2 typedef struct { symmetric_key K; @@ -247,9 +247,9 @@ typedef struct { ulong64 totlen, /* 64-bit counter used for IV and AAD */ pttotlen; /* 64-bit counter for the PT */ -#ifdef LTC_GCM_TABLES +#ifdef GCM_TABLES unsigned char PC[16][256][16] /* 16 tables of 8x128 */ -#ifdef LTC_GCM_TABLES_SSE2 +#ifdef GCM_TABLES_SSE2 __attribute__ ((aligned (16))) #endif ; @@ -287,9 +287,9 @@ int gcm_memory( int cipher, int direction); int gcm_test(void); -#endif /* LTC_GCM_MODE */ +#endif /* GCM_MODE */ -#ifdef LTC_PELICAN +#ifdef PELICAN typedef struct pelican_state { @@ -311,9 +311,6 @@ int pelican_memory(const unsigned char *key, unsigned long keylen, #ifdef LTC_XCBC -/* add this to "keylen" to xcbc_init to use a pure three-key XCBC MAC */ -#define LTC_XCBC_PURE 0x8000UL - typedef struct { unsigned char K[3][MAXBLOCKSIZE], IV[MAXBLOCKSIZE]; @@ -380,5 +377,5 @@ int f9_test(void); /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_mac.h,v $ */ -/* $Revision: 1.23 $ */ -/* $Date: 2007/05/12 14:37:41 $ */ +/* $Revision: 1.20 $ */ +/* $Date: 2006/11/08 21:57:04 $ */ diff --git a/src/libtom/tomcrypt_math.h b/src/libtom/tomcrypt_math.h index a05d7fff..c996e411 100644 --- a/src/libtom/tomcrypt_math.h +++ b/src/libtom/tomcrypt_math.h @@ -7,11 +7,11 @@ #define LTC_MP_NO 0 #define LTC_MP_YES 1 -#ifndef LTC_MECC +#ifndef MECC typedef void ecc_point; #endif -#ifndef LTC_MRSA +#ifndef MRSA typedef void rsa_key; #endif @@ -496,5 +496,5 @@ extern const ltc_math_descriptor gmp_desc; #endif /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_math.h,v $ */ -/* $Revision: 1.44 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ +/* $Revision: 1.43 $ */ +/* $Date: 2006/12/02 19:23:13 $ */ diff --git a/src/libtom/tomcrypt_misc.h b/src/libtom/tomcrypt_misc.h index f5384cac..0b444f8e 100644 --- a/src/libtom/tomcrypt_misc.h +++ b/src/libtom/tomcrypt_misc.h @@ -1,5 +1,5 @@ -/* ---- LTC_BASE64 Routines ---- */ -#ifdef LTC_BASE64 +/* ---- BASE64 Routines ---- */ +#ifdef BASE64 int base64_encode(const unsigned char *in, unsigned long len, unsigned char *out, unsigned long *outlen); @@ -19,5 +19,5 @@ extern const char *crypt_build_settings; int crypt_fsa(void *mp, ...); /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_misc.h,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ +/* $Revision: 1.4 $ */ +/* $Date: 2006/11/06 03:03:01 $ */ diff --git a/src/libtom/tomcrypt_pk.h b/src/libtom/tomcrypt_pk.h index 800fab3a..3a0d7abd 100644 --- a/src/libtom/tomcrypt_pk.h +++ b/src/libtom/tomcrypt_pk.h @@ -8,13 +8,13 @@ enum { int rand_prime(void *N, long len, prng_state *prng, int wprng); /* ---- RSA ---- */ -#ifdef LTC_MRSA +#ifdef MRSA /* Min and Max RSA key sizes (in bits) */ #define MIN_RSA_SIZE 1024 #define MAX_RSA_SIZE 4096 -/** RSA LTC_PKCS style key */ +/** RSA PKCS style key */ typedef struct Rsa_key { /** Type of key, PK_PRIVATE or PK_PUBLIC */ int type; @@ -44,20 +44,20 @@ int rsa_exptmod(const unsigned char *in, unsigned long inlen, void rsa_free(rsa_key *key); -/* These use LTC_PKCS #1 v2.0 padding */ +/* These use PKCS #1 v2.0 padding */ #define rsa_encrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, _key) \ - rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_LTC_PKCS_1_OAEP, _key) + rsa_encrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _prng, _prng_idx, _hash_idx, LTC_PKCS_1_OAEP, _key) #define rsa_decrypt_key(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, _stat, _key) \ - rsa_decrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, LTC_LTC_PKCS_1_OAEP, _stat, _key) + rsa_decrypt_key_ex(_in, _inlen, _out, _outlen, _lparam, _lparamlen, _hash_idx, LTC_PKCS_1_OAEP, _stat, _key) #define rsa_sign_hash(_in, _inlen, _out, _outlen, _prng, _prng_idx, _hash_idx, _saltlen, _key) \ - rsa_sign_hash_ex(_in, _inlen, _out, _outlen, LTC_LTC_PKCS_1_PSS, _prng, _prng_idx, _hash_idx, _saltlen, _key) + rsa_sign_hash_ex(_in, _inlen, _out, _outlen, LTC_PKCS_1_PSS, _prng, _prng_idx, _hash_idx, _saltlen, _key) #define rsa_verify_hash(_sig, _siglen, _hash, _hashlen, _hash_idx, _saltlen, _stat, _key) \ - rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key) + rsa_verify_hash_ex(_sig, _siglen, _hash, _hashlen, LTC_PKCS_1_PSS, _hash_idx, _saltlen, _stat, _key) -/* These can be switched between LTC_PKCS #1 v2.x and LTC_PKCS #1 v1.5 paddings */ +/* These can be switched between PKCS #1 v2.x and PKCS #1 v1.5 paddings */ int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, @@ -82,7 +82,7 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long siglen, int hash_idx, unsigned long saltlen, int *stat, rsa_key *key); -/* LTC_PKCS #1 import/export */ +/* PKCS #1 import/export */ int rsa_export(unsigned char *out, unsigned long *outlen, int type, rsa_key *key); int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); @@ -95,7 +95,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key); #define MIN_KAT_SIZE 1024 #define MAX_KAT_SIZE 4096 -/** Katja LTC_PKCS style key */ +/** Katja PKCS style key */ typedef struct KAT_key { /** Type of key, PK_PRIVATE or PK_PUBLIC */ int type; @@ -125,7 +125,7 @@ int katja_exptmod(const unsigned char *in, unsigned long inlen, void katja_free(katja_key *key); -/* These use LTC_PKCS #1 v2.0 padding */ +/* These use PKCS #1 v2.0 padding */ int katja_encrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const unsigned char *lparam, unsigned long lparamlen, @@ -137,14 +137,14 @@ int katja_decrypt_key(const unsigned char *in, unsigned long inlen, int hash_idx, int *stat, katja_key *key); -/* LTC_PKCS #1 import/export */ +/* PKCS #1 import/export */ int katja_export(unsigned char *out, unsigned long *outlen, int type, katja_key *key); int katja_import(const unsigned char *in, unsigned long inlen, katja_key *key); #endif /* ---- ECC Routines ---- */ -#ifdef LTC_MECC +#ifdef MECC /* size of our temp buffers for exported keys */ #define ECC_BUF_SIZE 256 @@ -251,7 +251,7 @@ void ltc_ecc_del_point(ecc_point *p); int ltc_ecc_is_valid_idx(int n); /* point ops (mp == montgomery digit) */ -#if !defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC) || defined(GMP_LTC_DESC) +#if !defined(MECC_ACCEL) || defined(LTM_DESC) || defined(GMP_DESC) /* R = 2P */ int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp); @@ -259,18 +259,11 @@ int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); #endif -#if defined(LTC_MECC_FP) -/* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */ +#if defined(MECC_FP) int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); - -/* functions for saving/loading/freeing/adding to fixed point cache */ int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen); int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen); void ltc_ecc_fp_free(void); -int ltc_ecc_fp_add_point(ecc_point *g, void *modulus, int lock); - -/* lock/unlock all points currently in fixed point cache */ -void ltc_ecc_fp_tablelock(int lock); #endif /* R = kG */ @@ -283,8 +276,7 @@ int ltc_ecc_mul2add(ecc_point *A, void *kA, ecc_point *C, void *modulus); -#ifdef LTC_MECC_FP -/* Shamir's trick with optimized point multiplication using fixed point cache */ +#ifdef MECC_FP int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, ecc_point *B, void *kB, ecc_point *C, void *modulus); @@ -298,13 +290,13 @@ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp); #endif -#ifdef LTC_MDSA +#ifdef MDSA /* Max diff between group and modulus size in bytes */ -#define LTC_MDSA_DELTA 512 +#define MDSA_DELTA 512 /* Max DSA group size in bytes (default allows 4k-bit groups) */ -#define LTC_MDSA_MAX_GROUP 512 +#define MDSA_MAX_GROUP 512 /** DSA key structure */ typedef struct { @@ -504,7 +496,7 @@ int der_printable_char_encode(int c); int der_printable_value_decode(int v); /* UTF-8 */ -#if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED) || defined (__WCHAR_TYPE__)) && !defined(LTC_NO_WCHAR) +#if (defined(SIZE_MAX) || __STDC_VERSION__ >= 199901L || defined(WCHAR_MAX) || defined(_WCHAR_T) || defined(_WCHAR_T_DEFINED)) && !defined(LTC_NO_WCHAR) #include #else typedef ulong32 wchar_t; @@ -548,5 +540,5 @@ int der_length_utctime(ltc_utctime *utctime, unsigned long *outlen); #endif /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pk.h,v $ */ -/* $Revision: 1.81 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ +/* $Revision: 1.77 $ */ +/* $Date: 2006/12/03 00:39:56 $ */ diff --git a/src/libtom/tomcrypt_pkcs.h b/src/libtom/tomcrypt_pkcs.h index 84fb82a6..71bcdb90 100644 --- a/src/libtom/tomcrypt_pkcs.h +++ b/src/libtom/tomcrypt_pkcs.h @@ -1,19 +1,19 @@ -/* LTC_PKCS Header Info */ +/* PKCS Header Info */ -/* ===> LTC_PKCS #1 -- RSA Cryptography <=== */ -#ifdef LTC_PKCS_1 +/* ===> PKCS #1 -- RSA Cryptography <=== */ +#ifdef PKCS_1 enum ltc_pkcs_1_v1_5_blocks { - LTC_LTC_PKCS_1_EMSA = 1, /* Block type 1 (LTC_PKCS #1 v1.5 signature padding) */ - LTC_LTC_PKCS_1_EME = 2 /* Block type 2 (LTC_PKCS #1 v1.5 encryption padding) */ + LTC_PKCS_1_EMSA = 1, /* Block type 1 (PKCS #1 v1.5 signature padding) */ + LTC_PKCS_1_EME = 2 /* Block type 2 (PKCS #1 v1.5 encryption padding) */ }; enum ltc_pkcs_1_paddings { - LTC_LTC_PKCS_1_V1_5 = 1, /* LTC_PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */ - LTC_LTC_PKCS_1_OAEP = 2, /* LTC_PKCS #1 v2.0 encryption padding */ - LTC_LTC_PKCS_1_PSS = 3 /* LTC_PKCS #1 v2.1 signature padding */ + LTC_PKCS_1_V1_5 = 1, /* PKCS #1 v1.5 padding (\sa ltc_pkcs_1_v1_5_blocks) */ + LTC_PKCS_1_OAEP = 2, /* PKCS #1 v2.0 encryption padding */ + LTC_PKCS_1_PSS = 3 /* PKCS #1 v2.1 signature padding */ }; int pkcs_1_mgf1( int hash_idx, @@ -65,10 +65,10 @@ int pkcs_1_pss_decode(const unsigned char *msghash, unsigned long msghashlen, unsigned long saltlen, int hash_idx, unsigned long modulus_bitlen, int *res); -#endif /* LTC_PKCS_1 */ +#endif /* PKCS_1 */ -/* ===> LTC_PKCS #5 -- Password Based Cryptography <=== */ -#ifdef LTC_PKCS_5 +/* ===> PKCS #5 -- Password Based Cryptography <=== */ +#ifdef PKCS_5 /* Algorithm #1 (old) */ int pkcs_5_alg1(const unsigned char *password, unsigned long password_len, @@ -82,8 +82,8 @@ int pkcs_5_alg2(const unsigned char *password, unsigned long password_len, int iteration_count, int hash_idx, unsigned char *out, unsigned long *outlen); -#endif /* LTC_PKCS_5 */ +#endif /* PKCS_5 */ /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_pkcs.h,v $ */ -/* $Revision: 1.8 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ +/* $Revision: 1.7 $ */ +/* $Date: 2006/11/15 12:44:59 $ */ diff --git a/src/libtom/tomcrypt_prng.h b/src/libtom/tomcrypt_prng.h index f3e3e550..dd640c96 100644 --- a/src/libtom/tomcrypt_prng.h +++ b/src/libtom/tomcrypt_prng.h @@ -1,5 +1,5 @@ /* ---- PRNG Stuff ---- */ -#ifdef LTC_YARROW +#ifdef YARROW struct yarrow_prng { int cipher, hash; unsigned char pool[MAXBLOCKSIZE]; @@ -8,16 +8,16 @@ struct yarrow_prng { }; #endif -#ifdef LTC_RC4 +#ifdef RC4 struct rc4_prng { int x, y; unsigned char buf[256]; }; #endif -#ifdef LTC_FORTUNA +#ifdef FORTUNA struct fortuna_prng { - hash_state pool[LTC_FORTUNA_POOLS]; /* the pools */ + hash_state pool[FORTUNA_POOLS]; /* the pools */ symmetric_key skey; @@ -33,7 +33,7 @@ struct fortuna_prng { }; #endif -#ifdef LTC_SOBER128 +#ifdef SOBER128 struct sober128_prng { ulong32 R[17], /* Working storage for the shift register */ initR[17], /* saved register contents */ @@ -49,16 +49,16 @@ struct sober128_prng { typedef union Prng_state { char dummy[1]; -#ifdef LTC_YARROW +#ifdef YARROW struct yarrow_prng yarrow; #endif -#ifdef LTC_RC4 +#ifdef RC4 struct rc4_prng rc4; #endif -#ifdef LTC_FORTUNA +#ifdef FORTUNA struct fortuna_prng fortuna; #endif -#ifdef LTC_SOBER128 +#ifdef SOBER128 struct sober128_prng sober128; #endif } prng_state; @@ -118,7 +118,7 @@ extern struct ltc_prng_descriptor { int (*test)(void); } prng_descriptor[]; -#ifdef LTC_YARROW +#ifdef YARROW int yarrow_start(prng_state *prng); int yarrow_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); int yarrow_ready(prng_state *prng); @@ -130,7 +130,7 @@ int yarrow_test(void); extern const struct ltc_prng_descriptor yarrow_desc; #endif -#ifdef LTC_FORTUNA +#ifdef FORTUNA int fortuna_start(prng_state *prng); int fortuna_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); int fortuna_ready(prng_state *prng); @@ -142,7 +142,7 @@ int fortuna_test(void); extern const struct ltc_prng_descriptor fortuna_desc; #endif -#ifdef LTC_RC4 +#ifdef RC4 int rc4_start(prng_state *prng); int rc4_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); int rc4_ready(prng_state *prng); @@ -154,7 +154,7 @@ int rc4_test(void); extern const struct ltc_prng_descriptor rc4_desc; #endif -#ifdef LTC_SPRNG +#ifdef SPRNG int sprng_start(prng_state *prng); int sprng_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); int sprng_ready(prng_state *prng); @@ -166,7 +166,7 @@ int sprng_test(void); extern const struct ltc_prng_descriptor sprng_desc; #endif -#ifdef LTC_SOBER128 +#ifdef SOBER128 int sober128_start(prng_state *prng); int sober128_add_entropy(const unsigned char *in, unsigned long inlen, prng_state *prng); int sober128_ready(prng_state *prng); @@ -195,5 +195,5 @@ int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void)) /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_prng.h,v $ */ -/* $Revision: 1.9 $ */ -/* $Date: 2007/05/12 14:32:35 $ */ +/* $Revision: 1.8 $ */ +/* $Date: 2006/11/05 01:36:43 $ */ diff --git a/src/pycrypto_common.h b/src/pycrypto_common.h deleted file mode 100644 index 3182ec10..00000000 --- a/src/pycrypto_common.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * pycrypto_compat.h: Common header file for PyCrypto - * - * Written in 2013 by Dwayne C. Litzenberger - * - * =================================================================== - * The contents of this file are dedicated to the public domain. To - * the extent that dedication to the public domain is not available, - * everyone is granted a worldwide, perpetual, royalty-free, - * non-exclusive license to exercise all rights associated with the - * contents of this file for any purpose whatsoever. - * No rights are reserved. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * =================================================================== - */ -#ifndef PYCRYPTO_COMMON_H -#define PYCRYPTO_COMMON_H - -#include "Python.h" -#include "pycrypto_compat.h" -#include "config.h" -#if HAVE_STDINT_H -# include -#elif HAVE_INTTYPES_H -# include -#elif HAVE_SYS_INTTYPES_H -# include -#else -# error "stdint.h and inttypes.h not found" -#endif - - -#endif /* PYCRYPTO_COMMON_H */ diff --git a/src/pycrypto_compat.h b/src/pycrypto_compat.h index 3f890b45..eaaebdb9 100644 --- a/src/pycrypto_compat.h +++ b/src/pycrypto_compat.h @@ -28,50 +28,20 @@ /* * Python 3.x defines, for conditional compiles */ - + #if PY_MAJOR_VERSION >= 3 -# define IS_PY3K -# define PyInt_AS_LONG PyLong_AS_LONG -# define PyInt_CheckExact PyLong_CheckExact -# define PyInt_FromLong PyLong_FromLong -# define PyString_Check PyUnicode_Check -# define PyString_CompareWithASCIIString PyUnicode_CompareWithASCIIString -# define PyString_FromString PyUnicode_FromString -# define staticforward static +#define IS_PY3K #else -# define PyBytes_GET_SIZE PyString_GET_SIZE -# define PyBytes_FromStringAndSize PyString_FromStringAndSize -# define PyBytes_AS_STRING PyString_AS_STRING -# define PyBytes_Check PyString_Check -# define PyBytes_Size PyString_Size -# define PyBytes_AsString PyString_AsString -# define PyBytesObject PyStringObject -# define PyString_CompareWithASCIIString(o,s) \ - (PyString_Check(o) ? strcmp(PyString_AsString(o),(s)) : -1) /* NB: only compares up to the first NUL byte */ -# if PY_MINOR_VERSION <= 5 /* Python 2.5 and earlier */ -# define Py_TYPE(v) ((v)->ob_type) -# define PyLong_MASK MASK -# define PyLong_SHIFT SHIFT -# define PyVarObject_HEAD_INIT(a,b) PyObject_HEAD_INIT(a) 0, -# endif -# if PY_MINOR_VERSION <= 1 /* Python 2.1 only */ -# define METH_O METH_OLDARGS /* METH_O is a subset of what METH_OLDARGS provides */ -# define PyInt_CheckExact PyInt_Check -# define PyString_CheckExact PyString_Check -# define PyType_Ready(t) (((t)->ob_type = &PyType_Type) ? 0 : 0) -# endif +#define PyBytes_GET_SIZE PyString_GET_SIZE +#define PyBytes_FromStringAndSize PyString_FromStringAndSize +#define PyBytes_AS_STRING PyString_AS_STRING +#define PyBytes_Check PyString_Check +#define PyBytes_Size PyString_Size +#define PyBytes_AsString PyString_AsString +#define PyBytesObject PyStringObject +#if PY_MINOR_VERSION <= 5 /* PyUnicode_FromString exists from Python 2.6 on up */ +#define PyUnicode_FromString PyString_FromString #endif - -/* Python 2.1 doesn't have PyModule_AddIntConstant */ -#if PYTHON_API_VERSION < 1011 -#define PyModule_AddIntConstant(m,n,v) \ - do { \ - PyObject *o=PyInt_FromLong(v); \ - if (o!=NULL) { \ - PyObject_SetAttrString((m),(n),o); \ - Py_DECREF(o); \ - } \ - } while(0) #endif /* diff --git a/src/stream_template.c b/src/stream_template.c index c0aa42c3..c3effa49 100644 --- a/src/stream_template.c +++ b/src/stream_template.c @@ -24,7 +24,17 @@ * =================================================================== */ -#include "pycrypto_common.h" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef _HAVE_STDC_HEADERS +#include +#endif + +#include "Python.h" +#include "pycrypto_compat.h" #include "modsupport.h" #define _STR(x) #x @@ -53,7 +63,14 @@ typedef struct /* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C. * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize */ +#ifdef IS_PY3K +static PyTypeObject ALGtype; +#define is_ALGobject(v) (Py_TYPE(v) == &ALGtype) +#else staticforward PyTypeObject ALGtype; +#define is_ALGobject(v) ((v)->ob_type == &ALGtype) +#define PyLong_FromLong PyInt_FromLong /* For Python 2.x */ +#endif static ALGobject * newALGobject(void) @@ -183,34 +200,47 @@ ALG_Decrypt(ALGobject *self, PyObject *args) /* ALGobject methods */ static PyMethodDef ALGmethods[] = { +#ifdef IS_PY3K {"encrypt", (PyCFunction) ALG_Encrypt, METH_O, ALG_Encrypt__doc__}, {"decrypt", (PyCFunction) ALG_Decrypt, METH_O, ALG_Decrypt__doc__}, +#else + {"encrypt", (PyCFunction) ALG_Encrypt, 0, ALG_Encrypt__doc__}, + {"decrypt", (PyCFunction) ALG_Decrypt, 0, ALG_Decrypt__doc__}, +#endif {NULL, NULL} /* sentinel */ }; static PyObject * +#ifdef IS_PY3K ALGgetattro(PyObject *self, PyObject *attr) +#else +ALGgetattr(PyObject *self, char *name) +#endif { - if (!PyString_Check(attr)) +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) goto generic; - if (PyString_CompareWithASCIIString(attr, "block_size") == 0) + if (PyUnicode_CompareWithASCIIString(attr, "block_size") == 0) +#else + if (strcmp(name, "block_size") == 0) +#endif { - return PyInt_FromLong(BLOCK_SIZE); + return PyLong_FromLong(BLOCK_SIZE); } - if (PyString_CompareWithASCIIString(attr, "key_size") == 0) +#ifdef IS_PY3K + if (PyUnicode_CompareWithASCIIString(attr, "key_size") == 0) +#else + if (strcmp(name, "key_size") == 0) +#endif { - return PyInt_FromLong(KEY_SIZE); + return PyLong_FromLong(KEY_SIZE); } +#ifdef IS_PY3K generic: -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ return PyObject_GenericGetAttr(self, attr); #else - if (PyString_Check(attr) < 0) { - PyErr_SetObject(PyExc_AttributeError, attr); - return NULL; - } - return Py_FindMethod(ALGmethods, (PyObject *)self, PyString_AsString(attr)); + return Py_FindMethod(ALGmethods, self, name); #endif } @@ -225,18 +255,28 @@ static struct PyMethodDef modulemethods[] = static PyTypeObject ALGtype = { +#ifdef IS_PY3K PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ +#endif _MODULE_STRING, /*tp_name*/ sizeof(ALGobject), /*tp_size*/ 0, /*tp_itemsize*/ /* methods */ (destructor) ALGdealloc, /*tp_dealloc*/ 0, /*tp_print*/ +#ifdef IS_PY3K 0, /*tp_getattr*/ +#else + ALGgetattr, /*tp_getattr*/ +#endif 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ +#ifdef IS_PY3K 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ @@ -251,7 +291,6 @@ static PyTypeObject ALGtype = 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ 0, /*tp_iter*/ 0, /*tp_iternext*/ ALGmethods, /*tp_methods*/ @@ -274,64 +313,52 @@ static PyTypeObject ALGtype = /* Initialization function for the module */ -PyMODINIT_FUNC -_MODULE_NAME (void) -{ - PyObject *m = NULL; - PyObject *__all__ = NULL; +/* Deal with old API in Python 2.1 */ +#if PYTHON_API_VERSION < 1011 +#define PyModule_AddIntConstant(m,n,v) {PyObject *o=PyInt_FromLong(v); \ + if (o!=NULL) \ + {PyDict_SetItemString(PyModule_GetDict(m),n,o); Py_DECREF(o);}} +#endif +#ifdef IS_PY3K +PyMODINIT_FUNC +#else +void +#endif + _MODULE_NAME (void) + { + PyObject *m, *d, *x; + +#ifdef IS_PY3K + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ if (PyType_Ready(&ALGtype) < 0) - goto errout; + return NULL; -#ifdef IS_PY3K /* Create the module and add the functions */ m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; #else + ALGtype.ob_type = &PyType_Type; /* Create the module and add the functions */ m = Py_InitModule("Crypto.Cipher." _MODULE_STRING, modulemethods); #endif - if (m == NULL) - goto errout; - - /* Add the type object to the module (using the name of the module itself), - * so that its methods docstrings are discoverable by introspection tools. */ - PyObject_SetAttrString(m, _MODULE_STRING, (PyObject *)&ALGtype); - - /* Add some symbolic constants to the module */ - PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE); + + /* Add some symbolic constants to the module */ + d = PyModule_GetDict(m); + x = PyUnicode_FromString(_MODULE_STRING ".error"); + PyDict_SetItemString(d, "error", x); + + PyModule_AddIntConstant(m, "block_size", BLOCK_SIZE); PyModule_AddIntConstant(m, "key_size", KEY_SIZE); - /* Create __all__ (to help generate documentation) */ - __all__ = PyList_New(4); - if (__all__ == NULL) - goto errout; - PyList_SetItem(__all__, 0, PyString_FromString(_MODULE_STRING)); /* This is the ALGType object */ - PyList_SetItem(__all__, 1, PyString_FromString("new")); - PyList_SetItem(__all__, 2, PyString_FromString("block_size")); - PyList_SetItem(__all__, 3, PyString_FromString("key_size")); - PyObject_SetAttrString(m, "__all__", __all__); - -out: - /* Final error check */ - if (m == NULL && !PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "can't initialize module"); - goto errout; - } - - /* Free local objects here */ - Py_CLEAR(__all__); + /* Check for errors */ + if (PyErr_Occurred()) + Py_FatalError("can't initialize module " _MODULE_STRING); - /* Return */ #ifdef IS_PY3K return m; -#else - return; #endif - -errout: - /* Free the module and other global objects here */ - Py_CLEAR(m); - goto out; -} - + } + /* vim:set ts=4 sw=4 sts=0 noexpandtab: */ diff --git a/src/strxor.c b/src/strxor.c index 55d80676..7cbbc1cf 100644 --- a/src/strxor.c +++ b/src/strxor.c @@ -21,12 +21,13 @@ * SOFTWARE. * =================================================================== */ - -#include "pycrypto_common.h" +#include "Python.h" #include #include #include +#include "pycrypto_compat.h" + static const char rcsid[] = "$Id$"; /* @@ -232,40 +233,25 @@ PyInit_strxor(void) initstrxor(void) #endif { - PyObject *m = NULL; + PyObject *m; /* Initialize the module */ #ifdef IS_PY3K m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; #else m = Py_InitModule("strxor", strxor_methods); -#endif if (m == NULL) - goto errout; - + return; +#endif + /* Perform runtime tests */ runtime_test(); -out: - /* Final error check */ - if (m == NULL && !PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "can't initialize module"); - goto errout; - } - - /* Free local objects here */ - - /* Return */ #ifdef IS_PY3K - return m; -#else - return; + return m; #endif - -errout: - /* Free the module and other global objects here */ - Py_CLEAR(m); - goto out; } /* vim:set ts=4 sw=4 sts=4 expandtab: */ diff --git a/src/winrand.c b/src/winrand.c index 4200fbcc..d505e540 100644 --- a/src/winrand.c +++ b/src/winrand.c @@ -30,7 +30,8 @@ /* Author: Mark Moraes */ -#include "pycrypto_common.h" +#include "Python.h" +#include "pycrypto_compat.h" #ifdef MS_WIN32 @@ -58,8 +59,14 @@ typedef struct /* Please see PEP3123 for a discussion of PyObject_HEAD and changes made in 3.x to make it conform to Standard C. * These changes also dictate using Py_TYPE to check type, and PyVarObject_HEAD_INIT(NULL, 0) to initialize */ +#ifdef IS_PY3K +static PyTypeObject WRtype; #define is_WRobject(v) (Py_TYPE(v) == &WRtype) +#else staticforward PyTypeObject WRtype; +#define is_WRobject(v) ((v)->ob_type == &WRtype) +#define PyLong_FromLong PyInt_FromLong /* for Python 2.x */ +#endif static void WRdealloc(PyObject *ptr) @@ -191,7 +198,11 @@ static PyMethodDef WR_mod_methods[] = { }; static PyObject * +#ifdef IS_PY3K WRgetattro(PyObject *s, PyObject *attr) +#else +WRgetattr(PyObject *s, char *name) +#endif { WRobject *self = (WRobject*)s; if (! is_WRobject(self)) { @@ -199,31 +210,39 @@ WRgetattro(PyObject *s, PyObject *attr) "WinRandom trying to getattr with non-WinRandom object"); return NULL; } - if (!PyString_Check(attr)) +#ifdef IS_PY3K + if (!PyUnicode_Check(attr)) goto generic; - if (PyString_CompareWithASCIIString(attr, "hcp") == 0) - return PyInt_FromLong((long) self->hcp); + if (PyUnicode_CompareWithASCIIString(attr, "hcp") == 0) +#else + if (strcmp(name, "hcp") == 0) +#endif + return PyLong_FromLong((long) self->hcp); +#ifdef IS_PY3K generic: -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ return PyObject_GenericGetAttr(s, attr); #else - if (PyString_Check(attr) < 0) { - PyErr_SetObject(PyExc_AttributeError, attr); - return NULL; - } - return Py_FindMethod(WRmethods, (PyObject *)self, PyString_AsString(attr)); + return Py_FindMethod(WRmethods, (PyObject *) self, name); #endif } static PyTypeObject WRtype = { + #ifdef IS_PY3K PyVarObject_HEAD_INIT(NULL, 0) /* deferred type init for compilation on Windows, type will be filled in at runtime */ +#else + PyObject_HEAD_INIT(NULL) + 0, /*ob_size*/ +#endif "winrandom.WinRandom", /*tp_name*/ sizeof(WRobject), /*tp_size*/ 0, /*tp_itemsize*/ /* methods */ (destructor) WRdealloc, /*tp_dealloc*/ 0, /*tp_print*/ +#ifndef IS_PY3K + WRgetattr, /*tp_getattr*/ +#else 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ @@ -243,7 +262,6 @@ static PyTypeObject WRtype = 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ -#if PYTHON_API_VERSION >= 1011 /* Python 2.2 and later */ 0, /*tp_iter*/ 0, /*tp_iternext*/ WRmethods, /*tp_methods*/ @@ -264,26 +282,27 @@ static struct PyModuleDef moduledef = { }; #endif -PyMODINIT_FUNC #ifdef IS_PY3K +PyMODINIT_FUNC PyInit_winrandom() #else +void initwinrandom() #endif { - PyObject *m = NULL; - - if (PyType_Ready(&WRtype) < 0) - goto errout; - - /* Initialize the module */ + PyObject *m; #ifdef IS_PY3K - m = PyModule_Create(&moduledef); + /* PyType_Ready automatically fills in ob_type with &PyType_Type if it's not already set */ + if (PyType_Ready(&WRtype) < 0) + return NULL; + /* Initialize the module */ + m = PyModule_Create(&moduledef); + if (m == NULL) + return NULL; #else + WRtype.ob_type = &PyType_Type; m = Py_InitModule("winrandom", WR_mod_methods); #endif - if (m == NULL) - goto errout; /* define Windows CSP Provider Types */ #ifdef PROV_RSA_FULL @@ -359,26 +378,12 @@ initwinrandom() PyModule_AddStringConstant(m, "INTEL_DEF_PROV", INTEL_DEF_PROV); #endif -out: - /* Final error check */ - if (m == NULL && !PyErr_Occurred()) { - PyErr_SetString(PyExc_ImportError, "can't initialize module"); - goto errout; - } - - /* Free local objects here */ + if (PyErr_Occurred()) + Py_FatalError("can't initialize module winrandom"); - /* Return */ #ifdef IS_PY3K return m; -#else - return; #endif - -errout: - /* Free the module and other global objects here */ - Py_CLEAR(m); - goto out; } /*