PDA

View Full Version : Challenge & Response



retepsnikrep
- 25th December 2020, 09:58
Seasons Greetings to all.

If you get bored with relatives and feasting today perhaps you might cast your eye over the below.

I have an electronic gadget that has a challenge response going on.

It sends me two bytes.
I have to respond with two bytes somehow derived from the ones it sent me.

I have a few examples below of correct challenges and responses.
Any ideas on how it is working and generating the response?

Challenge $E3 $C5
Response $82 $CB

Challenge $79 $71
Response $04 $35

Challenge $84 $15
Response $ED $85

Challenge $9B $B6
Response $6F $C9

Challenge $C7 $B0
Response $1A $DD

Challenge $AB $19
Response $9A $69

Many thanks and best wishes for the new year.

retepsnikrep
- 27th December 2020, 12:18
I found a C++ solution to this calculation but I need to translate it into PbPro.

The actual seed/key is 3 byte not two as I first thought.

Happy to pay for some help to do this as I know nothing about C++ and don't have Visual Studio etc.

Text file attached..

mpgmike
- 27th December 2020, 17:54
It appears to be a random number generator based on the "Seed". At the top is a function for InitializeComponent(); which isn't anywhere in the body of code. I don't understand fully what it's supposed to do, but can give you some translation ideas. Let's break some of it down. All of the "Using"s listed at the top bring in macros and such from external files that are part of VS. Again, without actually looking each of them up, it's hard to tell what they contribute. The rest of the document is a Collection; more specifically it's called "namespace Calculation"; the rules which are probably spelled out in "System.Collections.Generic;".

"int Func3(int paramInt1, int paramInt2, int paramInt3)" is a subroutine. In PBP we'd use "Func3:", but first we'd have to already declare:


paramInt1 VAR SIGNED WORD
paramInt2 VAR SIGNED WORD
paramInt3 VAR SIGNED WORD

Then prior to GOSUB Func3 we have to assign values to them:


paramInt1 = 1234
paramInt2 = -567
paramInt3 = 890

Next:


int Func3(int paramInt1, int paramInt2, int paramInt3)
{
int i = paramInt1 << 8 | paramInt2;
int j;
int k; int m; int n; int i1; switch (paramInt3)
{
case 65:
case 66:

"switch (paramInt3)" would be the same as "SELECT CASE paramInt3:" Also, " int i = paramInt1 << 8 | paramInt2;" is the same as
i.HIGHBYTE = paramInt1
i.LOWBYTE = paramInt2
At the bottom of the switch routine is "return Func2(i, j, k, m, n, i1);" In PBP we would have already placed the resultant values in each of these variables with


case 111:
j = 16360;
k = 6010;
m = 0;
n = 1;
i1 = -2;

"int getKey(int i)" manipulates the input ("i") with masks. I forget the hierarchy as to which gets precedence; ">>" or "&", and without parentheses, I would have to look it up to know for sure which operation is executed first.

I know this isn't everything, but hopefully it will help you to work through much of it. Do what you can then report back where you're having challenges.

retepsnikrep
- 27th December 2020, 21:00
Thanks for the response.

retepsnikrep
- 29th December 2020, 12:10
I've have this so far, but it's not right yet.
Gives same incorrect answer with different seeds.
Any obvious gaffes?

PIC18F2680




'Long Variables for signed Key Calculation

int VAR LONG
key VAR LONG
seed VAR LONG
top_j VAR LONG
top_k VAR LONG
top_l VAR LONG

F3_i VAR LONG
F3_j VAR LONG
F3_k VAR LONG
F3_m VAR LONG
F3_n VAR LONG
F3_i1 VAR LONG

F2_i VAR LONG
F2_j VAR LONG
F2_k VAR LONG
F2_m VAR LONG
F2_n VAR LONG
F2_i1 VAR LONG


'************************************************* ******************************

Start:

Seed.Byte0 = $6B
Seed.Byte1 = $E3
Seed.byte2 = $C5

'Answer should be $82 $CB $6B

lcdout hex2 Seed.byte2," $",hex2 Seed.byte1," $",hex2 seed.byte0

gosub CalcKey

lcdout hex2 key.byte2," $",hex2 key.byte1," $",hex2 key.byte0

'Try Again

Seed.Byte0 = $6B
Seed.Byte1 = $71
Seed.byte2 = $79

'Answer should be $04 $35 $6B

lcdout hex2 Seed.byte2," $",hex2 Seed.byte1," $",hex2 seed.byte0

gosub CalcKey

lcdout hex2 key.byte2," $",hex2 key.byte1," $",hex2 key.byte0

Stop


'************************************************* ******************************


CalcKey:

top_j = seed >> $10
top_j = top_j & $ff
top_k = seed >> 8
top_k = top_k & $ff
top_l = seed & $ff

F3_i = top_j << 8
F3_i = F3_i | top_k

SELECT CASE top_l

case 1
F3_j = 20483;
F3_k = 37495;
F3_m = 19380;
F3_n = 2;
F3_i1 = -1;

case 2
F3_j = 48737;
F3_k = 29064;
F3_m = 0;
F3_n = -2;
F3_i1 = 1;

case 3
F3_j = 38851;
F3_k = 17007;
F3_m = 57213;
F3_n = 2;
F3_i1 = -1;

case 4
F3_j = 38191;
F3_k = 42963;
F3_m = 45416;
F3_n = -3;
F3_i1 = 1;

case 5
F3_j = 31893;
F3_k = 60216;
F3_m = 0;
F3_n = 1;
F3_i1 = -2;

case 6
F3_j = 26458;
F3_k = 15181;
F3_m = 11362;
F3_n = -3;
F3_i1 = 1;

case 7
F3_j = 10773;
F3_k = 36766;
F3_m = 28592;
F3_n = 2;
F3_i1 = -1;

case 8
F3_j = 13376;
F3_k = 4967;
F3_m = 62941;
F3_n = 2;
F3_i1 = -3;

case 9
F3_j = 2197;
F3_k = 24862;
F3_m = 65475;
F3_n = -2;
F3_i1 = 3;

case 10
F3_j = 31199;
F3_k = 59852;
F3_m = 0;
F3_n = 1;
F3_i1 = -3;

case 11
F3_j = 45383;
F3_k = 9690;
F3_m = 0;
F3_n = 3;
F3_i1 = -2;

case 12
F3_j = 34146;
F3_k = 59163;
F3_m = 0;
F3_n = -1;
F3_i1 = 2;

case 13
F3_j = 62765;
F3_k = 33340;
F3_m = 5749;
F3_n = 3;
F3_i1 = -1;

case 14
F3_j = 45458;
F3_k = 44092;
F3_m = 0;
F3_n = -1;
F3_i1 = 3;

case 15
F3_j = 37357;
F3_k = 39321;
F3_m = 0;
F3_n = -2;
F3_i1 = 1;

case 16
F3_j = 8713;
F3_k = 454;
F3_m = 23575;
F3_n = 1;
F3_i1 = -2;

case 17
F3_j = 9988;
F3_k = 56677;
F3_m = 29637;
F3_n = -3;
F3_i1 = 1;

case 18
F3_j = 57758;
F3_k = 34088;
F3_m = 11152;
F3_n = 1;
F3_i1 = -3;

case 19
F3_j = 33800;
F3_k = 14769;
F3_m = 0;
F3_n = -2;
F3_i1 = 1;

case 20
F3_j = 4069;
F3_k = 4013;
F3_m = 24616;
F3_n = -1;
F3_i1 = 2;

case 21
F3_j = 17056;
F3_k = 12969;
F3_m = 11927;
F3_n = 3;
F3_i1 = -1;

case 22
F3_j = 31370;
F3_k = 60592;
F3_m = 0;
F3_n = -1;
F3_i1 = 3;

case 23
F3_j = 24184;
F3_k = 58486;
F3_m = 0;
F3_n = -1;
F3_i1 = 3;

case 24
F3_j = 56838;
F3_k = 5012;
F3_m = 35563;
F3_n = 2;
F3_i1 = -3;

case 25
F3_j = 49473;
F3_k = 5452;
F3_m = 33161;
F3_n = 3;
F3_i1 = -2;

case 26
F3_j = 64459;
F3_k = 44104;
F3_m = 0;
F3_n = 2;
F3_i1 = -1;

case 27
F3_j = 6123;
F3_k = 30247;
F3_m = 0;
F3_n = -1;
F3_i1 = 3;

case 28
F3_j = 62885;
F3_k = 57915;
F3_m = 28211;
F3_n = -2;
F3_i1 = 3;

case 29
F3_j = 56790;
F3_k = 34537;
F3_m = 0;
F3_n = -3;
F3_i1 = 1;

case 30
F3_j = 34655;
F3_k = 4726;
F3_m = 0;
F3_n = 3;
F3_i1 = -1;

case 31
F3_j = 45667;
F3_k = 2227;
F3_m = 0;
F3_n = -3;
F3_i1 = 1;

case 32
F3_j = 64118;
F3_k = 22124;
F3_m = 0;
F3_n = 1;
F3_i1 = -3;

case 33
F3_j = 20483;
F3_k = 37495;
F3_m = 19380;
F3_n = 2;
F3_i1 = -1;

case 34
F3_j = 18934;
F3_k = 33007;
F3_m = 45671;
F3_n = -1;
F3_i1 = 2;

case 35
F3_j = 53898;
F3_k = 43937;
F3_m = 8992;
F3_n = 3;
F3_i1 = -2;

case 36
F3_j = 26472;
F3_k = 30849;
F3_m = 15462;
F3_n = -2;
F3_i1 = 3;

case 37
F3_j = 18864;
F3_k = 16973;
F3_m = 0;
F3_n = -2;
F3_i1 = 2;

case 38
F3_j = 10153;
F3_k = 24758;
F3_m = 0;
F3_n = -2;
F3_i1 = 2;

case 39
F3_j = 28031;
F3_k = 31768;
F3_m = 65233;
F3_n = 3;
F3_i1 = -1;

case 40
F3_j = 9577;
F3_k = 32816;
F3_m = 0;
F3_n = -3;
F3_i1 = 3;

case 41
F3_j = 33294;
F3_k = 41833;
F3_m = 63823;
F3_n = 2;
F3_i1 = -2;

case 42
F3_j = 46258;
F3_k = 33763;
F3_m = 47869;
F3_n = 2;
F3_i1 = -2;

case 43
F3_j = 303;
F3_k = 15452;
F3_m = 49261;
F3_n = -3;
F3_i1 = 1;

case 44
F3_j = 14480;
F3_k = 52729;
F3_m = 0;
F3_n = 2;
F3_i1 = -2;

case 45
F3_j = 26181;
F3_k = 30558;
F3_m = 11669;
F3_n = -1;
F3_i1 = 1;

case 46
F3_j = 57729;
F3_k = 31412;
F3_m = 0;
F3_n = 3;
F3_i1 = -3;

case 47
F3_j = 38273;
F3_k = 42785;
F3_m = 57170;
F3_n = 2;
F3_i1 = -3;

case 48
F3_j = 65304;
F3_k = 24702;
F3_m = 12077;
F3_n = 2;
F3_i1 = -1;

case 49
F3_j = 25997;
F3_k = 16247;
F3_m = 11573;
F3_n = -2;
F3_i1 = 3;

case 50
F3_j = 47122;
F3_k = 17812;
F3_m = 0;
F3_n = 3;
F3_i1 = -1;

case 51
F3_j = 62790;
F3_k = 184;
F3_m = 43056;
F3_n = -2;
F3_i1 = 1;

case 52
F3_j = 27811;
F3_k = 36172;
F3_m = 10312;
F3_n = -1;
F3_i1 = 2;

case 53
F3_j = 33495;
F3_k = 4706;
F3_m = 23772;
F3_n = 1;
F3_i1 = -3;

case 54
F3_j = 11806;
F3_k = 6016;
F3_m = 0;
F3_n = 2;
F3_i1 = -1;

case 55
F3_j = 23022;
F3_k = 61027;
F3_m = 0;
F3_n = 1;
F3_i1 = -3;

case 56
F3_j = 14502;
F3_k = 52925;
F3_m = 45502;
F3_n = -3;
F3_i1 = 2;

case 57
F3_j = 19654;
F3_k = 47349;
F3_m = 29195;
F3_n = 3;
F3_i1 = -2;

case 58
F3_j = 4043;
F3_k = 49055;
F3_m = 0;
F3_n = 1;
F3_i1 = -2;

case 59
F3_j = 238;
F3_k = 61025;
F3_m = 46052;
F3_n = -2;
F3_i1 = 3;

case 60
F3_j = 26525;
F3_k = 16314;
F3_m = 0;
F3_n = 2;
F3_i1 = -1;

case 61
F3_j = 27577;
F3_k = 18161;
F3_m = 3841;
F3_n = -3;
F3_i1 = 1;

case 62
F3_j = 11820;
F3_k = 48834;
F3_m = 24936;
F3_n = -3;
F3_i1 = 2;

case 63
F3_j = 926;
F3_k = 34536;
F3_m = 62639;
F3_n = -1;
F3_i1 = 1;

case 64
F3_j = 34242;
F3_k = 21476;
F3_m = 0;
F3_n = 2;
F3_i1 = -3;

case 97
F3_j = 11937;
F3_k = 0;
F3_m = 54278;
F3_n = 3;
F3_i1 = -1;

case 98
F3_j = 11129;
F3_k = 0;
F3_m = 41060;
F3_n = 1;
F3_i1 = -3;

case 99
F3_j = 16232;
F3_k = 0;
F3_m = 37025;
F3_n = 3;
F3_i1 = -2;

case 100
F3_j = 62287;
F3_k = 21359;
F3_m = 0;
F3_n = -1;
F3_i1 = 1;

case 101
F3_j = 19345;
F3_k = 63583;
F3_m = 20313;
F3_n = -2;
F3_i1 = 2;

case 102
F3_j = 50636;
F3_k = 34432;
F3_m = 58878;
F3_n = -2;
F3_i1 = 2;

case 103
F3_j = 8636;
F3_k = 42038;
F3_m = 0;
F3_n = 3;
F3_i1 = -1;

case 104
F3_j = 49296;
F3_k = 0;
F3_m = 23727;
F3_n = -2;
F3_i1 = 2;

case 105
F3_j = 62603;
F3_k = 0;
F3_m = 7632;
F3_n = 2;
F3_i1 = -1;

case 106
F3_j = 54947;
F3_k = 13952;
F3_m = 0;
F3_n = -3;
F3_i1 = 2;

case 107
F3_j = 46336;
F3_k = 0;
F3_m = 32973;
F3_n = -1;
F3_i1 = 3;

case 108
F3_j = 31276;
F3_k = 0;
F3_m = 41988;
F3_n = -2;
F3_i1 = 2;

case 109
F3_j = 24959;
F3_k = 31354;
F3_m = 55064;
F3_n = 1;
F3_i1 = -1;

case 110
F3_j = 39963;
F3_k = 29660;
F3_m = 0;
F3_n = 2;
F3_i1 = -3;

case 111
F3_j = 16360;
F3_k = 6010;
F3_m = 0;
F3_n = 1;
F3_i1 = -2;

case 112
F3_j = 50050;
F3_k = 36355;
F3_m = 34628;
F3_n = 3;
F3_i1 = -3;

end select



F2_i = F3_i + F3_j
F2_i = F2_i & $FFFF

IF (F3_n > 0) then
F2_j = $FFFF & (F3_i << F3_n | F3_i >> 16 - F3_n)
ELSE
F2_j = $FFFF & (F3_i >> -F3_n | F3_i << 16 + F3_n)

endif

F2_k = F3_i + F3_k
F2_k = F2_k & $FFFF

IF (F3_i1 > 0) then
F2_m = $FFFF & (F2_k << F3_i1 | F2_k >> 16 - F3_i1);
ELSE
F2_m = $FFFF & (F2_k >> -F3_i1 | F2_k << 16 + F3_i1);

endif

F2_n = F2_j * F2_m

F2_i1 = F2_n + F3_m

key = F2_i1 & $FFFF

key = key << 8
key = key + top_l

return

richard
- 29th December 2020, 23:22
not sure that pbp correctly left or right shifts negative numbers , see henriks treatise on the bme280 for correct method to deal with signed ints

http://www.picbasic.co.uk/forum/showthread.php?t=24134


ps , i did notice that some cases may lead to doing a left or right shift of a negative number of bits, eg [var << -3 ] i'm not sure how gcc would resolve that

retepsnikrep
- 30th December 2020, 05:54
I agree that does look like a problem, thanks for the heads up.

retepsnikrep
- 31st December 2020, 07:07
I think I have this cracked now thanks to generous help on this and other forums.

In the end I did not need the large lookup table as it was always using the same table entry.

So my code ended up being tiny and did not require LONGS etc. .



W0 VAR WORD
W1 VAR WORD
W2 VAR WORD

SEED1 VAR BYTE
SEED2 VAR BYTE
SEED3 VAR BYTE

'KEY1 = 46336;
'KEY3 = 32973;
'SHIFT1 = 1; (-1)
'SHIFT2 = 3;

' Calculates and stores the results of two cryptographic operations
' on the first two seed bytes in W1 and W2
'
' The operation being carried out consists of adding two 16-bit values
' and performing a bitwise rotation on the result.
'
' The two results are calculated from adding the 2 seed bytes to both
' KEY1 and KEY2, with a rotation of SHIFT1 and SHIFT2 respectively.

SEED1 = $C7
SEED2 = $B0
SEED3 = $6B

'Answer should be $82 $CB $6B


W1.BYTE0 = SEED2
W1.BYTE1 = SEED1

W0 = W1 + 46336 'Key1

' Does a cyclic bitwise rotation of B0-bits on W0

W0 = (W0 >> 1 | W0 << ($10 - 1)) 'Note this is a negative shift

W2 = W0
W0 = W1

' Does a cyclic bitwise rotation of B0-bits on W0

W0 = (W0 << 3 | W0 >> ($10 - 3)) 'Note this is a positive shift

W1 = W0

' Multiplies the contents of W1 and W2 and adds KEY3, stores in W0
' Impicitly calculates 16-bit overflow only

W0 = W1 * W2
W0 = W0 + 32973 'KEY3

SEED1 = W0.BYTE1
SEED2 = W0.BYTE0

retepsnikrep
- 31st December 2020, 11:30
Are there any optimisations I have missed in the final code in my prev post?