1/* mpiutil.ac - Utility functions for MPI 2 * 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 modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (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 of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 19 */ 20 21#include "mpi-internal.h" 22 23/**************** 24 * Note: It was a bad idea to use the number of limbs to allocate 25 * because on a alpha the limbs are large but we normally need 26 * integers of n bits - So we should chnage 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 kzfree(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 cleared 84 * (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 = kmalloc(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 kzfree(a->d); 99 a->d = p; 100 } else { 101 a->d = kzalloc(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 kzfree(a->d); 116 else 117 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 125MODULE_DESCRIPTION("Multiprecision maths library"); 126MODULE_LICENSE("GPL"); 127