diff -r a179b74831c9 -r c1f20ce4abcf kerneltest/e32utils/nistsecurerng/src/genutils.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32utils/nistsecurerng/src/genutils.cpp Tue Aug 31 16:34:26 2010 +0300 @@ -0,0 +1,693 @@ +/* +* Portions Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* The original NIST Statistical Test Suite code is placed in public domain. +* (http://csrc.nist.gov/groups/ST/toolkit/rng/documentation_software.html) +* +* This software was developed at the National Institute of Standards and Technology by +* employees of the Federal Government in the course of their official duties. Pursuant +* to title 17 Section 105 of the United States Code this software is not subject to +* copyright protection and is in the public domain. The NIST Statistical Test Suite is +* an experimental system. NIST assumes no responsibility whatsoever for its use by other +* parties, and makes no guarantees, expressed or implied, about its quality, reliability, +* or any other characteristic. We would appreciate acknowledgment if the software is used. +*/ + +/* + * file: mp.c + * + * DESCRIPTION + * + * These functions comprise a multi-precision integer arithmetic + * and discrete function package. + */ + +#include "../include/genutils.h" + +#define MAXPLEN 384 + + +/***************************************** +** greater - Test if x > y * +** * +** Returns TRUE (1) if x greater than y, * +** otherwise FALSE (0). * +** * +** Parameters: * +** * +** x Address of array x * +** y Address of array y * +** l Length both x and y in bytes * +** * +******************************************/ +int greater(BYTE *x, BYTE *y, int l) +{ + int i; + + for ( i=0; i y[i] ) + return 1; + + return 0; +} + + +/***************************************** +** less - Test if x < y * +** * +** Returns TRUE (1) if x less than y, * +** otherwise FALSE (0). * +** * +** Parameters: * +** * +** x Address of array x * +** y Address of array y * +** l Length both x and y in bytes * +** * +******************************************/ +int less(BYTE *x, BYTE *y, int l) +{ + int i; + + for ( i=0; i>= 1; /* shift the word right once (ms bit = 0) */ + if ( c1 ) + *p |= 0x80; + c1 = c2; + c2 = 0; + p++; + } + + *p >>= 1; /* shift the word right once (ms bit = 0) */ + if ( c1 ) + *p |= 0x80; +} + + +/***************************************** +** Mult - Multiply two integers * +** * +** A = B * C * +** * +** Parameters: * +** * +** A Address of the result * +** B Address of the multiplier * +** C Address of the multiplicand * +** LB Length of B in bytes * +** LC Length of C in bytes * +** * +** NOTE: A MUST be LB+LC in length * +** * +******************************************/ +int Mult(BYTE *A, BYTE *B, int LB, BYTE *C, int LC) +{ + int i, j; + int k = 0; + DIGIT result; + + + for ( i=LB-1; i>=0; i-- ) { + result = 0; + for ( j=LC-1; j>=0; j-- ) { + k = i+j+1; + result = (DIGIT)((DIGIT)A[k] + ((DIGIT)(B[i] * C[j])) + (result >> 8)); + A[k] = (BYTE)result; + } + A[--k] = (BYTE)(result >> 8); + } + + return 0; +} + + +void ModSqr(BYTE *A, BYTE *B, int LB, BYTE *M, int LM) +{ + + Square(A, B, LB); + Mod(A, 2*LB, M, LM); +} + +void ModMult(BYTE *A, BYTE *B, int LB, BYTE *C, int LC, BYTE *M, int LM) +{ + Mult(A, B, LB, C, LC); + Mod(A, (LB+LC), M, LM); +} + + +/***************************************** +** smult - Multiply array by a scalar. * +** * +** A = b * C * +** * +** Parameters: * +** * +** A Address of the result * +** b Scalar (1 BYTE) * +** C Address of the multiplicand * +** L Length of C in bytes * +** * +** NOTE: A MUST be L+1 in length * +** * +******************************************/ +void smult(BYTE *A, BYTE b, BYTE *C, int L) +{ + int i; + DIGIT result; + + result = 0; + for ( i=L-1; i>0; i-- ) { + result = (DIGIT)(A[i] + ((DIGIT)b * C[i]) + (result >> 8)); + A[i] = (BYTE)(result & 0xff); + A[i-1] = (BYTE)(result >> 8); + } +} + +/***************************************** +** Square() - Square an integer * +** * +** A = B^2 * +** * +** Parameters: * +** * +** A Address of the result * +** B Address of the operand * +** L Length of B in bytes * +** * +** NOTE: A MUST be 2*L in length * +** * +******************************************/ +void Square(BYTE *A, BYTE *B, int L) +{ + Mult(A, B, L, B, L); +} + +/***************************************** +** ModExp - Modular Exponentiation * +** * +** A = B ** C (MOD M) * +** * +** Parameters: * +** * +** A Address of result * +** B Address of mantissa * +** C Address of exponent * +** M Address of modulus * +** LB Length of B in bytes * +** LC Length of C in bytes * +** LM Length of M in bytes * +** * +** NOTE: The integer B must be less * +** than the modulus M. * +** NOTE: A must be at least 3*LM * +** bytes long. However, the * +** result stored in A will be * +** only LM bytes long. * +******************************************/ +void ModExp(BYTE *A, BYTE *B, int LB, BYTE *C, int LC, BYTE *M, int LM) +{ + BYTE wmask; + int bits; + + bits = LC*8; + wmask = 0x80; + + A[LM-1] = 1; + + while ( !sniff_bit(C,wmask) ) { + wmask >>= 1; + bits--; + if ( !wmask ) { + wmask = 0x80; + C++; + } + } + + while ( bits-- ) { + memset(A+LM, 0x00, LM*2); + + /* temp = A*A (MOD M) */ + ModSqr(A+LM, A,LM, M,LM); + + /* A = lower L bytes of temp */ + memcpy(A, A+LM*2, LM); + memset(A+LM, 0x00, 2*LM); + + if ( sniff_bit(C,wmask) ) { + memset(A+LM, 0x00, (LM+LB)); + ModMult(A+LM, B,LB, A,LM, M,LM); /* temp = B * A (MOD M) */ + memcpy(A, A+LM+(LM+LB)-LM, LM); /* A = lower LM bytes of temp */ + memset(A+LM, 0x00, 2*LM); + } + + wmask >>= 1; + if ( !wmask ) { + wmask = 0x80; + C++; + } + } +} + + +/* DivMod: + * + * computes: + * quot = x / n + * rem = x % n + * returns: + * length of "quot" + * + * len of rem is lenx+1 + */ +int DivMod(BYTE *x, int lenx, BYTE *n, int lenn, BYTE *quot, BYTE *rem) +{ + BYTE *tx, *tn, *ttx, *ts, bmult[1]; + int i, shift, lgth_x, lgth_n, t_len, lenq; + DIGIT tMSn, mult; + ULONG tMSx; + int underflow; + + tx = x; + tn = n; + + /* point to the MSD of n */ + for ( i=0, lgth_n=lenn; i n, WATCH OUT if lgth_x == lgth_n */ + while ( (lgth_x > lgth_n) || ((lgth_x == lgth_n) && !less(tx, tn, lgth_n)) ) { + shift = 1; + if ( lgth_n == 1 ) { + if ( *tx < *tn ) { + tMSx = (DIGIT) (((*tx) << 8) | *(tx+1)); + tMSn = *tn; + shift = 0; + } + else { + tMSx = *tx; + tMSn = *tn; + } + } + else if ( lgth_n > 1 ) { + tMSx = (DIGIT) (((*tx) << 8) | *(tx+1)); + tMSn = (DIGIT) (((*tn) << 8) | *(tn+1)); + if ( (tMSx < tMSn) || ((tMSx == tMSn) && less(tx, tn, lgth_n)) ) { + tMSx = (tMSx << 8) | *(tx+2); + shift = 0; + } + } + else { + tMSx = (DIGIT) (((*tx) << 8) | *(tx+1)); + tMSn = *tn; + shift = 0; + } + + mult = (DIGIT) (tMSx / tMSn); + if ( mult > 0xff ) + mult = 0xff; + bmult[0] = (BYTE)(mult & 0xff); + + ts = rem; + do { + memset(ts, 0x00, lgth_x+1); + Mult(ts, tn, lgth_n, bmult, 1); + + underflow = 0; + if ( shift ) { + if ( ts[0] != 0 ) + underflow = 1; + else { + for ( i=0; i= 0) ) { + accum = (DIGIT)(accum + A[tL]); + A[tL--] = (BYTE)(accum & 0xff); + accum = (DIGIT)(accum >> 8); + } + + return accum; +} + + +/* + * add() + * + * A = A + B + * + * LB must be <= LA + * + */ +BYTE add(BYTE *A, int LA, BYTE *B, int LB) +{ + int i, indexA, indexB; + DIGIT accum; + + indexA = LA - 1; /* LSD of result */ + indexB = LB - 1; /* LSD of B */ + + accum = 0; + for ( i = 0; i < LB; i++ ) { + accum = (DIGIT)(accum + A[indexA]); + accum = (DIGIT)(accum + B[indexB--]); + A[indexA--] = (BYTE)(accum & 0xff); + accum = (DIGIT)(accum >> 8); + } + + if ( LA > LB ) + while ( accum && (indexA >= 0) ) { + accum = (DIGIT)(accum + A[indexA]); + A[indexA--] = (BYTE)(accum & 0xff); + accum = (DIGIT)(accum >> 8); + } + + return (BYTE)accum; +} + + +void prettyprintBstr(char *S, BYTE *A, int L) +{ + int i, extra, ctrb, ctrl; + + if ( L == 0 ) + printf("%s ", S); + else + printf("%s\n\t", S); + extra = L % 24; + if ( extra ) { + ctrb = 0; + for ( i=0; i<24-extra; i++ ) { + printf(" "); + if ( ++ctrb == 4) { + printf(" "); + ctrb = 0; + } + } + + for ( i=0; i> 16 ); + buffer[ count ] = ( ( value & 0xFF00FF00L ) >> 8 ) | ( ( value & 0x00FF00FFL ) << 8 ); + } +} + +void +ahtopb (char *ascii_hex, BYTE *p_binary, int bin_len) +{ + BYTE nibble; + int i; + + for ( i=0; i 'F' ) + nibble -= 0x20; + if ( nibble > '9' ) + nibble -= 7; + nibble -= '0'; + p_binary[i] = (BYTE)(nibble << 4); + + nibble = ascii_hex[i * 2 + 1]; + if ( nibble > 'F' ) + nibble -= 0x20; + if ( nibble > '9' ) + nibble -= 7; + nibble -= '0'; + p_binary[i] = (BYTE)(p_binary[i] + nibble); + } +}