void rln_crypt(userkey, cardkey) char *userkey; /* User's string (max 20 chars). */ u_int8_t *cardkey; /* 20 bits (3 bytes) */ { /* * From * "RangeLAN2 Security Features": * * The Security ID is a unique, 20 character alphanumeric * string defined and configured by the user. It must be * identically configured in every radio intended to * communicate with others in the same network. Once * configured, the Security ID is reduced to 20 bits by a * proprietary algorithm confidential to Proxim. It is * merged with the radio MAC address (a 12 character field * unique to every radio), scrambled and stored using another * proprietary, confidential algorithm. */ int32_t key; int8_t ret; int i; int len; int32_t multiplicand = 0x80000181; int64_t res; /* * This algorithm is `compatible' with Proxim's first * `proprietary confidential algorithm': i.e., it appears * to be functionally identical. */ len = strlen(s); key = 0x030201; for (i = 0; i < len; i++) { key *= userkey[i]; res = (int64_t)multiplicand * key; key = key - 0xfffffd * (((key + (int32_t)(res >> 32)) >> 23) - (key >> 31)); } cardkey[0] = (key >> 16) & 0xff; cardkey[1] = (key >> 8) & 0xff; cardkey[2] = key & 0xff; cardkey[0] |= 0x03; /* Restrict key space by 2 bits. */ }