コード例 #1
0
ファイル: CryptImpl.cs プロジェクト: morkvamax/PasswordSharp
        private static void __sha512_finish_ctx(sha512_ctx ctx, ArrayPointer <byte> buffer)
        {
            byte[] temp = new byte[ctx.stream.Length];
            ctx.stream.Seek(0, SeekOrigin.Begin);
            ctx.stream.Read(temp, 0, temp.Length);

            temp = SHA512.Create().ComputeHash(temp);

            for (int i = 0; i < temp.Length; i++, buffer++)
            {
                buffer.Value = temp[i];
            }
        }
コード例 #2
0
ファイル: CryptImpl.cs プロジェクト: morkvamax/PasswordSharp
 private static void __sha512_init_ctx(sha512_ctx ctx)
 {
     ctx.stream = new MemoryStream();
 }
コード例 #3
0
ファイル: CryptImpl.cs プロジェクト: morkvamax/PasswordSharp
 private static void __sha512_process_bytes(ArrayPointer <byte> buffer, int count, sha512_ctx ctx)
 {
     ctx.stream.Write(buffer.SourceArray, buffer.Address, count);
 }
コード例 #4
0
ファイル: CryptImpl.cs プロジェクト: morkvamax/PasswordSharp
        private static ArrayPointer <byte> __sha512_crypt_r(ArrayPointer <byte> key, ArrayPointer <byte> salt, ArrayPointer <byte> buffer, int buflen)
        {
            ArrayPointer <byte> alt_result  = new ArrayPointer <byte>(new byte[64]);
            ArrayPointer <byte> temp_result = new ArrayPointer <byte>(new byte[64]);
            sha512_ctx          ctx         = new sha512_ctx();
            sha512_ctx          alt_ctx     = new sha512_ctx();
            int salt_len;
            int key_len;
            int cnt;
            ArrayPointer <byte> cp;
            ArrayPointer <byte> copied_key;
            ArrayPointer <byte> copied_salt;
            ArrayPointer <byte> p_bytes;
            ArrayPointer <byte> s_bytes;
            /* Default number of rounds.  */
            int  rounds        = RoundsDefault;
            bool rounds_custom = false;

            /* Find beginning of salt string.  The prefix should normally always
             * be present.  Just in case it is not.  */
            if (strncmp(sha512_salt_prefix, salt, strlen(sha512_salt_prefix)) == 0)
            {
                /* Skip salt prefix.  */
                salt += strlen(sha512_salt_prefix);
            }

            if (strncmp(salt, sha512_rounds_prefix, strlen(sha512_rounds_prefix)) == 0)
            {
                ArrayPointer <byte> num = salt + strlen(sha512_rounds_prefix);
                ArrayPointer <byte> endp;
                ulong srounds = strtoul(num, out endp, 10);
                if (endp.Value == (byte)'$')
                {
                    salt          = endp + 1;
                    rounds        = (int)Math.Max(RoundsMin, Math.Min(srounds, RoundsMax));
                    rounds_custom = true;
                }
            }

            salt_len = Math.Min(strcspn(salt, dollar_sign), SaltLenMax);
            key_len  = strlen(key);

            byte[] temp = new byte[key.SourceArray.Length];
            key.SourceArray.CopyTo(temp, 0);
            copied_key         = new ArrayPointer <byte>(temp);
            copied_key.Address = key.Address;
            key = copied_key;

            temp = new byte[salt.SourceArray.Length];
            salt.SourceArray.CopyTo(temp, 0);
            copied_salt         = new ArrayPointer <byte>(temp);
            copied_salt.Address = salt.Address;
            salt = copied_salt;

            /* Prepare for the real work.  */
            __sha512_init_ctx(ctx);

            /* Add the key string.  */
            __sha512_process_bytes(key, key_len, ctx);

            /* The last part is the salt string.  This must be at most 16
             * characters and it ends at the first `$' character.  */
            __sha512_process_bytes(salt, salt_len, ctx);

            /* Compute alternate SHA256 sum with input KEY, SALT, and KEY.  The
             * final result will be added to the first context.  */
            __sha512_init_ctx(alt_ctx);

            /* Add key.  */
            __sha512_process_bytes(key, key_len, alt_ctx);

            /* Add salt.  */
            __sha512_process_bytes(salt, salt_len, alt_ctx);

            /* Add key again.  */
            __sha512_process_bytes(key, key_len, alt_ctx);

            /* Now get result of this (32 bytes) and add it to the other
             * context.  */
            __sha512_finish_ctx(alt_ctx, alt_result);

            /* Add for any character in the key one byte of the alternate sum.  */
            for (cnt = key_len; cnt > 64; cnt -= 64)
            {
                __sha512_process_bytes(alt_result, 64, ctx);
            }
            __sha512_process_bytes(alt_result, cnt, ctx);

            /* Take the binary representation of the length of the key and for every
             * 1 add the alternate sum, for every 0 the key.  */
            for (cnt = key_len; cnt > 0; cnt >>= 1)
            {
                if ((cnt & 1) != 0)
                {
                    __sha512_process_bytes(alt_result, 64, ctx);
                }
                else
                {
                    __sha512_process_bytes(key, key_len, ctx);
                }
            }

            /* Create intermediate result.  */
            __sha512_finish_ctx(ctx, alt_result);

            /* Start computation of P byte sequence.  */
            __sha512_init_ctx(alt_ctx);

            /* For every character in the password add the entire password.  */
            for (cnt = 0; cnt < key_len; ++cnt)
            {
                __sha512_process_bytes(key, key_len, alt_ctx);
            }

            /* Finish the digest.  */
            __sha512_finish_ctx(alt_ctx, temp_result);

            /* Create byte sequence P.  */
            cp = p_bytes = new ArrayPointer <byte>(new byte[key_len]);
            for (cnt = key_len; cnt >= 64; cnt -= 64)
            {
                cp = mempcpy(cp, temp_result, 64);
            }
            memcpy(cp, temp_result, cnt);

            /* Start computation of S byte sequence.  */
            __sha512_init_ctx(alt_ctx);

            /* For every character in the password add the entire password.  */
            for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
            {
                __sha512_process_bytes(salt, salt_len, alt_ctx);
            }

            /* Finish the digest.  */
            __sha512_finish_ctx(alt_ctx, temp_result);

            /* Create byte sequence S.  */
            cp = s_bytes = new ArrayPointer <byte>(new byte[salt_len]);
            for (cnt = salt_len; cnt >= 64; cnt -= 64)
            {
                cp = mempcpy(cp, temp_result, 64);
            }
            memcpy(cp, temp_result, cnt);

            /* Repeatedly run the collected hash value through SHA512 to burn
             * CPU cycles.  */
            for (cnt = 0; cnt < rounds; ++cnt)
            {
                /* New context.  */
                __sha512_init_ctx(ctx);

                /* Add key or last result.  */
                if ((cnt & 1) != 0)
                {
                    __sha512_process_bytes(p_bytes, key_len, ctx);
                }
                else
                {
                    __sha512_process_bytes(alt_result, 64, ctx);
                }

                /* Add salt for numbers not divisible by 3.  */
                if (cnt % 3 != 0)
                {
                    __sha512_process_bytes(s_bytes, salt_len, ctx);
                }

                /* Add key for numbers not divisible by 7.  */
                if (cnt % 7 != 0)
                {
                    __sha512_process_bytes(p_bytes, key_len, ctx);
                }

                /* Add key or last result.  */
                if ((cnt & 1) != 0)
                {
                    __sha512_process_bytes(alt_result, 64, ctx);
                }
                else
                {
                    __sha512_process_bytes(p_bytes, key_len, ctx);
                }

                /* Create intermediate result.  */
                __sha512_finish_ctx(ctx, alt_result);
            }

            /* Now we can construct the result string.  It consists of three
             * parts.  */
            cp      = __stpncpy(buffer, sha512_salt_prefix, Math.Max(0, buflen));
            buflen -= strlen(sha512_salt_prefix);

            if (rounds_custom)
            {
                cp      = __stpncpy(cp, sha512_rounds_prefix, Math.Max(0, buflen));
                buflen -= strlen(sha512_rounds_prefix);

                char[] temp1 = (rounds.ToString() + "$\0").ToCharArray();
                byte[] temp2 = new byte[temp1.Length];
                for (int i = 0; i < temp1.Length; i++)
                {
                    temp2[i] = (byte)temp1[i];
                }
                ArrayPointer <byte> temp3 = new ArrayPointer <byte>(temp2);

                cp      = __stpncpy(cp, temp3, Math.Max(0, buflen));
                buflen -= strlen(temp3);
            }

            cp      = __stpncpy(cp, salt, Math.Min(Math.Max(0, buflen), salt_len));
            buflen -= Math.Min(Math.Max(0, buflen), salt_len);

            if (buflen > 0)
            {
                cp.Value = (byte)'$';
                cp++;
                buflen--;
            }

            cp = b64_from_24bit(alt_result[0], alt_result[21], alt_result[42], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[22], alt_result[43], alt_result[1], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[44], alt_result[2], alt_result[23], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[3], alt_result[24], alt_result[45], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[25], alt_result[46], alt_result[4], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[47], alt_result[5], alt_result[26], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[6], alt_result[27], alt_result[48], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[28], alt_result[49], alt_result[7], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[50], alt_result[8], alt_result[29], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[9], alt_result[30], alt_result[51], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[31], alt_result[52], alt_result[10], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[53], alt_result[11], alt_result[32], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[12], alt_result[33], alt_result[54], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[34], alt_result[55], alt_result[13], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[56], alt_result[14], alt_result[35], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[15], alt_result[36], alt_result[57], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[37], alt_result[58], alt_result[16], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[59], alt_result[17], alt_result[38], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[18], alt_result[39], alt_result[60], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[40], alt_result[61], alt_result[19], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[62], alt_result[20], alt_result[41], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(0, 0, alt_result[63], 2, cp, buflen, out buflen);

            if (buflen <= 0)
            {
                throw new IndexOutOfRangeException();
            }
            else
            {
                cp.Value = 0;        /* Terminate the string.  */
            }

            /* Clear the buffer for the intermediate result so that people
             * attaching to processes or reading core dumps cannot get any
             * information.  We do it in this way to clear correct_words[]
             * inside the SHA512 implementation as well.  */
            __sha512_init_ctx(ctx);
            __sha512_finish_ctx(ctx, alt_result);

            return(buffer);
        }
コード例 #5
0
ファイル: CryptImpl.cs プロジェクト: ahall/PasswordSharp
 private static void __sha512_process_bytes(ArrayPointer<byte> buffer, int count, sha512_ctx ctx)
 {
     ctx.stream.Write(buffer.SourceArray, buffer.Address, count);
 }
コード例 #6
0
ファイル: CryptImpl.cs プロジェクト: ahall/PasswordSharp
 private static void __sha512_init_ctx(sha512_ctx ctx)
 {
     ctx.stream = new MemoryStream();
 }
コード例 #7
0
ファイル: CryptImpl.cs プロジェクト: ahall/PasswordSharp
        private static void __sha512_finish_ctx(sha512_ctx ctx, ArrayPointer<byte> buffer)
        {
            byte[] temp = new byte[ctx.stream.Length];
            ctx.stream.Seek(0, SeekOrigin.Begin);
            ctx.stream.Read(temp, 0, temp.Length);

            temp = SHA512.Create().ComputeHash(temp);

            for (int i = 0; i < temp.Length; i++, buffer++)
            {
                buffer.Value = temp[i];
            }
        }
コード例 #8
0
ファイル: CryptImpl.cs プロジェクト: ahall/PasswordSharp
        private static ArrayPointer<byte> __sha512_crypt_r(ArrayPointer<byte> key, ArrayPointer<byte> salt, ArrayPointer<byte> buffer, int buflen)
        {
            ArrayPointer<byte> alt_result = new ArrayPointer<byte>(new byte[64]);
            ArrayPointer<byte> temp_result = new ArrayPointer<byte>(new byte[64]);
            sha512_ctx ctx = new sha512_ctx();
            sha512_ctx alt_ctx = new sha512_ctx();
            int salt_len;
            int key_len;
            int cnt;
            ArrayPointer<byte> cp;
            ArrayPointer<byte> copied_key;
            ArrayPointer<byte> copied_salt;
            ArrayPointer<byte> p_bytes;
            ArrayPointer<byte> s_bytes;
            /* Default number of rounds.  */
            int rounds = RoundsDefault;
            bool rounds_custom = false;

            /* Find beginning of salt string.  The prefix should normally always
               be present.  Just in case it is not.  */
            if (strncmp(sha512_salt_prefix, salt, strlen(sha512_salt_prefix)) == 0)
                /* Skip salt prefix.  */
                salt += strlen(sha512_salt_prefix);

            if (strncmp(salt, sha512_rounds_prefix, strlen(sha512_rounds_prefix)) == 0)
            {
                ArrayPointer<byte> num = salt + strlen(sha512_rounds_prefix);
                ArrayPointer<byte> endp;
                ulong srounds = strtoul(num, out endp, 10);
                if (endp.Value == (byte)'$')
                {
                    salt = endp + 1;
                    rounds = (int)Math.Max(RoundsMin, Math.Min(srounds, RoundsMax));
                    rounds_custom = true;
                }
            }

            salt_len = Math.Min(strcspn(salt, dollar_sign), SaltLenMax);
            key_len = strlen(key);

            byte[] temp = new byte[key.SourceArray.Length];
            key.SourceArray.CopyTo(temp, 0);
            copied_key = new ArrayPointer<byte>(temp);
            copied_key.Address = key.Address;
            key = copied_key;

            temp = new byte[salt.SourceArray.Length];
            salt.SourceArray.CopyTo(temp, 0);
            copied_salt = new ArrayPointer<byte>(temp);
            copied_salt.Address = salt.Address;
            salt = copied_salt;

            /* Prepare for the real work.  */
            __sha512_init_ctx(ctx);

            /* Add the key string.  */
            __sha512_process_bytes(key, key_len, ctx);

            /* The last part is the salt string.  This must be at most 16
               characters and it ends at the first `$' character.  */
            __sha512_process_bytes(salt, salt_len, ctx);

            /* Compute alternate SHA256 sum with input KEY, SALT, and KEY.  The
               final result will be added to the first context.  */
            __sha512_init_ctx(alt_ctx);

            /* Add key.  */
            __sha512_process_bytes(key, key_len, alt_ctx);

            /* Add salt.  */
            __sha512_process_bytes(salt, salt_len, alt_ctx);

            /* Add key again.  */
            __sha512_process_bytes(key, key_len, alt_ctx);

            /* Now get result of this (32 bytes) and add it to the other
               context.  */
            __sha512_finish_ctx(alt_ctx, alt_result);

            /* Add for any character in the key one byte of the alternate sum.  */
            for (cnt = key_len; cnt > 64; cnt -= 64)
                __sha512_process_bytes(alt_result, 64, ctx);
            __sha512_process_bytes(alt_result, cnt, ctx);

            /* Take the binary representation of the length of the key and for every
               1 add the alternate sum, for every 0 the key.  */
            for (cnt = key_len; cnt > 0; cnt >>= 1)
                if ((cnt & 1) != 0)
                    __sha512_process_bytes(alt_result, 64, ctx);
                else
                    __sha512_process_bytes(key, key_len, ctx);

            /* Create intermediate result.  */
            __sha512_finish_ctx(ctx, alt_result);

            /* Start computation of P byte sequence.  */
            __sha512_init_ctx(alt_ctx);

            /* For every character in the password add the entire password.  */
            for (cnt = 0; cnt < key_len; ++cnt)
                __sha512_process_bytes(key, key_len, alt_ctx);

            /* Finish the digest.  */
            __sha512_finish_ctx(alt_ctx, temp_result);

            /* Create byte sequence P.  */
            cp = p_bytes = new ArrayPointer<byte>(new byte[key_len]);
            for (cnt = key_len; cnt >= 64; cnt -= 64)
                cp = mempcpy(cp, temp_result, 64);
            memcpy(cp, temp_result, cnt);

            /* Start computation of S byte sequence.  */
            __sha512_init_ctx(alt_ctx);

            /* For every character in the password add the entire password.  */
            for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
                __sha512_process_bytes(salt, salt_len, alt_ctx);

            /* Finish the digest.  */
            __sha512_finish_ctx(alt_ctx, temp_result);

            /* Create byte sequence S.  */
            cp = s_bytes = new ArrayPointer<byte>(new byte[salt_len]);
            for (cnt = salt_len; cnt >= 64; cnt -= 64)
                cp = mempcpy(cp, temp_result, 64);
            memcpy(cp, temp_result, cnt);

            /* Repeatedly run the collected hash value through SHA512 to burn
               CPU cycles.  */
            for (cnt = 0; cnt < rounds; ++cnt)
            {
                /* New context.  */
                __sha512_init_ctx(ctx);

                /* Add key or last result.  */
                if ((cnt & 1) != 0)
                    __sha512_process_bytes(p_bytes, key_len, ctx);
                else
                    __sha512_process_bytes(alt_result, 64, ctx);

                /* Add salt for numbers not divisible by 3.  */
                if (cnt % 3 != 0)
                    __sha512_process_bytes(s_bytes, salt_len, ctx);

                /* Add key for numbers not divisible by 7.  */
                if (cnt % 7 != 0)
                    __sha512_process_bytes(p_bytes, key_len, ctx);

                /* Add key or last result.  */
                if ((cnt & 1) != 0)
                    __sha512_process_bytes(alt_result, 64, ctx);
                else
                    __sha512_process_bytes(p_bytes, key_len, ctx);

                /* Create intermediate result.  */
                __sha512_finish_ctx(ctx, alt_result);
            }

            /* Now we can construct the result string.  It consists of three
               parts.  */
            cp = __stpncpy(buffer, sha512_salt_prefix, Math.Max(0, buflen));
            buflen -= strlen(sha512_salt_prefix);

            if (rounds_custom)
            {
                cp = __stpncpy(cp, sha512_rounds_prefix, Math.Max(0, buflen));
                buflen -= strlen(sha512_rounds_prefix);

                char[] temp1 = (rounds.ToString() + "$\0").ToCharArray();
                byte[] temp2 = new byte[temp1.Length];
                for(int i = 0; i < temp1.Length; i++) temp2[i] = (byte)temp1[i];
                ArrayPointer<byte> temp3 = new ArrayPointer<byte>(temp2);

                cp = __stpncpy(cp, temp3, Math.Max(0, buflen));
                buflen -= strlen(temp3);
            }

            cp = __stpncpy(cp, salt, Math.Min(Math.Max(0, buflen), salt_len));
            buflen -= Math.Min(Math.Max(0, buflen), salt_len);

            if (buflen > 0)
            {
                cp.Value = (byte)'$';
                cp++;
                buflen--;
            }

            cp = b64_from_24bit(alt_result[0], alt_result[21], alt_result[42], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[22], alt_result[43], alt_result[1], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[44], alt_result[2], alt_result[23], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[3], alt_result[24], alt_result[45], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[25], alt_result[46], alt_result[4], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[47], alt_result[5], alt_result[26], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[6], alt_result[27], alt_result[48], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[28], alt_result[49], alt_result[7], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[50], alt_result[8], alt_result[29], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[9], alt_result[30], alt_result[51], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[31], alt_result[52], alt_result[10], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[53], alt_result[11], alt_result[32], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[12], alt_result[33], alt_result[54], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[34], alt_result[55], alt_result[13], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[56], alt_result[14], alt_result[35], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[15], alt_result[36], alt_result[57], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[37], alt_result[58], alt_result[16], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[59], alt_result[17], alt_result[38], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[18], alt_result[39], alt_result[60], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[40], alt_result[61], alt_result[19], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(alt_result[62], alt_result[20], alt_result[41], 4, cp, buflen, out buflen);
            cp = b64_from_24bit(0, 0, alt_result[63], 2, cp, buflen, out buflen);

            if (buflen <= 0)
            {
                throw new IndexOutOfRangeException();
            }
            else
                cp.Value = 0;        /* Terminate the string.  */

            /* Clear the buffer for the intermediate result so that people
               attaching to processes or reading core dumps cannot get any
               information.  We do it in this way to clear correct_words[]
               inside the SHA512 implementation as well.  */
            __sha512_init_ctx(ctx);
            __sha512_finish_ctx(ctx, alt_result);

            return buffer;
        }