-
+ 4F010F44B2944A2995791C5A74D41BC1FFBE017C6BCBCEFA0655DD33C72CFC6AA547B7BCEDA6705C629AB707BBD2F260023EFAE997DD1EC53FD016D22FE1D5F5
eucrypt/mpi/mpiutil.c
(0 . 0)(1 . 508)
6581 /* mpiutil.ac - Utility functions for MPI
6582 * Modified by No Such Labs. (C) 2015. See README.
6583 *
6584 * This file was originally part of Gnu Privacy Guard (GPG), ver. 1.4.10,
6585 * SHA256(gnupg-1.4.10.tar.gz):
6586 * 0bfd74660a2f6cedcf7d8256db4a63c996ffebbcdc2cf54397bfb72878c5a85a
6587 * (C) 1994-2005 Free Software Foundation, Inc.
6588 *
6589 * This program is free software: you can redistribute it and/or modify
6590 * it under the terms of the GNU General Public License as published by
6591 * the Free Software Foundation, either version 3 of the License, or
6592 * (at your option) any later version.
6593 *
6594 * This program is distributed in the hope that it will be useful,
6595 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6596 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6597 * GNU General Public License for more details.
6598 *
6599 * You should have received a copy of the GNU General Public License
6600 * along with this program. If not, see <http://www.gnu.org/licenses/>.
6601 */
6602
6603 #include <stdio.h>
6604 #include <stdlib.h>
6605 #include <string.h>
6606 #include <assert.h>
6607
6608 #include "knobs.h"
6609 #include "mpi.h"
6610 #include "mpi-internal.h"
6611 #include "memory.h"
6612 #include "util.h"
6613
6614
6615 #ifdef M_DEBUG
6616 #undef mpi_alloc
6617 #undef mpi_alloc_secure
6618 #undef mpi_free
6619 #endif
6620
6621 /****************
6622 * Note: It was a bad idea to use the number of limbs to allocate
6623 * because on a alpha the limbs are large but we normally need
6624 * integers of n bits - So we should chnage this to bits (or bytes).
6625 *
6626 * But mpi_alloc is used in a lot of places :-)
6627 */
6628 MPI
6629 #ifdef M_DEBUG
6630 mpi_debug_alloc( unsigned nlimbs, const char *info )
6631 #else
6632 mpi_alloc( unsigned nlimbs )
6633 #endif
6634 {
6635 MPI a;
6636
6637 if( DBG_MEMORY )
6638 log_debug("mpi_alloc(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
6639 #ifdef M_DEBUG
6640 a = m_debug_alloc( sizeof *a, info );
6641 a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 0, info ) : NULL;
6642 #else
6643 a = xmalloc( sizeof *a );
6644 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
6645 #endif
6646 a->alloced = nlimbs;
6647 a->nlimbs = 0;
6648 a->sign = 0;
6649 a->flags = 0;
6650 a->nbits = 0;
6651 return a;
6652 }
6653
6654 void
6655 mpi_m_check( MPI a )
6656 {
6657 m_check(a);
6658 m_check(a->d);
6659 }
6660
6661 MPI
6662 #ifdef M_DEBUG
6663 mpi_debug_alloc_secure( unsigned nlimbs, const char *info )
6664 #else
6665 mpi_alloc_secure( unsigned nlimbs )
6666 #endif
6667 {
6668 MPI a;
6669
6670 if( DBG_MEMORY )
6671 log_debug("mpi_alloc_secure(%u)\n", nlimbs*BITS_PER_MPI_LIMB );
6672 #ifdef M_DEBUG
6673 a = m_debug_alloc( sizeof *a, info );
6674 a->d = nlimbs? mpi_debug_alloc_limb_space( nlimbs, 1, info ) : NULL;
6675 #else
6676 a = xmalloc( sizeof *a );
6677 a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
6678 #endif
6679 a->alloced = nlimbs;
6680 a->flags = 1;
6681 a->nlimbs = 0;
6682 a->sign = 0;
6683 a->nbits = 0;
6684 return a;
6685 }
6686
6687
6688 #if 0
6689 static void *unused_limbs_5;
6690 static void *unused_limbs_32;
6691 static void *unused_limbs_64;
6692 #endif
6693
6694 mpi_ptr_t
6695 #ifdef M_DEBUG
6696 mpi_debug_alloc_limb_space( unsigned nlimbs, int secure, const char *info )
6697 #else
6698 mpi_alloc_limb_space( unsigned nlimbs, int secure )
6699 #endif
6700 {
6701 size_t len = nlimbs * sizeof(mpi_limb_t);
6702 mpi_ptr_t p;
6703
6704 if( DBG_MEMORY )
6705 log_debug("mpi_alloc_limb_space(%u)\n", (unsigned)len*8 );
6706 #if 0
6707 if( !secure ) {
6708 if( nlimbs == 5 && unused_limbs_5 ) { /* DSA 160 bits */
6709 p = unused_limbs_5;
6710 unused_limbs_5 = *p;
6711 return p;
6712 }
6713 else if( nlimbs == 32 && unused_limbs_32 ) { /* DSA 1024 bits */
6714 p = unused_limbs_32;
6715 unused_limbs_32 = *p;
6716 return p;
6717 }
6718 else if( nlimbs == 64 && unused_limbs_64 ) { /* DSA 2*1024 bits */
6719 p = unused_limbs_64;
6720 unused_limbs_64 = *p;
6721 return p;
6722 }
6723 }
6724 #endif
6725
6726 #ifdef M_DEBUG
6727 p = secure? m_debug_alloc_secure(len, info):m_debug_alloc( len, info );
6728 #else
6729 p = secure? xmalloc_secure( len ):xmalloc( len );
6730 #endif
6731
6732 return p;
6733 }
6734
6735 void
6736 #ifdef M_DEBUG
6737 mpi_debug_free_limb_space( mpi_ptr_t a, const char *info )
6738 #else
6739 mpi_free_limb_space( mpi_ptr_t a )
6740 #endif
6741 {
6742 if( !a )
6743 return;
6744 if( DBG_MEMORY )
6745 log_debug("mpi_free_limb_space of size %lu\n", (ulong)m_size(a)*8 );
6746
6747 #if 0
6748 if( !m_is_secure(a) ) {
6749 size_t nlimbs = m_size(a) / 4 ;
6750 void *p = a;
6751
6752 if( nlimbs == 5 ) { /* DSA 160 bits */
6753 *a = unused_limbs_5;
6754 unused_limbs_5 = a;
6755 return;
6756 }
6757 else if( nlimbs == 32 ) { /* DSA 1024 bits */
6758 *a = unused_limbs_32;
6759 unused_limbs_32 = a;
6760 return;
6761 }
6762 else if( nlimbs == 64 ) { /* DSA 2*1024 bits */
6763 *a = unused_limbs_64;
6764 unused_limbs_64 = a;
6765 return;
6766 }
6767 }
6768 #endif
6769
6770 xfree(a);
6771 }
6772
6773
6774 void
6775 mpi_assign_limb_space( MPI a, mpi_ptr_t ap, unsigned nlimbs )
6776 {
6777 mpi_free_limb_space(a->d);
6778 a->d = ap;
6779 a->alloced = nlimbs;
6780 }
6781
6782
6783
6784 /****************
6785 * Resize the array of A to NLIMBS. the additional space is cleared
6786 * (set to 0) [done by xrealloc()]
6787 */
6788 void
6789 #ifdef M_DEBUG
6790 mpi_debug_resize( MPI a, unsigned nlimbs, const char *info )
6791 #else
6792 mpi_resize( MPI a, unsigned nlimbs )
6793 #endif
6794 {
6795 if( nlimbs <= a->alloced )
6796 return; /* no need to do it */
6797 /* Note: a->secure is not used - instead the realloc functions
6798 * take care of it. Maybe we should drop a->secure completely
6799 * and rely on a mpi_is_secure function, which would be
6800 * a wrapper around m_is_secure
6801 */
6802 #ifdef M_DEBUG
6803 if( a->d )
6804 a->d = m_debug_realloc(a->d, nlimbs * sizeof(mpi_limb_t), info );
6805 else
6806 a->d = m_debug_alloc_clear( nlimbs * sizeof(mpi_limb_t), info );
6807 #else
6808 if( a->d )
6809 a->d = xrealloc(a->d, nlimbs * sizeof(mpi_limb_t) );
6810 else
6811 a->d = xmalloc_clear( nlimbs * sizeof(mpi_limb_t) );
6812 #endif
6813 a->alloced = nlimbs;
6814 }
6815
6816 void
6817 mpi_clear( MPI a )
6818 {
6819 a->nlimbs = 0;
6820 a->nbits = 0;
6821 a->flags = 0;
6822 }
6823
6824
6825 void
6826 #ifdef M_DEBUG
6827 mpi_debug_free( MPI a, const char *info )
6828 #else
6829 mpi_free( MPI a )
6830 #endif
6831 {
6832 if( !a )
6833 return;
6834 if( DBG_MEMORY )
6835 log_debug("mpi_free\n" );
6836 if( a->flags & 4 )
6837 xfree( a->d );
6838 else {
6839 #ifdef M_DEBUG
6840 mpi_debug_free_limb_space(a->d, info);
6841 #else
6842 mpi_free_limb_space(a->d);
6843 #endif
6844 }
6845 if( a->flags & ~7 )
6846 log_bug("invalid flag value in mpi\n");
6847 xfree(a);
6848 }
6849
6850
6851 void
6852 mpi_set_secure( MPI a )
6853 {
6854 mpi_ptr_t ap, bp;
6855
6856 if( (a->flags & 1) )
6857 return;
6858 a->flags |= 1;
6859 ap = a->d;
6860 if( !a->nlimbs ) {
6861 assert(!ap);
6862 return;
6863 }
6864 #ifdef M_DEBUG
6865 bp = mpi_debug_alloc_limb_space( a->nlimbs, 1, "set_secure" );
6866 #else
6867 bp = mpi_alloc_limb_space( a->nlimbs, 1 );
6868 #endif
6869 MPN_COPY( bp, ap, a->nlimbs );
6870 a->d = bp;
6871 #ifdef M_DEBUG
6872 mpi_debug_free_limb_space(ap, "set_secure");
6873 #else
6874 mpi_free_limb_space(ap);
6875 #endif
6876 }
6877
6878
6879 MPI
6880 mpi_set_opaque( MPI a, void *p, unsigned int len )
6881 {
6882 if( !a ) {
6883 #ifdef M_DEBUG
6884 a = mpi_debug_alloc(0,"alloc_opaque");
6885 #else
6886 a = mpi_alloc(0);
6887 #endif
6888 }
6889
6890 if( a->flags & 4 )
6891 xfree( a->d );
6892 else {
6893 #ifdef M_DEBUG
6894 mpi_debug_free_limb_space(a->d, "alloc_opaque");
6895 #else
6896 mpi_free_limb_space(a->d);
6897 #endif
6898 }
6899
6900 a->d = p;
6901 a->alloced = 0;
6902 a->nlimbs = 0;
6903 a->nbits = len;
6904 a->flags = 4;
6905 return a;
6906 }
6907
6908
6909 void *
6910 mpi_get_opaque( MPI a, unsigned int *len )
6911 {
6912 if( !(a->flags & 4) )
6913 log_bug("mpi_get_opaque on normal mpi\n");
6914 if( len )
6915 *len = a->nbits;
6916 return a->d;
6917 }
6918
6919
6920 /****************
6921 * Note: This copy function should not interpret the MPI
6922 * but copy it transparently.
6923 */
6924 MPI
6925 #ifdef M_DEBUG
6926 mpi_debug_copy( MPI a, const char *info )
6927 #else
6928 mpi_copy( MPI a )
6929 #endif
6930 {
6931 int i;
6932 MPI b;
6933
6934 if( a && (a->flags & 4) ) {
6935 void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits )
6936 : xmalloc( a->nbits );
6937 memcpy( p, a->d, a->nbits );
6938 b = mpi_set_opaque( NULL, p, a->nbits );
6939 }
6940 else if( a ) {
6941 #ifdef M_DEBUG
6942 b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
6943 : mpi_debug_alloc( a->nlimbs, info );
6944 #else
6945 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
6946 : mpi_alloc( a->nlimbs );
6947 #endif
6948 b->nlimbs = a->nlimbs;
6949 b->sign = a->sign;
6950 b->flags = a->flags;
6951 b->nbits = a->nbits;
6952 for(i=0; i < b->nlimbs; i++ )
6953 b->d[i] = a->d[i];
6954 }
6955 else
6956 b = NULL;
6957 return b;
6958 }
6959
6960
6961 /****************
6962 * This function allocates an MPI which is optimized to hold
6963 * a value as large as the one given in the argument and allocates it
6964 * with the same flags as A.
6965 */
6966 MPI
6967 #ifdef M_DEBUG
6968 mpi_debug_alloc_like( MPI a, const char *info )
6969 #else
6970 mpi_alloc_like( MPI a )
6971 #endif
6972 {
6973 MPI b;
6974
6975 if( a && (a->flags & 4) ) {
6976 void *p = m_is_secure(a->d)? xmalloc_secure( a->nbits )
6977 : xmalloc( a->nbits );
6978 memcpy( p, a->d, a->nbits );
6979 b = mpi_set_opaque( NULL, p, a->nbits );
6980 }
6981 else if( a ) {
6982 #ifdef M_DEBUG
6983 b = mpi_is_secure(a)? mpi_debug_alloc_secure( a->nlimbs, info )
6984 : mpi_debug_alloc( a->nlimbs, info );
6985 #else
6986 b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
6987 : mpi_alloc( a->nlimbs );
6988 #endif
6989 b->nlimbs = 0;
6990 b->sign = 0;
6991 b->flags = a->flags;
6992 b->nbits = 0;
6993 }
6994 else
6995 b = NULL;
6996 return b;
6997 }
6998
6999
7000 void
7001 mpi_set( MPI w, MPI u)
7002 {
7003 mpi_ptr_t wp, up;
7004 mpi_size_t usize = u->nlimbs;
7005 int usign = u->sign;
7006
7007 RESIZE_IF_NEEDED(w, usize);
7008 wp = w->d;
7009 up = u->d;
7010 MPN_COPY( wp, up, usize );
7011 w->nlimbs = usize;
7012 w->nbits = u->nbits;
7013 w->flags = u->flags;
7014 w->sign = usign;
7015 }
7016
7017
7018 void
7019 mpi_set_ui( MPI w, unsigned long u)
7020 {
7021 RESIZE_IF_NEEDED(w, 1);
7022 w->d[0] = u;
7023 w->nlimbs = u? 1:0;
7024 w->sign = 0;
7025 w->nbits = 0;
7026 w->flags = 0;
7027 }
7028
7029
7030 MPI
7031 mpi_alloc_set_ui( unsigned long u)
7032 {
7033 #ifdef M_DEBUG
7034 MPI w = mpi_debug_alloc(1,"alloc_set_ui");
7035 #else
7036 MPI w = mpi_alloc(1);
7037 #endif
7038 w->d[0] = u;
7039 w->nlimbs = u? 1:0;
7040 w->sign = 0;
7041 return w;
7042 }
7043
7044
7045 void
7046 mpi_swap( MPI a, MPI b)
7047 {
7048 struct gcry_mpi tmp;
7049
7050 tmp = *a; *a = *b; *b = tmp;
7051 }
7052
7053
7054 int
7055 mpi_get_nlimbs (MPI a)
7056 {
7057 return a->nlimbs;
7058 }
7059
7060
7061 int
7062 mpi_is_neg (MPI a)
7063 {
7064 return a->sign;
7065 }
7066
7067
7068 /* Return the number of limbs to store an MPI which is specified by
7069 the number of bytes to represent it. */
7070 unsigned int
7071 mpi_nlimb_hint_from_nbytes (unsigned int nbytes)
7072 {
7073 return (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
7074 }
7075
7076 /* Return the number of limbs to store an MPI which is specified by
7077 the number of bytes to represent it. */
7078 unsigned int
7079 mpi_nlimb_hint_from_nbits (unsigned int nbits)
7080 {
7081 return (nbits+BITS_PER_MPI_LIMB-1) / BITS_PER_MPI_LIMB;
7082 }
7083
7084 unsigned int
7085 mpi_get_flags (MPI a)
7086 {
7087 return a->flags;
7088 }