1

I want perform sha1sum file1 and sha1sum file2 and perform bitwise OR operation with them using bash. Output should be printable i.e 53a23bc2e24d039 ... (160 bit)

How can I do this?

I know

echo $(( 0xa | 0xb )) but how to extend to 40 hexadecimal digits?

Thanks

idazuwaika
  • 2,749
  • 7
  • 38
  • 46
  • Why do you want to do that? If we knew you higher level goal, you could get better alternative solutions. Bitwise or on hash outputs smells like something you may not actually want. – laalto Nov 10 '09 at 10:55
  • Basically, with Trusted Platform Module, the PCR register is extended with operation SHA-1 ( old PCR value | inDigest ). Both PCR value and inDigest are 160-bit hash output – idazuwaika Nov 10 '09 at 11:04
  • .. and I want to emulate that behaviour in software – idazuwaika Nov 10 '09 at 11:05
  • @idazuwaika: You're reading the specs wrong. `PCR := SHA1(PCR || data)` reads "concatenate the old value of PCR with the data, hash the concatenated string and store the hash in PCR". It's not `PCR := PCR BITWISE-OR SHA1(data)` nor `PCR := SHA1(PCR BITWISE-OR data)`. – laalto Nov 10 '09 at 11:13
  • I'm using TPM emulator from Mario Strasser, and in his code `tpm_integrity.c` are below. TPM_RESULT TPM_Extend(TPM_PCRINDEX pcrNum, TPM_DIGEST *inDigest, TPM_PCRVALUE *outDigest) { ... /* compute new PCR value as SHA-1(old PCR value || inDigest) */ tpm_sha1_init(&ctx); tpm_sha1_update(&ctx, PCR_VALUE[pcrNum].digest, sizeof(PCR_VALUE[pcrNum].digest)); tpm_sha1_update(&ctx, inDigest->digest, sizeof(inDigest->digest)); tpm_sha1_final(&ctx, PCR_VALUE[pcrNum].digest); /* set output digest */ .. } return TPM_SUCCESS; } Does it follow spec? – idazuwaika Nov 10 '09 at 11:34
  • sorry for the ugly comment but it included /* compute new PCR value as SHA-1(old PCR value || inDigest) */ – idazuwaika Nov 10 '09 at 11:36
  • @idazuwaika: Seems so. It first updates the SHA1 hash state with PCR_VALUE and then with inDigest, and finally stores the hash output to PCR_VALUE. That's equivalent to first concatenating PCR_VALUE and inDigest and then hashing the concatenation. – laalto Nov 10 '09 at 11:43
  • @laalto: thanks. Luckily with answers below, I think I can know the exact behaviour of the TPM emulator. – idazuwaika Nov 10 '09 at 11:46
  • You may also want to use the binary values of SHA1 instead of hex ascii representation given by e.g. sha1sum. – laalto Nov 10 '09 at 11:55

4 Answers4

2

I don't think you really want a 160-bit inclusive OR, but if you do:

split32 () {
  x='s/\(........\)\(........\)\(........\)\(........\)\(........\)/'
  x=$x'0x\1 0x\2 0x\3 0x\4 0x\5/'
  sed -e "$x"
}

(sha1sum $1 | split32; sha1sum $2 | split32) | (
    read a1 b1 c1 d1 e1 x1
    read a2 b2 c2 d2 e2 x2
    a=$(($a1 | $a2))
    b=$(($b1 | $b2))
    c=$(($c1 | $c2))
    d=$(($d1 | $d2))
    e=$(($e1 | $e2))
    printf '  %08x%08x%08x%08x%08x\n' $a1 $b1 $c1 $d1 $e1
    printf '+ %08x%08x%08x%08x%08x\n' $a2 $b2 $c2 $d2 $e2
    printf '= %08x%08x%08x%08x%08x\n' $a  $b  $c  $d  $e 
)
$ bash bigOr.sh fun.tar fun.tgz
  e515d3813b17c36b9a7d29f7aea3e79e264449b7
+ 4f201513105c301944d0a0ba5864d9f07544ca76
= ef35d7933b5ff37bdefda9fffee7fffe7744cbf7
DigitalRoss
  • 143,651
  • 25
  • 248
  • 329
1

Try this:

val1=$(sha1sum file1)
val1=${val1% *}
val2=$(sha1sum file2)
val2=${val2% *}
val3=$(( 0x$val1 | 0x$val2 ))
printf "%x\n" $val3
Dennis Williamson
  • 346,391
  • 90
  • 374
  • 439
0

On my machine bash can handle fixed width integer arithmetic with signed 64 bit values. This means, I can bitwise OR seven bytes at once.

One option would be splitting up your checksum in three pieces an do your OR with these. You can achieve "printable output" by printf "%x" $val later on.

mkluwe
  • 3,823
  • 2
  • 28
  • 45
0

you can use gawk

sha1sum file1 file2 | awk '{sh1=$1;getline;sh2=$1;print or(sh1,sh2);exit}'
ghostdog74
  • 327,991
  • 56
  • 259
  • 343
  • will the output of sha1sum in this case be treated as hexadecimal digit or alphanumeric character? – idazuwaika Nov 10 '09 at 11:47
  • Each of the arguments to `or` need to be converted from hex to decimal like this: `or(strtonum("0x"sh1),strtonum("0x"sh2))` since the output of `sha1sum` is hexadecimal without a prefix. However, these numbers exceed the capacity of `gawk` (which uses float to represent *all* numbers). – Dennis Williamson Nov 10 '09 at 14:56