~ubuntu-branches/ubuntu/precise/gnupg2/precise-proposed

« back to all changes in this revision

Viewing changes to mpi/mpi-mul.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Urlichs
  • Date: 2006-01-24 04:31:42 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060124043142-pbg192or6qxv3yk2
Tags: 1.9.20-1
* New Upstream version. Closes:#306890,#344530
  * Closes:#320490: gpg-protect-tool fails to decrypt PKCS-12 files 
* Depend on libopensc2-dev, not -1-. Closes:#348106

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* mpi-mul.c  -  MPI functions
 
2
 *      Copyright (C) 1994, 1996 Free Software Foundation, Inc.
 
3
 *      Copyright (C) 1998, 2001 Free Software Foundation, Inc.
 
4
 *
 
5
 * This file is part of GnuPG.
 
6
 *
 
7
 * GnuPG is free software; you can redistribute it and/or modify
 
8
 * it under the terms of the GNU General Public License as published by
 
9
 * the Free Software Foundation; either version 2 of the License, or
 
10
 * (at your option) any later version.
 
11
 *
 
12
 * GnuPG is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program; if not, write to the Free Software
 
19
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
20
 *
 
21
 * Note: This code is heavily based on the GNU MP Library.
 
22
 *       Actually it's the same code with only minor changes in the
 
23
 *       way the data is stored; this is to support the abstraction
 
24
 *       of an optional secure memory allocation which may be used
 
25
 *       to avoid revealing of sensitive data due to paging etc.
 
26
 *       The GNU MP Library itself is published under the LGPL;
 
27
 *       however I decided to publish this code under the plain GPL.
 
28
 */
 
29
 
 
30
#include <config.h>
 
31
#include <stdio.h>
 
32
#include <stdlib.h>
 
33
#include "mpi-internal.h"
 
34
 
 
35
 
 
36
void
 
37
mpi_mul_ui( MPI prod, MPI mult, unsigned long small_mult )
 
38
{
 
39
    mpi_size_t size, prod_size;
 
40
    mpi_ptr_t  prod_ptr;
 
41
    mpi_limb_t cy;
 
42
    int sign;
 
43
 
 
44
    size = mult->nlimbs;
 
45
    sign = mult->sign;
 
46
 
 
47
    if( !size || !small_mult ) {
 
48
        prod->nlimbs = 0;
 
49
        prod->sign = 0;
 
50
        return;
 
51
    }
 
52
 
 
53
    prod_size = size + 1;
 
54
    if( prod->alloced < prod_size )
 
55
        mpi_resize( prod, prod_size );
 
56
    prod_ptr = prod->d;
 
57
 
 
58
    cy = mpihelp_mul_1( prod_ptr, mult->d, size, (mpi_limb_t)small_mult );
 
59
    if( cy )
 
60
        prod_ptr[size++] = cy;
 
61
    prod->nlimbs = size;
 
62
    prod->sign = sign;
 
63
}
 
64
 
 
65
 
 
66
void
 
67
mpi_mul_2exp( MPI w, MPI u, unsigned long cnt)
 
68
{
 
69
    mpi_size_t usize, wsize, limb_cnt;
 
70
    mpi_ptr_t wp;
 
71
    mpi_limb_t wlimb;
 
72
    int usign, wsign;
 
73
 
 
74
    usize = u->nlimbs;
 
75
    usign = u->sign;
 
76
 
 
77
    if( !usize ) {
 
78
        w->nlimbs = 0;
 
79
        w->sign = 0;
 
80
        return;
 
81
    }
 
82
 
 
83
    limb_cnt = cnt / BITS_PER_MPI_LIMB;
 
84
    wsize = usize + limb_cnt + 1;
 
85
    if( w->alloced < wsize )
 
86
        mpi_resize(w, wsize );
 
87
    wp = w->d;
 
88
    wsize = usize + limb_cnt;
 
89
    wsign = usign;
 
90
 
 
91
    cnt %= BITS_PER_MPI_LIMB;
 
92
    if( cnt ) {
 
93
        wlimb = mpihelp_lshift( wp + limb_cnt, u->d, usize, cnt );
 
94
        if( wlimb ) {
 
95
            wp[wsize] = wlimb;
 
96
            wsize++;
 
97
        }
 
98
    }
 
99
    else {
 
100
        MPN_COPY_DECR( wp + limb_cnt, u->d, usize );
 
101
    }
 
102
 
 
103
    /* Zero all whole limbs at low end.  Do it here and not before calling
 
104
     * mpn_lshift, not to lose for U == W.  */
 
105
    MPN_ZERO( wp, limb_cnt );
 
106
 
 
107
    w->nlimbs = wsize;
 
108
    w->sign = wsign;
 
109
}
 
110
 
 
111
 
 
112
 
 
113
void
 
114
mpi_mul( MPI w, MPI u, MPI v)
 
115
{
 
116
    mpi_size_t usize, vsize, wsize;
 
117
    mpi_ptr_t up, vp, wp;
 
118
    mpi_limb_t cy;
 
119
    int usign, vsign, usecure, vsecure, sign_product;
 
120
    int assign_wp=0;
 
121
    mpi_ptr_t tmp_limb=NULL;
 
122
 
 
123
 
 
124
    if( u->nlimbs < v->nlimbs ) { /* Swap U and V. */
 
125
        usize = v->nlimbs;
 
126
        usign = v->sign;
 
127
        usecure = mpi_is_secure(v);
 
128
        up    = v->d;
 
129
        vsize = u->nlimbs;
 
130
        vsign = u->sign;
 
131
        vsecure = mpi_is_secure(u);
 
132
        vp    = u->d;
 
133
    }
 
134
    else {
 
135
        usize = u->nlimbs;
 
136
        usign = u->sign;
 
137
        usecure = mpi_is_secure(u);
 
138
        up    = u->d;
 
139
        vsize = v->nlimbs;
 
140
        vsign = v->sign;
 
141
        vsecure = mpi_is_secure(v);
 
142
        vp    = v->d;
 
143
    }
 
144
    sign_product = usign ^ vsign;
 
145
    wp = w->d;
 
146
 
 
147
    /* Ensure W has space enough to store the result.  */
 
148
    wsize = usize + vsize;
 
149
    if ( !mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v)) ) {
 
150
        /* w is not allocated in secure space but u or v is.  To make sure
 
151
         * that no temporray results are stored in w, we temporary use 
 
152
         * a newly allocated limb space for w */
 
153
        wp = mpi_alloc_limb_space( wsize, 1 );
 
154
        assign_wp = 2; /* mark it as 2 so that we can later copy it back to
 
155
                        * mormal memory */
 
156
    }
 
157
    else if( w->alloced < wsize ) {
 
158
        if( wp == up || wp == vp ) {
 
159
            wp = mpi_alloc_limb_space( wsize, mpi_is_secure(w) );
 
160
            assign_wp = 1;
 
161
        }
 
162
        else {
 
163
            mpi_resize(w, wsize );
 
164
            wp = w->d;
 
165
        }
 
166
    }
 
167
    else { /* Make U and V not overlap with W.  */
 
168
        if( wp == up ) {
 
169
            /* W and U are identical.  Allocate temporary space for U.  */
 
170
            up = tmp_limb = mpi_alloc_limb_space( usize, usecure  );
 
171
            /* Is V identical too?  Keep it identical with U.  */
 
172
            if( wp == vp )
 
173
                vp = up;
 
174
            /* Copy to the temporary space.  */
 
175
            MPN_COPY( up, wp, usize );
 
176
        }
 
177
        else if( wp == vp ) {
 
178
            /* W and V are identical.  Allocate temporary space for V.  */
 
179
            vp = tmp_limb = mpi_alloc_limb_space( vsize, vsecure );
 
180
            /* Copy to the temporary space.  */
 
181
            MPN_COPY( vp, wp, vsize );
 
182
        }
 
183
    }
 
184
 
 
185
    if( !vsize )
 
186
        wsize = 0;
 
187
    else {
 
188
        cy = mpihelp_mul( wp, up, usize, vp, vsize );
 
189
        wsize -= cy? 0:1;
 
190
    }
 
191
 
 
192
    if( assign_wp ) {
 
193
        if (assign_wp == 2) {
 
194
            /* copy the temp wp from secure memory back to normal memory */
 
195
            mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0);
 
196
            MPN_COPY (tmp_wp, wp, wsize);
 
197
            mpi_free_limb_space (wp);
 
198
            wp = tmp_wp;
 
199
        }
 
200
        mpi_assign_limb_space( w, wp, wsize );
 
201
    }
 
202
    w->nlimbs = wsize;
 
203
    w->sign = sign_product;
 
204
    if( tmp_limb )
 
205
        mpi_free_limb_space( tmp_limb );
 
206
}
 
207
 
 
208
 
 
209
void
 
210
mpi_mulm( MPI w, MPI u, MPI v, MPI m)
 
211
{
 
212
    mpi_mul(w, u, v);
 
213
    mpi_fdiv_r( w, w, m );
 
214
}
 
215