Calculate the password requested by ethernet gateways from the Legrand / Bticino MyHome OpenWebNet home automation system when the user's ip address is not in the gateway's whitelist

Note: Factory default password is '12345'. Changing it is highly recommended !

conversation goes as follows

← *#*1##
→ *99*0##
← *#603356072##
at which point a password should be sent back, calculated from the "password open" that is set in the gateway, and the nonce that was just sent

→ *#25280520##
← *#*1##
with javascript_semantics 
function ownCalcPass(atom pwd, string nonce)
    bool start = true
    atom num1 = 0,
         num2 = 0
    for i=1 to length(nonce) do
        integer c = nonce[i]
        if c!='0' and start then
            num2 = pwd
            start = false
        end if
        switch c do
            case '1':   num1 = shift_bits(num2,7)
                        num2 = shift_bits(num2,-25)
            case '2':   num1 = shift_bits(num2,4)
                        num2 = shift_bits(num2,-28)
            case '3':   num1 = shift_bits(num2,3)
                        num2 = shift_bits(num2,-29)
            case '4':   num1 = shift_bits(num2,-1)
                        num2 = shift_bits(num2,31)
            case '5':   num1 = shift_bits(num2,-5)
                        num2 = shift_bits(num2,27)
            case '6':   num1 = shift_bits(num2,-12)
                        num2 = shift_bits(num2,20)
            case '7':   num1 = or_bits(and_bits(num2,0x0000FF00),
                               or_bits(shift_bits(and_bits(num2,0x000000FF),-24),
                                       shift_bits(and_bits(num2,0x00FF0000),16)))
                        num2 = shift_bits(and_bits(num2,0xFF000000),8)
            case '8':   num1 = or_bits(shift_bits(and_bits(num2,0x0000FFFF),-16),
                                       shift_bits(num2,24))
                        num2 = shift_bits(and_bits(num2,0x00FF0000),8)
            case '9':   num1 = not_bits(num2)
            default:    num1 = num2
        end switch
        if c!='0' and c!='9' then
            num1 = or_bits(num1,num2)
        end if
        num2 = num1
    end for
    if num1<0 then num1 += #1_0000_0000 end if
    return num1
end function
 
procedure testPasswordCalc(atom pwd, string nonce, atom expected)
    atom res := ownCalcPass(pwd, nonce)
    string pf = iff(res=expected?"PASS":"FAIL")
    printf(1,"%s  %d  %s  %-10d  %-10d\n", {pf, pwd, nonce, res, expected})
end procedure
 
testPasswordCalc(12345, "603356072", 25280520)
testPasswordCalc(12345, "410501656", 119537670)
testPasswordCalc(12345, "630292165", 4269684735)
testPasswordCalc(12345, "523781130", 537331200)
