Ejemplo n.º 1
0
        /// <summary>
        /// Generates a seed, in accordance with RFC 7292, §B.2
        /// </summary>
        /// <param name="H">Hash function</param>
        /// <param name="r">Iteration count</param>
        /// <param name="P">Formatted password.</param>
        /// <param name="S">Salt.</param>
        /// <param name="n">Number of pseudo-random bits to generate.</param>
        /// <param name="ID">Purpose of key:
        ///
        /// If ID=1, then the pseudorandom bits being produced are to be used
        /// as key material for performing encryption or decryption.
        ///
        /// 2.  If ID=2, then the pseudorandom bits being produced are to be used
        /// as an IV (Initial Value) for encryption or decryption.
        ///
        /// 3.  If ID=3, then the pseudorandom bits being produced are to be used
        /// as an integrity key for MACing.
        /// </param>
        internal static byte[] PRF(HashFunction H, int r, byte[] P, byte[] S, int n, byte ID)
        {
            int u, v;

            if ((n & 7) != 0)
            {
                throw new ArgumentException("Must be a factor of 8.", nameof(n));
            }

            switch (H)
            {
            case HashFunction.MD5:
                u = 128;
                v = 512;
                break;

            case HashFunction.SHA1:
                u = 160;
                v = 512;
                break;

            case HashFunction.SHA256:
                u = 256;
                v = 512;
                break;

            case HashFunction.SHA384:
                u = 384;
                v = 1024;
                break;

            case HashFunction.SHA512:
                u = 512;
                v = 1024;
                break;

            default:
                throw new ArgumentException("Hash function not supported.", nameof(H));
            }

            int v8 = v / 8;
            int u8 = u / 8;

            byte[] D = new byte[v8];
            int    i, j, c;

            for (i = 0; i < v8; i++)
            {
                D[i] = ID;
            }

            S = Extend(S, v);
            P = Extend(P, v);

            byte[] I  = Primitives.CONCAT(S, P);
            int    i8 = I.Length;

            c = (n + u - 1) / u;

            byte[][] As = new byte[c][];

            for (i = 0; i < c; i++)
            {
                As[i] = Primitives.CONCAT(D, I);

                for (j = 0; j < r; j++)
                {
                    As[i] = Hashes.ComputeHash(H, As[i]);
                }

                byte[] B = Extend(As[i], v);

                for (j = 0; j < i8; j += v8)
                {
                    AddTo(I, j, B, true);
                }
            }

            byte[] A = Primitives.CONCAT(As);

            if (A.Length != n)
            {
                Array.Resize <byte>(ref A, n);
            }

            return(A);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Formats a password, in accordance with RFC 7292, §B.1.
 /// </summary>
 /// <param name="Password">Password</param>
 /// <returns>Formatted password</returns>
 internal static byte[] FormatPassword(string Password)
 {
     return(Primitives.CONCAT(Encoding.BigEndianUnicode.GetBytes(Password), new byte[] { 0, 0 }));
 }