#include <linux/export.h>
#include "mpi-internal.h"
MPI mpi_alloc(unsigned nlimbs)
{
MPI a;
a = kmalloc_obj(*a);
if (!a)
return a;
if (nlimbs) {
a->d = mpi_alloc_limb_space(nlimbs);
if (!a->d) {
kfree(a);
return NULL;
}
} else {
a->d = NULL;
}
a->alloced = nlimbs;
a->nlimbs = 0;
a->sign = 0;
a->flags = 0;
a->nbits = 0;
return a;
}
EXPORT_SYMBOL_GPL(mpi_alloc);
mpi_ptr_t mpi_alloc_limb_space(unsigned nlimbs)
{
size_t len = nlimbs * sizeof(mpi_limb_t);
if (!len)
return NULL;
return kmalloc(len, GFP_KERNEL);
}
void mpi_free_limb_space(mpi_ptr_t a)
{
if (!a)
return;
kfree_sensitive(a);
}
void mpi_assign_limb_space(MPI a, mpi_ptr_t ap, unsigned nlimbs)
{
mpi_free_limb_space(a->d);
a->d = ap;
a->alloced = nlimbs;
}
int mpi_resize(MPI a, unsigned nlimbs)
{
void *p;
if (nlimbs <= a->alloced)
return 0;
if (a->d) {
p = kzalloc_objs(mpi_limb_t, nlimbs);
if (!p)
return -ENOMEM;
memcpy(p, a->d, a->alloced * sizeof(mpi_limb_t));
kfree_sensitive(a->d);
a->d = p;
} else {
a->d = kzalloc_objs(mpi_limb_t, nlimbs);
if (!a->d)
return -ENOMEM;
}
a->alloced = nlimbs;
return 0;
}
void mpi_free(MPI a)
{
if (!a)
return;
if (a->flags & 4)
kfree_sensitive(a->d);
else
mpi_free_limb_space(a->d);
if (a->flags & ~7)
pr_info("invalid flag value in mpi\n");
kfree(a);
}
EXPORT_SYMBOL_GPL(mpi_free);
MPI mpi_copy(MPI a)
{
int i;
MPI b;
if (a) {
b = mpi_alloc(a->nlimbs);
if (!b)
return NULL;
b->nlimbs = a->nlimbs;
b->sign = a->sign;
b->flags = a->flags;
b->flags &= ~(16|32);
for (i = 0; i < b->nlimbs; i++)
b->d[i] = a->d[i];
} else
b = NULL;
return b;
}
MODULE_DESCRIPTION("Multiprecision maths library");
MODULE_LICENSE("GPL");