diff options
author | Miloslav Trmač <mitr@redhat.com> | 2010-09-06 15:00:17 +0200 |
---|---|---|
committer | Miloslav Trmač <mitr@redhat.com> | 2010-09-06 15:00:17 +0200 |
commit | c61c13594953d462597ed18d6c77e736878ff9d9 (patch) | |
tree | 583b7cb956cb9fce6c630cc634e772942e3bbaf7 | |
parent | 9cab3a1a9660ed5f798b063aa7e827eb0c95ba94 (diff) | |
parent | 8afc069c742f80d3e383ba3d0e38697aeeeb147b (diff) | |
download | kernel-crypto-ncr-standalone-rename.tar.gz kernel-crypto-ncr-standalone-rename.tar.xz kernel-crypto-ncr-standalone-rename.zip |
Merge branch 'standalone-master' into standalone-renamencr-standalone-rename
Conflicts:
crypto/userspace/libtomcrypt/misc/qsort.c
crypto/userspace/libtommath/bn_mp_and.c
crypto/userspace/libtommath/bn_mp_exteuclid.c
crypto/userspace/libtommath/bn_mp_jacobi.c
crypto/userspace/libtommath/bn_mp_or.c
crypto/userspace/libtommath/bn_mp_prime_fermat.c
crypto/userspace/libtommath/bn_mp_radix_size.c
crypto/userspace/libtommath/bn_mp_radix_smap.c
crypto/userspace/libtommath/bn_mp_read_radix.c
crypto/userspace/libtommath/bn_mp_sqrt.c
crypto/userspace/libtommath/bn_mp_toradix.c
crypto/userspace/libtommath/bn_mp_toradix_n.c
crypto/userspace/libtommath/bn_mp_xor.c
examples/Makefile
examples/ncr.c
examples/pk.c
31 files changed, 311 insertions, 1209 deletions
diff --git a/crypto/userspace/Makefile b/crypto/userspace/Makefile index cdaab9339e3..73e9ebbf385 100644 --- a/crypto/userspace/Makefile +++ b/crypto/userspace/Makefile @@ -14,25 +14,23 @@ TOMMATH_OBJECTS = libtommath/bncore.o libtommath/bn_mp_init.o libtommath/bn_mp_c libtommath/bn_mp_div_d.o libtommath/bn_mp_mod_d.o libtommath/bn_mp_expt_d.o libtommath/bn_mp_addmod.o libtommath/bn_mp_submod.o \ libtommath/bn_mp_mulmod.o libtommath/bn_mp_sqrmod.o libtommath/bn_mp_gcd.o libtommath/bn_mp_lcm.o libtommath/bn_fast_mp_invmod.o libtommath/bn_mp_invmod.o \ libtommath/bn_mp_reduce.o libtommath/bn_mp_montgomery_setup.o libtommath/bn_fast_mp_montgomery_reduce.o libtommath/bn_mp_montgomery_reduce.o \ - libtommath/bn_mp_exptmod_fast.o libtommath/bn_mp_exptmod.o libtommath/bn_mp_2expt.o libtommath/bn_mp_n_root.o libtommath/bn_mp_jacobi.o libtommath/bn_reverse.o \ + libtommath/bn_mp_exptmod_fast.o libtommath/bn_mp_exptmod.o libtommath/bn_mp_2expt.o libtommath/bn_reverse.o \ libtommath/bn_mp_count_bits.o libtommath/bn_mp_read_unsigned_bin.o libtommath/bn_mp_read_signed_bin.o libtommath/bn_mp_to_unsigned_bin.o \ libtommath/bn_mp_to_signed_bin.o libtommath/bn_mp_unsigned_bin_size.o libtommath/bn_mp_signed_bin_size.o \ - libtommath/bn_mp_xor.o libtommath/bn_mp_and.o libtommath/bn_mp_or.o libtommath/bn_mp_rand.o libtommath/bn_mp_montgomery_calc_normalization.o \ - libtommath/bn_mp_prime_is_divisible.o libtommath/bn_prime_tab.o libtommath/bn_mp_prime_fermat.o libtommath/bn_mp_prime_miller_rabin.o \ + libtommath/bn_mp_rand.o libtommath/bn_mp_montgomery_calc_normalization.o \ + libtommath/bn_mp_prime_is_divisible.o libtommath/bn_prime_tab.o libtommath/bn_mp_prime_miller_rabin.o \ libtommath/bn_mp_prime_is_prime.o libtommath/bn_mp_prime_next_prime.o libtommath/bn_mp_dr_reduce.o \ libtommath/bn_mp_dr_is_modulus.o libtommath/bn_mp_dr_setup.o libtommath/bn_mp_reduce_setup.o \ libtommath/bn_mp_toom_mul.o libtommath/bn_mp_toom_sqr.o libtommath/bn_mp_div_3.o libtommath/bn_s_mp_exptmod.o \ libtommath/bn_mp_reduce_2k.o libtommath/bn_mp_reduce_is_2k.o libtommath/bn_mp_reduce_2k_setup.o \ libtommath/bn_mp_reduce_2k_l.o libtommath/bn_mp_reduce_is_2k_l.o libtommath/bn_mp_reduce_2k_setup_l.o \ - libtommath/bn_mp_radix_smap.o libtommath/bn_mp_read_radix.o libtommath/bn_mp_toradix.o libtommath/bn_mp_radix_size.o \ - libtommath/bn_mp_cnt_lsb.o libtommath/bn_error.o \ - libtommath/bn_mp_init_multi.o libtommath/bn_mp_clear_multi.o libtommath/bn_mp_exteuclid.o libtommath/bn_mp_toradix_n.o \ - libtommath/bn_mp_prime_random_ex.o libtommath/bn_mp_get_int.o libtommath/bn_mp_sqrt.o libtommath/bn_mp_is_square.o libtommath/bn_mp_init_set.o \ + libtommath/bn_mp_cnt_lsb.o libtommath/bn_error.o libtommath/bn_mp_init_multi.o libtommath/bn_mp_clear_multi.o \ + libtommath/bn_mp_prime_random_ex.o libtommath/bn_mp_get_int.o libtommath/bn_mp_init_set.o \ libtommath/bn_mp_init_set_int.o libtommath/bn_mp_invmod_slow.o libtommath/bn_mp_prime_rabin_miller_trials.o \ libtommath/bn_mp_to_signed_bin_n.o libtommath/bn_mp_to_unsigned_bin_n.o TOMCRYPT_OBJECTS = libtomcrypt/misc/zeromem.o libtomcrypt/misc/crypt/crypt_argchk.o \ - libtomcrypt/math/rand_prime.o libtomcrypt/misc/qsort.o libtomcrypt/hashes/hash_get_oid.o \ + libtomcrypt/math/rand_prime.o libtomcrypt/hashes/hash_get_oid.o \ libtomcrypt/hashes/crypt_hash_is_valid.o libtomcrypt/hashes/hash_memory.o libtomcrypt/hashes/hash_memory_multi.o \ libtomcrypt/pk/dsa/dsa_make_key.o libtomcrypt/pk/dsa/dsa_export.o libtomcrypt/pk/dsa/dsa_import.o \ libtomcrypt/pk/dsa/dsa_free.o libtomcrypt/pk/dsa/dsa_sign_hash.o libtomcrypt/pk/dsa/dsa_verify_hash.o \ diff --git a/crypto/userspace/libtomcrypt/headers/tomcrypt.h b/crypto/userspace/libtomcrypt/headers/tomcrypt.h index fdb6c8d1f16..a9c675d0944 100644 --- a/crypto/userspace/libtomcrypt/headers/tomcrypt.h +++ b/crypto/userspace/libtomcrypt/headers/tomcrypt.h @@ -6,6 +6,7 @@ #include <linux/string.h> #include <linux/ctype.h> #include <linux/nls.h> +#include <linux/sort.h> /* use configuration data */ #include <tomcrypt_custom.h> diff --git a/crypto/userspace/libtomcrypt/headers/tomcrypt_cfg.h b/crypto/userspace/libtomcrypt/headers/tomcrypt_cfg.h index 8ad90bce4b0..93db10e6729 100644 --- a/crypto/userspace/libtomcrypt/headers/tomcrypt_cfg.h +++ b/crypto/userspace/libtomcrypt/headers/tomcrypt_cfg.h @@ -19,11 +19,11 @@ #define LTC_EXPORT #endif -LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); - /* certain platforms use macros for these, making the prototypes broken */ #ifndef LTC_NO_PROTOTYPES +LTC_EXPORT void LTC_CALL XQSORT(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); + /* you can change how memory allocation works ... */ LTC_EXPORT void * LTC_CALL XMALLOC(size_t n); LTC_EXPORT void * LTC_CALL XREALLOC(void *p, size_t n); diff --git a/crypto/userspace/libtomcrypt/headers/tomcrypt_custom.h b/crypto/userspace/libtomcrypt/headers/tomcrypt_custom.h index c537dc7605a..76b574487bc 100644 --- a/crypto/userspace/libtomcrypt/headers/tomcrypt_custom.h +++ b/crypto/userspace/libtomcrypt/headers/tomcrypt_custom.h @@ -65,7 +65,7 @@ #ifdef qsort #define LTC_NO_PROTOTYPES #endif -#define XQSORT qsort +#define XQSORT(x,y,z,w) sort(x,y,z,w,NULL) #endif /* Easy button? */ diff --git a/crypto/userspace/libtomcrypt/misc/qsort.c b/crypto/userspace/libtomcrypt/misc/qsort.c deleted file mode 100644 index 72f51088e35..00000000000 --- a/crypto/userspace/libtomcrypt/misc/qsort.c +++ /dev/null @@ -1,247 +0,0 @@ -/* Copyright (C) 1991,1992,1996,1997,1999,2004 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Written by Douglas C. Schmidt (schmidt@ics.uci.edu). - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* If you consider tuning this algorithm, you should consult first: - Engineering a sort function; Jon Bentley and M. Douglas McIlroy; - Software - Practice and Experience; Vol. 23 (11), 1249-1265, 1993. */ - -#include <tomcrypt.h> - -/* Byte-wise swap two items of size SIZE. */ -#define SWAP(a, b, size) \ - do \ - { \ - register size_t __size = (size); \ - register char *__a = (a), *__b = (b); \ - do \ - { \ - char __tmp = *__a; \ - *__a++ = *__b; \ - *__b++ = __tmp; \ - } while (--__size > 0); \ - } while (0) - -/* Discontinue quicksort algorithm when partition gets below this size. - This particular magic number was chosen to work best on a Sun 4/260. */ -#define MAX_THRESH 4 - -/* Stack node declarations used to store unfulfilled partition obligations. */ -typedef struct - { - char *lo; - char *hi; - } stack_node; - -/* The next 4 #defines implement a very fast in-line stack abstraction. */ -/* The stack needs log (total_elements) entries (we could even subtract - log(MAX_THRESH)). Since total_elements has type size_t, we get as - upper bound for log (total_elements): - bits per byte (CHAR_BIT) * sizeof(size_t). */ -#define STACK_SIZE (CHAR_BIT * sizeof(size_t)) -#define PUSH(low, high) ((void) ((top->lo = (low)), (top->hi = (high)), ++top)) -#define POP(low, high) ((void) (--top, (low = top->lo), (high = top->hi))) -#define STACK_NOT_EMPTY (stack < top) - - -/* Order size using quicksort. This implementation incorporates - four optimizations discussed in Sedgewick: - - 1. Non-recursive, using an explicit stack of pointer that store the - next array partition to sort. To save time, this maximum amount - of space required to store an array of SIZE_MAX is allocated on the - stack. Assuming a 32-bit (64 bit) integer for size_t, this needs - only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes). - Pretty cheap, actually. - - 2. Chose the pivot element using a median-of-three decision tree. - This reduces the probability of selecting a bad pivot value and - eliminates certain extraneous comparisons. - - 3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving - insertion sort to order the MAX_THRESH items within each partition. - This is a big win, since insertion sort is faster for small, mostly - sorted array segments. - - 4. The larger of the two sub-partitions is always pushed onto the - stack first, with the algorithm then concentrating on the - smaller partition. This *guarantees* no more than log (total_elems) - stack size is needed (actually O(1) in this case)! */ - -typedef int(*__compar_fn_t)(const void *, const void *); - -void -qsort (void *const pbase, size_t total_elems, size_t size, - __compar_fn_t cmp) -{ - register char *base_ptr = (char *) pbase; - - const size_t max_thresh = MAX_THRESH * size; - - if (total_elems == 0) - /* Avoid lossage with unsigned arithmetic below. */ - return; - - if (total_elems > MAX_THRESH) - { - char *lo = base_ptr; - char *hi = &lo[size * (total_elems - 1)]; - stack_node stack[STACK_SIZE]; - stack_node *top = stack; - - PUSH (NULL, NULL); - - while (STACK_NOT_EMPTY) - { - char *left_ptr; - char *right_ptr; - - /* Select median value from among LO, MID, and HI. Rearrange - LO and HI so the three values are sorted. This lowers the - probability of picking a pathological pivot value and - skips a comparison for both the LEFT_PTR and RIGHT_PTR in - the while loops. */ - - char *mid = lo + size * ((hi - lo) / size >> 1); - - if ((*cmp) ((void *) mid, (void *) lo) < 0) - SWAP (mid, lo, size); - if ((*cmp) ((void *) hi, (void *) mid) < 0) - SWAP (mid, hi, size); - else - goto jump_over; - if ((*cmp) ((void *) mid, (void *) lo) < 0) - SWAP (mid, lo, size); - jump_over:; - - left_ptr = lo + size; - right_ptr = hi - size; - - /* Here's the famous ``collapse the walls'' section of quicksort. - Gotta like those tight inner loops! They are the main reason - that this algorithm runs much faster than others. */ - do - { - while ((*cmp) ((void *) left_ptr, (void *) mid) < 0) - left_ptr += size; - - while ((*cmp) ((void *) mid, (void *) right_ptr) < 0) - right_ptr -= size; - - if (left_ptr < right_ptr) - { - SWAP (left_ptr, right_ptr, size); - if (mid == left_ptr) - mid = right_ptr; - else if (mid == right_ptr) - mid = left_ptr; - left_ptr += size; - right_ptr -= size; - } - else if (left_ptr == right_ptr) - { - left_ptr += size; - right_ptr -= size; - break; - } - } - while (left_ptr <= right_ptr); - - /* Set up pointers for next iteration. First determine whether - left and right partitions are below the threshold size. If so, - ignore one or both. Otherwise, push the larger partition's - bounds on the stack and continue sorting the smaller one. */ - - if ((size_t) (right_ptr - lo) <= max_thresh) - { - if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore both small partitions. */ - POP (lo, hi); - else - /* Ignore small left partition. */ - lo = left_ptr; - } - else if ((size_t) (hi - left_ptr) <= max_thresh) - /* Ignore small right partition. */ - hi = right_ptr; - else if ((right_ptr - lo) > (hi - left_ptr)) - { - /* Push larger left partition indices. */ - PUSH (lo, right_ptr); - lo = left_ptr; - } - else - { - /* Push larger right partition indices. */ - PUSH (left_ptr, hi); - hi = right_ptr; - } - } - } - - /* Once the BASE_PTR array is partially sorted by quicksort the rest - is completely sorted using insertion sort, since this is efficient - for partitions below MAX_THRESH size. BASE_PTR points to the beginning - of the array to sort, and END_PTR points at the very last element in - the array (*not* one beyond it!). */ - - { - char *const end_ptr = &base_ptr[size * (total_elems - 1)]; - char *tmp_ptr = base_ptr; - char *thresh = min(end_ptr, base_ptr + max_thresh); - register char *run_ptr; - - /* Find smallest element in first threshold and place it at the - array's beginning. This is the smallest array element, - and the operation speeds up insertion sort's inner loop. */ - - for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size) - if ((*cmp) ((void *) run_ptr, (void *) tmp_ptr) < 0) - tmp_ptr = run_ptr; - - if (tmp_ptr != base_ptr) - SWAP (tmp_ptr, base_ptr, size); - - /* Insertion sort, running from left-hand-side up to right-hand-side. */ - - run_ptr = base_ptr + size; - while ((run_ptr += size) <= end_ptr) - { - tmp_ptr = run_ptr - size; - while ((*cmp) ((void *) run_ptr, (void *) tmp_ptr) < 0) - tmp_ptr -= size; - - tmp_ptr += size; - if (tmp_ptr != run_ptr) - { - char *trav; - - trav = run_ptr + size; - while (--trav >= run_ptr) - { - char c = *trav; - char *hi, *lo; - - for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo) - *hi = *lo; - *hi = c; - } - } - } - } -} diff --git a/crypto/userspace/libtommath/bn_mp_and.c b/crypto/userspace/libtommath/bn_mp_and.c deleted file mode 100644 index 8ea22878f91..00000000000 --- a/crypto/userspace/libtommath/bn_mp_and.c +++ /dev/null @@ -1,57 +0,0 @@ -#include <tommath.h> -#ifdef BN_MP_AND_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* AND two ints together */ -int -mp_and (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] &= x->dp[ix]; - } - - /* zero digits above the last from the smallest mp_int */ - for (; ix < t.used; ix++) { - t.dp[ix] = 0; - } - - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_and.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/crypto/userspace/libtommath/bn_mp_div.c b/crypto/userspace/libtommath/bn_mp_div.c index aee9c94324d..723c8b503dd 100644 --- a/crypto/userspace/libtommath/bn_mp_div.c +++ b/crypto/userspace/libtommath/bn_mp_div.c @@ -195,7 +195,7 @@ int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d) mp_word tmp; tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT); tmp |= ((mp_word) x.dp[i - 1]); - tmp /= ((mp_word) y.dp[t]); + tmp = word_div_int(tmp, (int)y.dp[t]); if (tmp > (mp_word) MP_MASK) tmp = MP_MASK; q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK)); diff --git a/crypto/userspace/libtommath/bn_mp_div_3.c b/crypto/userspace/libtommath/bn_mp_div_3.c index 3c60269ecea..608e759e366 100644 --- a/crypto/userspace/libtommath/bn_mp_div_3.c +++ b/crypto/userspace/libtommath/bn_mp_div_3.c @@ -25,7 +25,7 @@ mp_div_3 (mp_int * a, mp_int *c, mp_digit * d) int res, ix; /* b = 2**DIGIT_BIT / 3 */ - b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3); + b = word_div_int (((mp_word)1) << DIGIT_BIT, 3); if ((res = mp_init_size(&q, a->used)) != MP_OKAY) { return res; diff --git a/crypto/userspace/libtommath/bn_mp_div_d.c b/crypto/userspace/libtommath/bn_mp_div_d.c index 6a26d4f0cf6..63efc2cfa69 100644 --- a/crypto/userspace/libtommath/bn_mp_div_d.c +++ b/crypto/userspace/libtommath/bn_mp_div_d.c @@ -87,7 +87,7 @@ int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d) w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]); if (w >= b) { - t = (mp_digit)(w / b); + t = (mp_digit)(word_div_int(w, b)); w -= ((mp_word)t) * ((mp_word)b); } else { t = 0; diff --git a/crypto/userspace/libtommath/bn_mp_exteuclid.c b/crypto/userspace/libtommath/bn_mp_exteuclid.c deleted file mode 100644 index e6c4ce2b853..00000000000 --- a/crypto/userspace/libtommath/bn_mp_exteuclid.c +++ /dev/null @@ -1,82 +0,0 @@ -#include <tommath.h> -#ifdef BN_MP_EXTEUCLID_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* Extended euclidean algorithm of (a, b) produces - a*u1 + b*u2 = u3 - */ -int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3) -{ - mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp; - int err; - - if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) { - return err; - } - - /* initialize, (u1,u2,u3) = (1,0,a) */ - mp_set(&u1, 1); - if ((err = mp_copy(a, &u3)) != MP_OKAY) { goto _ERR; } - - /* initialize, (v1,v2,v3) = (0,1,b) */ - mp_set(&v2, 1); - if ((err = mp_copy(b, &v3)) != MP_OKAY) { goto _ERR; } - - /* loop while v3 != 0 */ - while (mp_iszero(&v3) == MP_NO) { - /* q = u3/v3 */ - if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY) { goto _ERR; } - - /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */ - if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY) { goto _ERR; } - if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY) { goto _ERR; } - if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY) { goto _ERR; } - if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY) { goto _ERR; } - - /* (u1,u2,u3) = (v1,v2,v3) */ - if ((err = mp_copy(&v1, &u1)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&v2, &u2)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&v3, &u3)) != MP_OKAY) { goto _ERR; } - - /* (v1,v2,v3) = (t1,t2,t3) */ - if ((err = mp_copy(&t1, &v1)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&t2, &v2)) != MP_OKAY) { goto _ERR; } - if ((err = mp_copy(&t3, &v3)) != MP_OKAY) { goto _ERR; } - } - - /* make sure U3 >= 0 */ - if (u3.sign == MP_NEG) { - mp_neg(&u1, &u1); - mp_neg(&u2, &u2); - mp_neg(&u3, &u3); - } - - /* copy result out */ - if (U1 != NULL) { mp_exch(U1, &u1); } - if (U2 != NULL) { mp_exch(U2, &u2); } - if (U3 != NULL) { mp_exch(U3, &u3); } - - err = MP_OKAY; -_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL); - return err; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_exteuclid.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/crypto/userspace/libtommath/bn_mp_jacobi.c b/crypto/userspace/libtommath/bn_mp_jacobi.c deleted file mode 100644 index 91cfeeade4c..00000000000 --- a/crypto/userspace/libtommath/bn_mp_jacobi.c +++ /dev/null @@ -1,105 +0,0 @@ -#include <tommath.h> -#ifdef BN_MP_JACOBI_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* computes the jacobi c = (a | n) (or Legendre if n is prime) - * HAC pp. 73 Algorithm 2.149 - */ -int mp_jacobi (mp_int * a, mp_int * p, int *c) -{ - mp_int a1, p1; - int k, s, r, res; - mp_digit residue; - - /* if p <= 0 return MP_VAL */ - if (mp_cmp_d(p, 0) != MP_GT) { - return MP_VAL; - } - - /* step 1. if a == 0, return 0 */ - if (mp_iszero (a) == 1) { - *c = 0; - return MP_OKAY; - } - - /* step 2. if a == 1, return 1 */ - if (mp_cmp_d (a, 1) == MP_EQ) { - *c = 1; - return MP_OKAY; - } - - /* default */ - s = 0; - - /* step 3. write a = a1 * 2**k */ - if ((res = mp_init_copy (&a1, a)) != MP_OKAY) { - return res; - } - - if ((res = mp_init (&p1)) != MP_OKAY) { - goto LBL_A1; - } - - /* divide out larger power of two */ - k = mp_cnt_lsb(&a1); - if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) { - goto LBL_P1; - } - - /* step 4. if e is even set s=1 */ - if ((k & 1) == 0) { - s = 1; - } else { - /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */ - residue = p->dp[0] & 7; - - if (residue == 1 || residue == 7) { - s = 1; - } else if (residue == 3 || residue == 5) { - s = -1; - } - } - - /* step 5. if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */ - if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) { - s = -s; - } - - /* if a1 == 1 we're done */ - if (mp_cmp_d (&a1, 1) == MP_EQ) { - *c = s; - } else { - /* n1 = n mod a1 */ - if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) { - goto LBL_P1; - } - if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) { - goto LBL_P1; - } - *c = s * r; - } - - /* done */ - res = MP_OKAY; -LBL_P1:mp_clear (&p1); -LBL_A1:mp_clear (&a1); - return res; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_jacobi.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/crypto/userspace/libtommath/bn_mp_or.c b/crypto/userspace/libtommath/bn_mp_or.c deleted file mode 100644 index bff49954896..00000000000 --- a/crypto/userspace/libtommath/bn_mp_or.c +++ /dev/null @@ -1,50 +0,0 @@ -#include <tommath.h> -#ifdef BN_MP_OR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* OR two ints together */ -int mp_or (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] |= x->dp[ix]; - } - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_or.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/crypto/userspace/libtommath/bn_mp_prime_fermat.c b/crypto/userspace/libtommath/bn_mp_prime_fermat.c deleted file mode 100644 index c23d77f6de7..00000000000 --- a/crypto/userspace/libtommath/bn_mp_prime_fermat.c +++ /dev/null @@ -1,62 +0,0 @@ -#include <tommath.h> -#ifdef BN_MP_PRIME_FERMAT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* performs one Fermat test. - * - * If "a" were prime then b**a == b (mod a) since the order of - * the multiplicative sub-group would be phi(a) = a-1. That means - * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a). - * - * Sets result to 1 if the congruence holds, or zero otherwise. - */ -int mp_prime_fermat (mp_int * a, mp_int * b, int *result) -{ - mp_int t; - int err; - - /* default to composite */ - *result = MP_NO; - - /* ensure b > 1 */ - if (mp_cmp_d(b, 1) != MP_GT) { - return MP_VAL; - } - - /* init t */ - if ((err = mp_init (&t)) != MP_OKAY) { - return err; - } - - /* compute t = b**a mod a */ - if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) { - goto LBL_T; - } - - /* is it equal to b? */ - if (mp_cmp (&t, b) == MP_EQ) { - *result = MP_YES; - } - - err = MP_OKAY; -LBL_T:mp_clear (&t); - return err; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_prime_fermat.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/crypto/userspace/libtommath/bn_mp_radix_size.c b/crypto/userspace/libtommath/bn_mp_radix_size.c deleted file mode 100644 index 1b61e3a1be9..00000000000 --- a/crypto/userspace/libtommath/bn_mp_radix_size.c +++ /dev/null @@ -1,78 +0,0 @@ -#include <tommath.h> -#ifdef BN_MP_RADIX_SIZE_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* returns size of ASCII reprensentation */ -int mp_radix_size (mp_int * a, int radix, int *size) -{ - int res, digs; - mp_int t; - mp_digit d; - - *size = 0; - - /* special case for binary */ - if (radix == 2) { - *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1; - return MP_OKAY; - } - - /* make sure the radix is in range */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - if (mp_iszero(a) == MP_YES) { - *size = 2; - return MP_OKAY; - } - - /* digs is the digit count */ - digs = 0; - - /* if it's negative add one for the sign */ - if (a->sign == MP_NEG) { - ++digs; - } - - /* init a copy of the input */ - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* force temp to positive */ - t.sign = MP_ZPOS; - - /* fetch out all of the digits */ - while (mp_iszero (&t) == MP_NO) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - ++digs; - } - mp_clear (&t); - - /* return digs + 1, the 1 is for the NULL byte that would be required. */ - *size = digs + 1; - return MP_OKAY; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_radix_size.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/crypto/userspace/libtommath/bn_mp_radix_smap.c b/crypto/userspace/libtommath/bn_mp_radix_smap.c deleted file mode 100644 index 7d72feb84e6..00000000000 --- a/crypto/userspace/libtommath/bn_mp_radix_smap.c +++ /dev/null @@ -1,24 +0,0 @@ -#include <tommath.h> -#ifdef BN_MP_RADIX_SMAP_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* chars used in radix conversions */ -const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/"; -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_radix_smap.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/crypto/userspace/libtommath/bn_mp_read_radix.c b/crypto/userspace/libtommath/bn_mp_read_radix.c deleted file mode 100644 index 91c46c22f74..00000000000 --- a/crypto/userspace/libtommath/bn_mp_read_radix.c +++ /dev/null @@ -1,85 +0,0 @@ -#include <tommath.h> -#ifdef BN_MP_READ_RADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* read a string [ASCII] in a given radix */ -int mp_read_radix (mp_int * a, const char *str, int radix) -{ - int y, res, neg; - char ch; - - /* zero the digit bignum */ - mp_zero(a); - - /* make sure the radix is ok */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - /* if the leading digit is a - * minus set the sign to negative. - */ - if (*str == '-') { - ++str; - neg = MP_NEG; - } else { - neg = MP_ZPOS; - } - - /* set the integer to the default of zero */ - mp_zero (a); - - /* process each digit of the string */ - while (*str) { - /* if the radix < 36 the conversion is case insensitive - * this allows numbers like 1AB and 1ab to represent the same value - * [e.g. in hex] - */ - ch = (char) ((radix < 36) ? toupper (*str) : *str); - for (y = 0; y < 64; y++) { - if (ch == mp_s_rmap[y]) { - break; - } - } - - /* if the char was found in the map - * and is less than the given radix add it - * to the number, otherwise exit the loop. - */ - if (y < radix) { - if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) { - return res; - } - if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) { - return res; - } - } else { - break; - } - ++str; - } - - /* set the sign only if a != 0 */ - if (mp_iszero(a) != 1) { - a->sign = neg; - } - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_read_radix.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/crypto/userspace/libtommath/bn_mp_sqrt.c b/crypto/userspace/libtommath/bn_mp_sqrt.c deleted file mode 100644 index 8fd057ceedb..00000000000 --- a/crypto/userspace/libtommath/bn_mp_sqrt.c +++ /dev/null @@ -1,81 +0,0 @@ -#include <tommath.h> -#ifdef BN_MP_SQRT_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* this function is less generic than mp_n_root, simpler and faster */ -int mp_sqrt(mp_int *arg, mp_int *ret) -{ - int res; - mp_int t1,t2; - - /* must be positive */ - if (arg->sign == MP_NEG) { - return MP_VAL; - } - - /* easy out */ - if (mp_iszero(arg) == MP_YES) { - mp_zero(ret); - return MP_OKAY; - } - - if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) { - return res; - } - - if ((res = mp_init(&t2)) != MP_OKAY) { - goto E2; - } - - /* First approx. (not very bad for large arg) */ - mp_rshd (&t1,t1.used/2); - - /* t1 > 0 */ - if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { - goto E1; - } - if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { - goto E1; - } - if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { - goto E1; - } - /* And now t1 > sqrt(arg) */ - do { - if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) { - goto E1; - } - if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) { - goto E1; - } - if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) { - goto E1; - } - /* t1 >= sqrt(arg) >= t2 at this point */ - } while (mp_cmp_mag(&t1,&t2) == MP_GT); - - mp_exch(&t1,ret); - -E1: mp_clear(&t2); -E2: mp_clear(&t1); - return res; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_sqrt.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/crypto/userspace/libtommath/bn_mp_toradix.c b/crypto/userspace/libtommath/bn_mp_toradix.c deleted file mode 100644 index 0adc28d2fdb..00000000000 --- a/crypto/userspace/libtommath/bn_mp_toradix.c +++ /dev/null @@ -1,75 +0,0 @@ -#include <tommath.h> -#ifdef BN_MP_TORADIX_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* stores a bignum as a ASCII string in a given radix (2..64) */ -int mp_toradix (mp_int * a, char *str, int radix) -{ - int res, digs; - mp_int t; - mp_digit d; - char *_s = str; - - /* check range of the radix */ - if (radix < 2 || radix > 64) { - return MP_VAL; - } - - /* quick out if its zero */ - if (mp_iszero(a) == 1) { - *str++ = '0'; - *str = '\0'; - return MP_OKAY; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* if it is negative output a - */ - if (t.sign == MP_NEG) { - ++_s; - *str++ = '-'; - t.sign = MP_ZPOS; - } - - digs = 0; - while (mp_iszero (&t) == 0) { - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - *str++ = mp_s_rmap[d]; - ++digs; - } - - /* reverse the digits of the string. In this case _s points - * to the first digit [exluding the sign] of the number] - */ - bn_reverse ((unsigned char *)_s, digs); - - /* append a NULL so the string is properly terminated */ - *str = '\0'; - - mp_clear (&t); - return MP_OKAY; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_toradix.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/crypto/userspace/libtommath/bn_mp_toradix_n.c b/crypto/userspace/libtommath/bn_mp_toradix_n.c deleted file mode 100644 index 796ed55c65e..00000000000 --- a/crypto/userspace/libtommath/bn_mp_toradix_n.c +++ /dev/null @@ -1,88 +0,0 @@ -#include <tommath.h> -#ifdef BN_MP_TORADIX_N_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* stores a bignum as a ASCII string in a given radix (2..64) - * - * Stores upto maxlen-1 chars and always a NULL byte - */ -int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen) -{ - int res, digs; - mp_int t; - mp_digit d; - char *_s = str; - - /* check range of the maxlen, radix */ - if (maxlen < 2 || radix < 2 || radix > 64) { - return MP_VAL; - } - - /* quick out if its zero */ - if (mp_iszero(a) == MP_YES) { - *str++ = '0'; - *str = '\0'; - return MP_OKAY; - } - - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - - /* if it is negative output a - */ - if (t.sign == MP_NEG) { - /* we have to reverse our digits later... but not the - sign!! */ - ++_s; - - /* store the flag and mark the number as positive */ - *str++ = '-'; - t.sign = MP_ZPOS; - - /* subtract a char */ - --maxlen; - } - - digs = 0; - while (mp_iszero (&t) == 0) { - if (--maxlen < 1) { - /* no more room */ - break; - } - if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) { - mp_clear (&t); - return res; - } - *str++ = mp_s_rmap[d]; - ++digs; - } - - /* reverse the digits of the string. In this case _s points - * to the first digit [exluding the sign] of the number - */ - bn_reverse ((unsigned char *)_s, digs); - - /* append a NULL so the string is properly terminated */ - *str = '\0'; - - mp_clear (&t); - return MP_OKAY; -} - -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_toradix_n.c,v $ */ -/* $Revision: 1.5 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/crypto/userspace/libtommath/bn_mp_xor.c b/crypto/userspace/libtommath/bn_mp_xor.c deleted file mode 100644 index 59ff2e18320..00000000000 --- a/crypto/userspace/libtommath/bn_mp_xor.c +++ /dev/null @@ -1,51 +0,0 @@ -#include <tommath.h> -#ifdef BN_MP_XOR_C -/* LibTomMath, multiple-precision integer library -- Tom St Denis - * - * LibTomMath is a library that provides multiple-precision - * integer arithmetic as well as number theoretic functionality. - * - * The library was designed directly after the MPI library by - * Michael Fromberger but has been written from scratch with - * additional optimizations in place. - * - * The library is free for all purposes without any express - * guarantee it works. - * - * Tom St Denis, tomstdenis@gmail.com, http://libtom.org - */ - -/* XOR two ints together */ -int -mp_xor (mp_int * a, mp_int * b, mp_int * c) -{ - int res, ix, px; - mp_int t, *x; - - if (a->used > b->used) { - if ((res = mp_init_copy (&t, a)) != MP_OKAY) { - return res; - } - px = b->used; - x = b; - } else { - if ((res = mp_init_copy (&t, b)) != MP_OKAY) { - return res; - } - px = a->used; - x = a; - } - - for (ix = 0; ix < px; ix++) { - t.dp[ix] ^= x->dp[ix]; - } - mp_clamp (&t); - mp_exch (c, &t); - mp_clear (&t); - return MP_OKAY; -} -#endif - -/* $Source: /cvs/libtom/libtommath/bn_mp_xor.c,v $ */ -/* $Revision: 1.4 $ */ -/* $Date: 2006/12/28 01:25:13 $ */ diff --git a/crypto/userspace/libtommath/tommath.h b/crypto/userspace/libtommath/tommath.h index 31ded829977..3fa7ae89853 100644 --- a/crypto/userspace/libtommath/tommath.h +++ b/crypto/userspace/libtommath/tommath.h @@ -20,6 +20,7 @@ #include <linux/slab.h> #include <linux/random.h> #include <linux/ctype.h> +#include <linux/math64.h> #define CHAR_BIT sizeof(uint8_t)*8 @@ -64,16 +65,23 @@ extern "C" { * At the very least a mp_digit must be able to hold 7 bits * [any size beyond that is ok provided it doesn't overflow the data type] */ -#if BITS_PER_LONG <= 32 + +/* FIXME: This can be improved, but requires to use 128bit division + * on 64bit machines, which is not available in kernel now. + */ +#if BITS_PER_LONG < 32 typedef uint16_t mp_digit; typedef uint32_t mp_word; # define DIGIT_BIT 15 -#elif BITS_PER_LONG == 64 - +#elif BITS_PER_LONG <= 64 + typedef uint32_t mp_digit; typedef uint64_t mp_word; + +# define word_div_int(x,y) div_u64((x),(y)) + # define DIGIT_BIT 31 #endif @@ -88,6 +96,11 @@ extern "C" { #endif +#ifndef word_div_int +# define word_div_int(x,y) ((x)/(y)) +#endif + + /* define heap macros */ #ifndef XMALLOC # define XMALLOC(x) kmalloc(x, GFP_KERNEL) diff --git a/crypto/userspace/ncr-dh.c b/crypto/userspace/ncr-dh.c index bc45723fe3e..501eaa399cb 100644 --- a/crypto/userspace/ncr-dh.c +++ b/crypto/userspace/ncr-dh.c @@ -92,20 +92,22 @@ int dh_generate_key(dh_key * key) return -ENOMEM; } - get_random_bytes(buf, size); + do { + get_random_bytes(buf, size); - if ((err = mp_read_unsigned_bin(&key->x, buf, size)) != CRYPT_OK) { - err(); - ret = _ncr_tomerr(err); - goto fail; - } + if ((err = mp_read_unsigned_bin(&key->x, buf, size)) != CRYPT_OK) { + err(); + ret = _ncr_tomerr(err); + goto fail; + } - err = mp_mod(&key->x, &key->p, &key->x); - if (err != CRYPT_OK) { - err(); - ret = _ncr_tomerr(err); - goto fail; - } + err = mp_mod(&key->x, &key->p, &key->x); + if (err != CRYPT_OK) { + err(); + ret = _ncr_tomerr(err); + goto fail; + } + } while(mp_cmp_d(&key->x, 0) == MP_EQ || mp_cmp_d(&key->x, 1) == MP_EQ); key->type = PK_PRIVATE; diff --git a/crypto/userspace/ncr-int.h b/crypto/userspace/ncr-int.h index 87964b08065..400cf7e5218 100644 --- a/crypto/userspace/ncr-int.h +++ b/crypto/userspace/ncr-int.h @@ -20,26 +20,40 @@ struct ncr_out; // Not all known algorithms - only for quick internal identification. Note // that more than one struct algo_properties_st may share the same enum value! -enum ncr_algorithm { - NCR_ALG_NONE__, +typedef enum { + NCR_ALG_NONE, NCR_ALG_NULL, NCR_ALG_3DES_CBC, - - NCR_ALG_MD5, + NCR_ALG_3DES_ECB, + + NCR_ALG_AES_ECB, + NCR_ALG_AES_CBC, + NCR_ALG_AES_CTR, + + NCR_ALG_CAMELIA_ECB, + NCR_ALG_CAMELIA_CBC, + NCR_ALG_CAMELIA_CTR, + + NCR_ALG_MD5=200, NCR_ALG_SHA1, NCR_ALG_SHA2_224, NCR_ALG_SHA2_256, NCR_ALG_SHA2_384, NCR_ALG_SHA2_512, - NCR_ALG_RSA, + NCR_ALG_RSA=600, NCR_ALG_DSA, NCR_ALG_DH, +} ncr_algorithm_t; + +struct algo_oid_st { + oid_st oid; + int key_size; }; struct algo_properties_st { - enum ncr_algorithm algo; + ncr_algorithm_t algo; const char *kstr; size_t kstr_len; unsigned needs_iv:1; @@ -56,6 +70,7 @@ struct algo_properties_st { * NCR_KEY_TYPE_PUBLIC for a public key algorithm. */ ncr_key_type_t key_type; + const struct algo_oid_st *oids; }; struct key_item_st { @@ -189,9 +204,11 @@ int key_to_storage_data( uint8_t** data, size_t * data_size, const struct key_it /* misc helper macros */ -const struct algo_properties_st *_ncr_algo_to_properties(const char *algo); +const struct algo_properties_st *_ncr_algo_to_properties(ncr_algorithm_t algo); const struct algo_properties_st *_ncr_nla_to_properties(const struct nlattr *nla); int _ncr_key_get_sec_level(struct key_item_st* item); +const struct algo_properties_st *_ncr_oid_to_properties(oid_st* oid); +const oid_st* _ncr_properties_to_oid(const struct algo_properties_st * prop, int key_size); /* CONFIG_COMPAT handling */ diff --git a/crypto/userspace/ncr-key-storage.c b/crypto/userspace/ncr-key-storage.c index 9afa2dc0411..bc64131ea82 100644 --- a/crypto/userspace/ncr-key-storage.c +++ b/crypto/userspace/ncr-key-storage.c @@ -35,7 +35,7 @@ struct packed_key { uint32_t version; uint8_t type; uint32_t flags; - uint8_t algorithm[32]; /* NUL-terminated */ + uint32_t algorithm; uint8_t key_id[MAX_KEY_ID_SIZE]; uint8_t key_id_size; @@ -43,7 +43,7 @@ struct packed_key { uint32_t raw_size; } __attribute__((__packed__)); -#define THIS_VERSION 1 +#define THIS_VERSION 2 int key_to_storage_data( uint8_t** sdata, size_t * sdata_size, const struct key_item_st *key) { @@ -59,8 +59,9 @@ int key_to_storage_data( uint8_t** sdata, size_t * sdata_size, const struct key_ pkey->version = THIS_VERSION; pkey->type = key->type; pkey->flags = key->flags; - BUG_ON(strlen(key->algorithm->kstr) > sizeof(pkey->algorithm) - 1); - strcpy(pkey->algorithm, key->algorithm->kstr); + + pkey->algorithm = key->algorithm->algo; + pkey->key_id_size = key->key_id_size; memcpy(pkey->key_id, key->key_id, key->key_id_size); @@ -96,7 +97,6 @@ int key_from_storage_data(struct key_item_st* key, const void* data, size_t data int ret; if (data_size != sizeof(*pkey) || pkey->version != THIS_VERSION - || memchr(pkey->algorithm, '\0', sizeof(pkey->algorithm)) == NULL || pkey->key_id_size > MAX_KEY_ID_SIZE) { err(); return -EINVAL; diff --git a/crypto/userspace/ncr-key-wrap.c b/crypto/userspace/ncr-key-wrap.c index 7ea70cfc847..a15d3710653 100644 --- a/crypto/userspace/ncr-key-wrap.c +++ b/crypto/userspace/ncr-key-wrap.c @@ -36,6 +36,12 @@ #define KEY_WRAP_VERSION 0 +/* To be further checked. If the current implemented key wrapping mechanism + * has no issues, it might be possible to relax the requirement for + * privileged key wrapping. + */ +#define KEY_WRAP_IS_PRIVILEGED + typedef uint8_t val64_t[8]; static const val64_t initA = "\xA6\xA6\xA6\xA6\xA6\xA6\xA6\xA6"; @@ -537,6 +543,13 @@ const void *iv; size_t data_size, iv_size; int ret; +#ifdef KEY_WRAP_IS_PRIVILEGED + if (current_euid() != 0) { + err(); + return -EPERM; + } +#endif + if (wrap->buffer_size < 0) { err(); return -EINVAL; @@ -640,6 +653,13 @@ void* data = NULL; size_t data_size; int ret; +#ifdef KEY_WRAP_IS_PRIVILEGED + if (current_euid() != 0) { + err(); + return -EPERM; + } +#endif + ret = ncr_key_item_get_write(&wkey, lst, wrap->dest_key); if (ret < 0) { err(); @@ -831,8 +851,8 @@ fail: /* Packed data are DER encoded: * PackedData ::= SEQUENCE { * version INTEGER { v1(0) } - * type INTEGER { secret_key(0), rsa_privkey(1), rsa_pubkey(2), dsa_privkey(3), dsa_pubkey(4), - * dh_privkey(5), dh_pubkey(6) }, + * algorithm OBJECT IDENTIFIER, + * type INTEGER { secret_key(0), public(1), private(2) }, * data OCTET STRING * } * @@ -847,6 +867,7 @@ static int key_to_packed_data( uint8_t** sdata, size_t * sdata_size, const struc unsigned long version = KEY_WRAP_VERSION; unsigned long type; unsigned long derlen; + const oid_st* oid; *sdata_size = KEY_DATA_MAX_SIZE; pkey = kmalloc(*sdata_size, GFP_KERNEL); @@ -875,37 +896,25 @@ static int key_to_packed_data( uint8_t** sdata, size_t * sdata_size, const struc goto fail; } - switch (key->algorithm->algo) { - case NCR_ALG_RSA: - if (key->type == NCR_KEY_TYPE_PUBLIC) - type = 2; - else type = 1; - break; - case NCR_ALG_DSA: - if (key->type == NCR_KEY_TYPE_PUBLIC) - type = 4; - else type = 3; - break; - case NCR_ALG_DH: - if (key->type == NCR_KEY_TYPE_PUBLIC) - type = 6; - else type = 5; - break; - default: - /* unsupported yet */ - ret = -EINVAL; - err(); - goto fail; - } - + if (key->type == NCR_KEY_TYPE_PUBLIC) + type = 1; + else type = 2; } else { err(); ret = -EINVAL; goto fail; } + + oid = _ncr_properties_to_oid(key->algorithm, pkey_size); + if (oid == NULL) { + err(); + ret = -EOPNOTSUPP; + goto fail; + } err = der_encode_sequence_multi(derkey, &derlen, LTC_ASN1_SHORT_INTEGER, 1UL, &version, + LTC_ASN1_OBJECT_IDENTIFIER, oid->OIDlen, oid->OID, LTC_ASN1_SHORT_INTEGER, 1UL, &type, LTC_ASN1_OCTET_STRING, (unsigned long)pkey_size, pkey, LTC_ASN1_EOL, 0UL, NULL); @@ -934,42 +943,17 @@ inline static int packed_type_to_key_type(unsigned long type, struct key_item_st switch(type) { case 0: key->type = NCR_KEY_TYPE_SECRET; - key->algorithm = _ncr_algo_to_properties("cbc(aes)"); break; case 1: - key->type = NCR_KEY_TYPE_PRIVATE; - key->algorithm = _ncr_algo_to_properties("rsa"); - break; - case 2: - key->type = NCR_KEY_TYPE_PUBLIC; - key->algorithm = _ncr_algo_to_properties("rsa"); - break; - case 3: - key->type = NCR_KEY_TYPE_PRIVATE; - key->algorithm = _ncr_algo_to_properties("dsa"); - break; - case 4: key->type = NCR_KEY_TYPE_PUBLIC; - key->algorithm = _ncr_algo_to_properties("dsa"); break; - case 5: + case 2: key->type = NCR_KEY_TYPE_PRIVATE; - key->algorithm = _ncr_algo_to_properties("dh"); - break; - case 6: - key->type = NCR_KEY_TYPE_PUBLIC; - key->algorithm = _ncr_algo_to_properties("dh"); break; default: err(); return -EINVAL; } - - if (key->algorithm == NULL) { - err(); - return -EINVAL; - } - return 0; } @@ -981,9 +965,10 @@ static int key_from_packed_data(struct nlattr *tb[], struct key_item_st *key, const void *data, size_t data_size) { ltc_asn1_list list[6]; - int ret, i = 0, pkey_size, err; + int ret, i, pkey_size, err; unsigned long version, type; uint8_t * pkey = NULL; + oid_st oid; if (data_size > DER_KEY_MAX_SIZE) { err(); @@ -997,10 +982,16 @@ static int key_from_packed_data(struct nlattr *tb[], struct key_item_st *key, return -ENOMEM; } + i = 0; + list[i].type = LTC_ASN1_SHORT_INTEGER; list[i].size = 1; list[i++].data = &version; + list[i].type = LTC_ASN1_OBJECT_IDENTIFIER; + list[i].size = sizeof(oid.OID)/sizeof(oid.OID[0]); + list[i++].data = oid.OID; + list[i].type = LTC_ASN1_SHORT_INTEGER; list[i].size = 1; list[i++].data = &type; @@ -1015,14 +1006,15 @@ static int key_from_packed_data(struct nlattr *tb[], struct key_item_st *key, ret = _ncr_tomerr(err); goto fail; } - + if (version != KEY_WRAP_VERSION) { err(); ret = -EINVAL; goto fail; } - - pkey_size = list[2].size; + + oid.OIDlen = list[1].size; + pkey_size = list[3].size; ret = packed_type_to_key_type(type, key); if (ret < 0) { @@ -1030,11 +1022,26 @@ static int key_from_packed_data(struct nlattr *tb[], struct key_item_st *key, goto fail; } + key->algorithm = _ncr_oid_to_properties(&oid); + if (key->algorithm == NULL) { + err(); + ret = -EINVAL; + goto fail; + } + ret = ncr_key_update_flags(key, tb[NCR_ATTR_KEY_FLAGS]); if (ret != 0) { err(); return ret; } + + +#ifndef KEY_WRAP_IS_PRIVILEGED + /* Do not allow key unwrapping to result to exportable keys + */ + if (current_euid() != 0) + key->flags &= (~NCR_KEY_FLAG_EXPORTABLE); +#endif if (key->type == NCR_KEY_TYPE_SECRET) { if (data_size > NCR_CIPHER_MAX_KEY_LEN) { diff --git a/crypto/userspace/ncr-key.c b/crypto/userspace/ncr-key.c index 406e03299c3..8e082d169a2 100644 --- a/crypto/userspace/ncr-key.c +++ b/crypto/userspace/ncr-key.c @@ -558,7 +558,7 @@ int bits; /* FIXME: should we move everything here into algorithm properties? */ if (item->type == NCR_KEY_TYPE_SECRET) { - if (item->algorithm->algo == NCR_ALG_3DES_CBC) + if (item->algorithm->algo == NCR_ALG_3DES_CBC || item->algorithm->algo == NCR_ALG_3DES_ECB) return 112; return item->key.secret.size*8; diff --git a/crypto/userspace/ncr-pk.c b/crypto/userspace/ncr-pk.c index 9b9078efe38..904e8d65ace 100644 --- a/crypto/userspace/ncr-pk.c +++ b/crypto/userspace/ncr-pk.c @@ -123,7 +123,7 @@ static int ncr_pk_make_public_and_id( struct key_item_st * private, struct key_i } key_id_size = MAX_KEY_ID_SIZE; - cret = hash_memory(_ncr_algo_to_properties("sha1"), tmp, max_size, + cret = hash_memory(_ncr_algo_to_properties(NCR_ALG_SHA1), tmp, max_size, private->key_id, &key_id_size); if (cret != CRYPT_OK) { err(); diff --git a/crypto/userspace/ncr-sessions.c b/crypto/userspace/ncr-sessions.c index c65db2f751e..cb18853d974 100644 --- a/crypto/userspace/ncr-sessions.c +++ b/crypto/userspace/ncr-sessions.c @@ -212,6 +212,89 @@ err_sess: return NULL; } +const oid_st* _ncr_properties_to_oid(const struct algo_properties_st * prop, int key_size) +{ +int i = 0; + + if (prop->oids == NULL) + return NULL; + + do { + if (key_size == prop->oids[i].key_size || + prop->oids[i].key_size == -1 /* catch all */) { + + return &prop->oids[i].oid; + } + } while(prop->oids[++i].key_size != 0); + + return NULL; +} + +const static struct algo_oid_st aes_cbc_oids[] = { + {.key_size=16, + .oid = {{2,16,840,1,101,3,4,1,2}, 9}}, + {.key_size=24, + .oid = {{2,16,840,1,101,3,4,1,22}, 9}}, + {.key_size=32, + .oid = {{2,16,840,1,101,3,4,1,42}, 9}}, + {.key_size=0 } +}; + +const static struct algo_oid_st aes_ecb_oids[] = { + {.key_size=16, + .oid = {{2,16,840,1,101,3,4,1,1}, 9}}, + {.key_size=24, + .oid = {{2,16,840,1,101,3,4,1,21}, 9}}, + {.key_size=32, + .oid = {{2,16,840,1,101,3,4,1,41}, 9}}, + {.key_size=0 } +}; + +const static struct algo_oid_st des3_cbc_oids[] = { + {.key_size=-1, + .oid = {{1,2,840,113549,3,7}, 6}}, + {.key_size=0 } +}; + +/* http://www.oid-info.com/get/1.3.6.1.4.1.4929.1.7 + */ +const static struct algo_oid_st des3_ecb_oids[] = { + {.key_size=-1, + .oid = {{1,3,6,1,4,1,4929,1,7}, 9}}, + {.key_size=0 } +}; + +const static struct algo_oid_st camelia_cbc_oids[] = { + {.key_size=16, + .oid = {{1,2,392,200011,61,1,1,1,2}, 9}}, + {.key_size=24, + .oid = {{1,2,392,200011,61,1,1,1,3}, 9}}, + {.key_size=32, + .oid = {{1,2,392,200011,61,1,1,1,4}, 9}}, + {.key_size=0 } +}; + +const static struct algo_oid_st rsa_oid[] = { + {.key_size=-1, + .oid = {{1,2,840,113549,1,1,1}, 7}}, + {.key_size=0 } +}; + +const static struct algo_oid_st dsa_oid[] = { + {.key_size=-1, + .oid = {{1,2,840,10040,4,1}, 6}}, + {.key_size=0 } +}; + +const static struct algo_oid_st dh_oid[] = { + {.key_size=-1, + .oid = {{1,2,840,10046,2,1}, 6}}, + {.key_size=0 } +}; + +/* OIDs are used in cipher algorithms to distinguish keys on key wrapping. + */ + static const struct algo_properties_st algo_properties[] = { #define KSTR(x) .kstr = x, .kstr_len = sizeof(x) - 1 { .algo = NCR_ALG_NULL, KSTR("ecb(cipher_null)"), @@ -219,25 +302,28 @@ static const struct algo_properties_st algo_properties[] = { .key_type = NCR_KEY_TYPE_INVALID }, { .algo = NCR_ALG_3DES_CBC, KSTR("cbc(des3_ede)"), .needs_iv = 1, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, - { KSTR("cbc(aes)"), + .key_type = NCR_KEY_TYPE_SECRET, .oids = des3_cbc_oids }, + { .algo = NCR_ALG_3DES_ECB, KSTR("ecb(des3_ede)"), + .needs_iv = 0, .is_symmetric=1, .can_encrypt=1, + .key_type = NCR_KEY_TYPE_SECRET, .oids = des3_ecb_oids }, + { .algo = NCR_ALG_AES_CBC, KSTR("cbc(aes)"), .needs_iv = 1, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, - { KSTR("cbc(camelia)"), + .key_type = NCR_KEY_TYPE_SECRET, .oids = aes_cbc_oids }, + { .algo = NCR_ALG_CAMELIA_CBC, KSTR("cbc(camelia)"), .needs_iv = 1, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, - { KSTR("ctr(aes)"), + .key_type = NCR_KEY_TYPE_SECRET, .oids = camelia_cbc_oids }, + { .algo = NCR_ALG_AES_CTR, KSTR("ctr(aes)"), .needs_iv = 1, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, - { KSTR("ctr(camelia)"), + .key_type = NCR_KEY_TYPE_SECRET, /* FIXME: no OIDs */ }, + { .algo = NCR_ALG_CAMELIA_CTR, KSTR("ctr(camelia)"), .needs_iv = 1, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, - { KSTR("ecb(aes)"), + .key_type = NCR_KEY_TYPE_SECRET, /* FIXME: no OIDs */ }, + { .algo = NCR_ALG_AES_ECB, KSTR("ecb(aes)"), .needs_iv = 0, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, - { KSTR("ecb(camelia)"), + .key_type = NCR_KEY_TYPE_SECRET, .oids = aes_ecb_oids }, + { .algo = NCR_ALG_CAMELIA_ECB, KSTR("ecb(camelia)"), .needs_iv = 0, .is_symmetric=1, .can_encrypt=1, - .key_type = NCR_KEY_TYPE_SECRET }, + .key_type = NCR_KEY_TYPE_SECRET, /* FIXME: no OIDs */ }, { .algo = NCR_ALG_SHA1, KSTR("sha1"), .digest_size = 20, .can_digest=1, .key_type = NCR_KEY_TYPE_INVALID }, @@ -277,38 +363,77 @@ static const struct algo_properties_st algo_properties[] = { /* NOTE: These algorithm names are not available through the kernel API (yet). */ { .algo = NCR_ALG_RSA, KSTR("rsa"), .is_pk = 1, - .can_encrypt=1, .can_sign=1, .key_type = NCR_KEY_TYPE_PUBLIC }, - { .algo = NCR_ALG_RSA, KSTR(NCR_ALG_RSA_TRANSPARENT_HASH), .is_pk = 1, - .can_encrypt=1, .can_sign=1, .has_transparent_hash = 1, - .key_type = NCR_KEY_TYPE_PUBLIC }, + .can_encrypt=1, .can_sign=1, .key_type = NCR_KEY_TYPE_PUBLIC, + .oids = rsa_oid }, { .algo = NCR_ALG_DSA, KSTR("dsa"), .is_pk = 1, - .can_sign=1, .key_type = NCR_KEY_TYPE_PUBLIC }, + .can_sign=1, .key_type = NCR_KEY_TYPE_PUBLIC, + .oids = dsa_oid }, + { .algo = NCR_ALG_DH, KSTR("dh"), .is_pk = 1, + .can_kx=1, .key_type = NCR_KEY_TYPE_PUBLIC, + .oids = dh_oid }, + { .algo = NCR_ALG_DSA, KSTR(NCR_ALG_DSA_TRANSPARENT_HASH), .is_pk = 1, .can_sign=1, .has_transparent_hash = 1, - .key_type = NCR_KEY_TYPE_PUBLIC }, - { .algo = NCR_ALG_DH, KSTR("dh"), .is_pk = 1, - .can_kx=1, .key_type = NCR_KEY_TYPE_PUBLIC }, + .key_type = NCR_KEY_TYPE_PUBLIC, .oids = rsa_oid }, + { .algo = NCR_ALG_RSA, KSTR(NCR_ALG_RSA_TRANSPARENT_HASH), .is_pk = 1, + .can_encrypt=1, .can_sign=1, .has_transparent_hash = 1, + .key_type = NCR_KEY_TYPE_PUBLIC, .oids = dsa_oid }, + #undef KSTR }; /* The lookups by string are inefficient - can we look up all we need from crypto API? */ -const struct algo_properties_st *_ncr_algo_to_properties(const char *algo) +const struct algo_properties_st *_ncr_algo_to_properties(ncr_algorithm_t algo) { const struct algo_properties_st *a; - size_t name_len; - name_len = strlen(algo); for (a = algo_properties; a < algo_properties + ARRAY_SIZE(algo_properties); a++) { - if (a->kstr_len == name_len - && memcmp(a->kstr, algo, name_len) == 0) + if (a->algo == algo) return a; } return NULL; } +static void print_oid(oid_st* oid) +{ +char txt[128]=""; +char tmp[64]; +int i; + + for (i=0;i<oid->OIDlen;i++) { + sprintf(tmp, "%d.", (int)oid->OID[i]); + strcat(txt, tmp); + } + + dprintk(1, KERN_DEBUG, "unknown oid: %s\n", txt); +} + +const struct algo_properties_st *_ncr_oid_to_properties(oid_st* oid) +{ + const struct algo_properties_st *a; + int i; + + for (a = algo_properties; + a < algo_properties + ARRAY_SIZE(algo_properties); a++) { + + i=0; + + if (a->oids == NULL) continue; + + do { + if (a->oids[i].oid.OIDlen == oid->OIDlen && + memcmp(oid->OID, a->oids[i].oid.OID, oid->OIDlen*sizeof(oid->OID[0]))==0) + return a; + } while(a->oids[++i].key_size != 0); + } + + print_oid(oid); + return NULL; +} + const struct algo_properties_st *_ncr_nla_to_properties(const struct nlattr *nla) { const struct algo_properties_st *a; @@ -537,6 +662,14 @@ static struct session_item_st *_ncr_session_init(struct ncr_lists *lists, goto fail; } + /* wrapping keys cannot be used for anything except wrapping. + */ + if (ns->key->flags & NCR_KEY_FLAG_WRAPPING) { + err(); + ret = -EINVAL; + goto fail; + } + if (ns->algorithm->is_hmac && ns->key->type == NCR_KEY_TYPE_SECRET) { if (ns->algorithm->is_pk) { err(); @@ -592,6 +725,14 @@ static struct session_item_st *_ncr_session_init(struct ncr_lists *lists, } if (ns->algorithm->has_transparent_hash) { + /* transparent hash has to be allowed by the key + */ + if (!(ns->key->flags & NCR_KEY_FLAG_ALLOW_TRANSPARENT_HASH)) { + err(); + ret = -EPERM; + goto fail; + } + ns->transparent_hash = kzalloc(ns->hash.digestsize, GFP_KERNEL); if (ns->transparent_hash == NULL) { err(); @@ -1167,6 +1308,12 @@ static int _ncr_session_update_key(struct ncr_lists *lists, ret = -EINVAL; goto fail; } + + if (!(key->flags & NCR_KEY_FLAG_HASHABLE)) { + err(); + ret = -EPERM; + goto fail; + } switch(sess->op) { case NCR_OP_ENCRYPT: diff --git a/utils.c b/crypto/userspace/utils.c index a427833fdad..a427833fdad 100644 --- a/utils.c +++ b/crypto/userspace/utils.c diff --git a/utils.h b/crypto/userspace/utils.h index 2802afa7758..2802afa7758 100644 --- a/utils.h +++ b/crypto/userspace/utils.h diff --git a/include/linux/ncr.h b/include/linux/ncr.h index ce84f7a7f85..e4500b9c0d7 100644 --- a/include/linux/ncr.h +++ b/include/linux/ncr.h @@ -106,6 +106,8 @@ typedef __s32 ncr_key_t; */ #define NCR_KEY_FLAG_WRAPPING (1<<6) #define NCR_KEY_FLAG_UNWRAPPING (1<<7) +#define NCR_KEY_FLAG_HASHABLE (1<<8) +#define NCR_KEY_FLAG_ALLOW_TRANSPARENT_HASH (1<<9) struct ncr_key_generate { __u32 input_size, output_size; |