151 lines · c
1/* mpiutil.ac - Utility functions for MPI2 * Copyright (C) 1998, 1999 Free Software Foundation, Inc.3 *4 * This file is part of GnuPG.5 *6 * GnuPG is free software; you can redistribute it and/or modify7 * it under the terms of the GNU General Public License as published by8 * the Free Software Foundation; either version 2 of the License, or9 * (at your option) any later version.10 *11 * GnuPG is distributed in the hope that it will be useful,12 * but WITHOUT ANY WARRANTY; without even the implied warranty of13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14 * GNU General Public License for more details.15 *16 * You should have received a copy of the GNU General Public License17 * along with this program; if not, write to the Free Software18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA19 */20 21#include "mpi-internal.h"22 23/****************24 * Note: It was a bad idea to use the number of limbs to allocate25 * because on a alpha the limbs are large but we normally need26 * integers of n bits - So we should change this to bits (or bytes).27 *28 * But mpi_alloc is used in a lot of places :-)29 */30MPI mpi_alloc(unsigned nlimbs)31{32 MPI a;33 34 a = kmalloc(sizeof *a, GFP_KERNEL);35 if (!a)36 return a;37 38 if (nlimbs) {39 a->d = mpi_alloc_limb_space(nlimbs);40 if (!a->d) {41 kfree(a);42 return NULL;43 }44 } else {45 a->d = NULL;46 }47 48 a->alloced = nlimbs;49 a->nlimbs = 0;50 a->sign = 0;51 a->flags = 0;52 a->nbits = 0;53 return a;54}55EXPORT_SYMBOL_GPL(mpi_alloc);56 57mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs)58{59 size_t len = nlimbs * sizeof(mpi_limb_t);60 61 if (!len)62 return NULL;63 64 return kmalloc(len, GFP_KERNEL);65}66 67void mpi_free_limb_space(mpi_ptr_t a)68{69 if (!a)70 return;71 72 kfree_sensitive(a);73}74 75void mpi_assign_limb_space(MPI a, mpi_ptr_t ap, unsigned nlimbs)76{77 mpi_free_limb_space(a->d);78 a->d = ap;79 a->alloced = nlimbs;80}81 82/****************83 * Resize the array of A to NLIMBS. the additional space is cleared84 * (set to 0) [done by m_realloc()]85 */86int mpi_resize(MPI a, unsigned nlimbs)87{88 void *p;89 90 if (nlimbs <= a->alloced)91 return 0; /* no need to do it */92 93 if (a->d) {94 p = kcalloc(nlimbs, sizeof(mpi_limb_t), GFP_KERNEL);95 if (!p)96 return -ENOMEM;97 memcpy(p, a->d, a->alloced * sizeof(mpi_limb_t));98 kfree_sensitive(a->d);99 a->d = p;100 } else {101 a->d = kcalloc(nlimbs, sizeof(mpi_limb_t), GFP_KERNEL);102 if (!a->d)103 return -ENOMEM;104 }105 a->alloced = nlimbs;106 return 0;107}108 109void mpi_free(MPI a)110{111 if (!a)112 return;113 114 if (a->flags & 4)115 kfree_sensitive(a->d);116 else117 mpi_free_limb_space(a->d);118 119 if (a->flags & ~7)120 pr_info("invalid flag value in mpi\n");121 kfree(a);122}123EXPORT_SYMBOL_GPL(mpi_free);124 125/****************126 * Note: This copy function should not interpret the MPI127 * but copy it transparently.128 */129MPI mpi_copy(MPI a)130{131 int i;132 MPI b;133 134 if (a) {135 b = mpi_alloc(a->nlimbs);136 if (!b)137 return NULL;138 b->nlimbs = a->nlimbs;139 b->sign = a->sign;140 b->flags = a->flags;141 b->flags &= ~(16|32); /* Reset the immutable and constant flags. */142 for (i = 0; i < b->nlimbs; i++)143 b->d[i] = a->d[i];144 } else145 b = NULL;146 return b;147}148 149MODULE_DESCRIPTION("Multiprecision maths library");150MODULE_LICENSE("GPL");151