mirror of
https://github.com/MobileTooling/AndroidDebugBridge.git
synced 2026-07-27 12:48:37 -07:00
171 lines
5.4 KiB
C#
171 lines
5.4 KiB
C#
/*
|
|
* MIT License
|
|
*
|
|
* Copyright (c) 2024 The DuoWOA authors
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*/
|
|
using System.IO;
|
|
using System.Numerics;
|
|
using System.Security.Cryptography;
|
|
|
|
namespace AndroidDebugBridge
|
|
{
|
|
internal class AndroidDebugBridgeCryptography
|
|
{
|
|
private static BigInteger EGCD(BigInteger left,
|
|
BigInteger right,
|
|
out BigInteger leftFactor,
|
|
out BigInteger rightFactor)
|
|
{
|
|
leftFactor = 0;
|
|
rightFactor = 1;
|
|
BigInteger u = 1;
|
|
BigInteger v = 0;
|
|
BigInteger gcd = 0;
|
|
|
|
while (left != 0)
|
|
{
|
|
BigInteger q = right / left;
|
|
BigInteger r = right % left;
|
|
|
|
BigInteger m = leftFactor - (u * q);
|
|
BigInteger n = rightFactor - (v * q);
|
|
|
|
right = left;
|
|
left = r;
|
|
leftFactor = u;
|
|
rightFactor = v;
|
|
u = m;
|
|
v = n;
|
|
|
|
gcd = right;
|
|
}
|
|
|
|
return gcd;
|
|
}
|
|
|
|
private static BigInteger ModInverse(BigInteger value, BigInteger modulo)
|
|
{
|
|
BigInteger egcd = EGCD(value, modulo, out BigInteger x, out _);
|
|
if (1 != egcd)
|
|
{
|
|
//throw new ArgumentException("Invalid modulo", nameof(modulo));
|
|
}
|
|
|
|
if (x < 0)
|
|
{
|
|
x += modulo;
|
|
}
|
|
|
|
return x % modulo;
|
|
}
|
|
|
|
internal static byte[] ADBRSAToBuffer(uint n0inv, uint[] n, uint[] rr, int exponent)
|
|
{
|
|
int len = n.Length;
|
|
|
|
byte[] buffer = new byte[12 + (8 * len)];
|
|
using MemoryStream memoryStream = new(buffer);
|
|
using BinaryWriter binaryWriter = new(memoryStream);
|
|
|
|
binaryWriter.Write(len);
|
|
binaryWriter.Write(n0inv);
|
|
|
|
foreach (uint nElement in n)
|
|
{
|
|
binaryWriter.Write(nElement);
|
|
}
|
|
|
|
foreach (uint rrElement in rr)
|
|
{
|
|
binaryWriter.Write(rrElement);
|
|
}
|
|
|
|
binaryWriter.Write(exponent);
|
|
|
|
return buffer;
|
|
}
|
|
|
|
internal static (uint n0inv, uint[] n, uint[] rr, int exponent) BufferToADBRSA(byte[] buffer)
|
|
{
|
|
using MemoryStream memoryStream = new(buffer);
|
|
using BinaryReader binaryReader = new(memoryStream);
|
|
|
|
int len = binaryReader.ReadInt32();
|
|
|
|
if (buffer.Length != 12 + (8 * len))
|
|
{
|
|
throw new InvalidDataException("Invalid ADB RSA Buffer!");
|
|
}
|
|
|
|
uint n0inv = binaryReader.ReadUInt32();
|
|
|
|
uint[] n = new uint[len];
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
n[i] = binaryReader.ReadUInt32();
|
|
}
|
|
|
|
uint[] rr = new uint[len];
|
|
for (int i = 0; i < len; i++)
|
|
{
|
|
rr[i] = binaryReader.ReadUInt32();
|
|
}
|
|
|
|
int exponent = binaryReader.ReadInt32();
|
|
|
|
return (n0inv, n, rr, exponent);
|
|
}
|
|
|
|
internal static (uint n0inv, uint[] n, uint[] rr, int exponent) ConvertRSAToADBRSA(RSAParameters publicKeyParameters)
|
|
{
|
|
byte[] modulus = publicKeyParameters.Modulus!;
|
|
byte[] exponent = publicKeyParameters.Exponent!;
|
|
|
|
const int keyLengthInDWORDs = 64; // 2048 bits / 256 bytes / 64 DWORDs
|
|
|
|
int e = (int)new BigInteger(exponent);
|
|
|
|
BigInteger r32 = new BigInteger(1) << 32;
|
|
|
|
BigInteger n = new(modulus);
|
|
BigInteger r = new BigInteger(1) << (keyLengthInDWORDs * 32);
|
|
BigInteger rr = BigInteger.ModPow(r, new BigInteger(2), n);
|
|
|
|
BigInteger remainder = BigInteger.Remainder(n, r32);
|
|
BigInteger tn0inv = ModInverse(remainder, r32);
|
|
uint n0inv = (uint)(BigInteger.Negate(tn0inv) & uint.MaxValue);
|
|
|
|
uint[] nTable = new uint[keyLengthInDWORDs];
|
|
uint[] rrTable = new uint[keyLengthInDWORDs];
|
|
|
|
for (int i = 0; i < keyLengthInDWORDs; i++)
|
|
{
|
|
rr = BigInteger.DivRem(rr, r32, out remainder);
|
|
rrTable[i] = (uint)remainder;
|
|
|
|
n = BigInteger.DivRem(n, r32, out remainder);
|
|
nTable[i] = (uint)(remainder & uint.MaxValue);
|
|
}
|
|
|
|
return (n0inv, nTable, rrTable, e);
|
|
}
|
|
}
|
|
} |