https://osmocom.org/https://osmocom.org/favicon.ico?16647414092016-03-28T09:53:17ZOpen Source Mobile CommunicationsOsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=12212016-03-28T09:53:17Zlaforge
<ul><li><strong>Assignee</strong> set to <i>spaar</i></li></ul> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=12852016-04-28T19:27:08Zlaforge
<ul><li><strong>Status</strong> changed from <i>New</i> to <i>In Progress</i></li></ul> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=14762016-05-31T13:10:13Zmsuraev
<ul></ul><p>Note: implementation of GEA3 and 4 was once posted to mailing list <a class="external" href="https://www.freecalypso.org/archive/lists.osmocom.org/baseband-devel/2013-April/003970.html">https://www.freecalypso.org/archive/lists.osmocom.org/baseband-devel/2013-April/003970.html</a> but have not been forward ported.</p> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=14992016-06-01T14:04:42Zlaforge
<ul></ul><p>see <a class="external" href="http://lists.osmocom.org/pipermail/osmocom-net-gprs/2016-May/000614.html">http://lists.osmocom.org/pipermail/osmocom-net-gprs/2016-May/000614.html</a> for an update, also here for convenience:</p>
<pre>
GEA issues (May 2016):
***********************
libosmo-crypt-gea12/src/osmocom.c
---------------------------------
GEA1_stream() and GEA2_stream() operate with bits and not bytes. This
is how they have to be used:
static int gea1_run(uint8_t *out, uint16_t len, uint64_t kc, uint32_t iv,
enum gprs_cipher_direction direction)
{
uint8_t dir;
uint8_t bits_input[32];
uint8_t bits_kc[64];
int i;
// get 32 input bits
for(i = 0; i < 32; i++)
{
bits_input[i] = (BYTE)((iv >> i) & 1);
}
// get 64 key bits
for(i = 0; i < 64; i++)
{
#if 0 // reverse Kc byte order ("reverse" compared to Calypso test code)
bits_kc[i] = (BYTE)((kc >> i) & 1);
#else // "normal" Kc byte order (whatever "normal" is)
bits_kc[i] = (BYTE)((kc >> (((7 - (i / 8)) * 8) + (i % 8))) & 1);
#endif
}
if (direction == GPRS_CIPH_MS2SGSN)
dir = DIRECTION_UPLINK;
else
dir = DIRECTION_DOWNLINK;
GEA1_stream(bits_kc, bits_input, dir, len, out);
return 0;
}
static int gea2_run(uint8_t *out, uint16_t len, uint64_t kc, uint32_t iv,
enum gprs_cipher_direction direction)
{
uint8_t dir;
uint8_t bits_input[32];
uint8_t bits_kc[64];
int i;
// get 32 input bits
for(i = 0; i < 32; i++)
{
bits_input[i] = (BYTE)((iv >> i) & 1);
}
// get 64 key bits
for(i = 0; i < 64; i++)
{
#if 0 // reverse Kc byte order ("reverse" compared to Calypso test code)
bits_kc[i] = (BYTE)((kc >> i) & 1);
#else // "normal" Kc byte order (whatever "normal" is)
bits_kc[i] = (BYTE)((kc >> (((7 - (i / 8)) * 8) + (i % 8))) & 1);
#endif
}
if (direction == GPRS_CIPH_MS2SGSN)
dir = DIRECTION_UPLINK;
else
dir = DIRECTION_DOWNLINK;
GEA2_stream(bits_kc, bits_input, dir, len, out);
return 0;
}
libosmo-crypt-a53/src/osmocom.c
-------------------------------
The length of the key is in bits and not in bytes:
static int gea3_run(uint8_t *out, uint16_t len, uint64_t kc, uint32_t iv,
enum gprs_cipher_direction direction)
{
uint8_t dir;
if (direction == GPRS_CIPH_MS2SGSN)
dir = 0;
else
dir = 1;
GEA3((uint8_t *)&kc, sizeof(kc) * 8, iv, dir, out, len);
return 0;
}
openbsc/openbsc/src/gprs/gprs_llc.c
-----------------------------------
Frame encryption in gprs_llc_tx_ui() doesn't work:
/* encrypt information field + FCS, if needed! */
if (lle->llme->algo != GPRS_ALGO_GEA0) {
uint32_t iov_ui = 0; /* FIXME: randomly select for TLLI */
uint16_t crypt_len = (fcs + 3) - (llch + 3);
uint8_t cipher_out[GSM0464_CIPH_MAX_BLOCK];
uint32_t iv;
int rc, i;
uint64_t kc = *(uint64_t *)&lle->llme->kc;
/* Compute the 'Input' Paraemeter */
iv = gprs_cipher_gen_input_ui(iov_ui, sapi, nu, oc);
/* Compute the keystream that we need to XOR with the data */
rc = gprs_cipher_run(cipher_out, crypt_len, lle->llme->algo,
kc, iv, GPRS_CIPH_SGSN2MS);
if (rc < 0) {
LOGP(DLLC, LOGL_ERROR, "Error crypting UI frame: %d\n", rc);
msgb_free(msg);
return rc;
}
/* Mark frame as encrypted */
#if 1 // Dieter: recalculate checksum after properly setting the flag
llch[2] |= 0x02;
fcs_calc = gprs_llc_fcs(llch, fcs - llch);
fcs[0] = fcs_calc & 0xff;
fcs[1] = (fcs_calc >> 8) & 0xff;
fcs[2] = (fcs_calc >> 16) & 0xff;
#endif
/* XOR the cipher output with the information field + FCS */
for (i = 0; i < crypt_len; i++)
*(llch + 3 + i) ^= cipher_out[i];
/* Mark frame as encrypted */
#if 0 // Dieter: This won't work
ctrl[1] |= 0x02;
#endif
}
Frame decryption in gprs_llc_rcvmsg() doesn't work:
/* decrypt information field + FCS, if needed! */
if (llhp.is_encrypted) {
uint32_t iov_ui = 0; /* FIXME: randomly select for TLLI */
uint16_t crypt_len = llhp.data_len + 3;
uint8_t cipher_out[GSM0464_CIPH_MAX_BLOCK];
uint32_t iv;
uint64_t kc = *(uint64_t *)&lle->llme->kc;
int rc, i;
if (lle->llme->algo == GPRS_ALGO_GEA0) {
LOGP(DLLC, LOGL_NOTICE, "encrypted frame for LLC that "
"has no KC/Algo! Dropping.\n");
return 0;
}
iv = gprs_cipher_gen_input_ui(iov_ui, lle->sapi, llhp.seq_tx,
lle->oc_ui_recv);
rc = gprs_cipher_run(cipher_out, crypt_len, lle->llme->algo,
kc, iv, GPRS_CIPH_MS2SGSN);
if (rc < 0) {
LOGP(DLLC, LOGL_ERROR, "Error decrypting frame: %d\n",
rc);
return rc;
}
/* XOR the cipher output with the information field + FCS */
for (i = 0; i < crypt_len; i++)
*(llhp.data + i) ^= cipher_out[i];
#if 1 // Dieter: FCS is encrypted, gprs_llc_hdr_parse() should be called again
llhp.fcs = *(llhp.data + crypt_len - 3);
llhp.fcs |= *(llhp.data + crypt_len - 2) << 8;
llhp.fcs |= *(llhp.data + crypt_len - 1) << 16;
#endif
} else {
if (lle->llme->algo != GPRS_ALGO_GEA0) {
LOGP(DLLC, LOGL_NOTICE, "unencrypted frame for LLC "
"that is supposed to be encrypted. Dropping.\n");
return 0;
}
}
Open issues:
############
openbsc/openbsc/src/gprs/gprs_llc.c
-----------------------------------
When creating an LLME "on the fly" in lle_for_rx_by_tlli_sapi() kc and algo
of the LLME have to be set to the ones used for the subscriber.
In general:
-----------
Management of GEA algorithm and KC for a subscriber. The algorithm has to
be selected according to the capabilities of the MS. Some affected functions
are gprs_llgmm_assign() and gsm48_tx_gmm_auth_ciph_req().
Handling of IOV (initialisation vector), currently most of the time IOV is
set to 0, but gprs_llgmm_reset() and gprs_llgmm_reset_oldmsg() use a random
IOV and would probably cause problems when called.
Using uint64_t as the type for Kc in the GEA libraries is not a good choice,
uint8_t[8] would be better and cause less troubles (e.g. endian issues and
incompatibility with the test vectors, where the order of Kc has to be
reversed). Attention: this change might require to adjust the byte order of
Kc in the GEA libraries.
</pre> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=15062016-06-01T14:29:47Zlaforge
<ul><li><strong>Assignee</strong> changed from <i>spaar</i> to <i>laforge</i></li><li><strong>% Done</strong> changed from <i>0</i> to <i>30</i></li></ul><p>changes to libosmo-crypt-* have just been pushed. Changes to OsmoSGSN still pending.</p> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=15072016-06-01T14:34:52Zlaforge
<ul><li><strong>Related to</strong> <i><a class="issue tracker-2 status-5 priority-2 priority-default closed" href="/issues/1741">Feature #1741</a>: GEA encryption unit tests</i> added</li></ul> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=15912016-06-14T09:31:09Zlaforge
<ul><li><strong>Assignee</strong> changed from <i>laforge</i> to <i>msuraev</i></li></ul> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=15922016-06-14T09:35:53Zlaforge
<ul><li><strong>Priority</strong> changed from <i>Normal</i> to <i>High</i></li></ul> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=15942016-06-14T09:38:02Zlaforge
<ul><li><strong>Priority</strong> changed from <i>High</i> to <i>Urgent</i></li></ul> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=17072016-06-28T10:02:55Zmsuraev
<ul><li><strong>Blocked by</strong> <i><a class="issue tracker-1 status-6 priority-2 priority-default closed" href="/issues/1758">Bug #1758</a>: segfault in sgsn</i> added</li></ul> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=17232016-07-01T16:30:18Zmsuraev
<ul></ul><p>Testing with osmo-auc - Kc is generated properly and propagated to LLC layer, phone capabilities are checked but activating pdp context fails. Most likely reason: encryption is started at the wrong time (too early?). Unlike GSM in GPRS there seems to be no explicit command to mark the moment when encryption should be applied.</p> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=17372016-07-04T16:28:27Zmsuraev
<ul></ul><p>GEA3 encryption working with gerrit #455 but only tested with IOV=0 instead of random due to missing XID IOV negotiation code.</p> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=17442016-07-05T10:15:57Zmsuraev
<ul><li><strong>% Done</strong> changed from <i>30</i> to <i>40</i></li></ul><p>Preliminary implementation sent for review as gerrit #460</p> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=18602016-07-18T08:03:08Zmsuraev
<ul><li><strong>% Done</strong> changed from <i>40</i> to <i>70</i></li></ul><p>Everything except for XID is merged into master.</p> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=18622016-07-18T08:03:36Zmsuraev
<ul><li><strong>Blocked by</strong> <i><a class="issue tracker-2 status-5 priority-3 priority-high3 closed" href="/issues/1580">Feature #1580</a>: IP header compression</i> added</li></ul> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=18712016-07-19T10:22:22Zmsuraev
<ul><li><strong>Status</strong> changed from <i>In Progress</i> to <i>Stalled</i></li></ul> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=20282016-08-09T14:23:56Zmsuraev
<ul><li><strong>Status</strong> changed from <i>Stalled</i> to <i>Resolved</i></li><li><strong>Assignee</strong> changed from <i>msuraev</i> to <i>laforge</i></li><li><strong>% Done</strong> changed from <i>70</i> to <i>100</i></li></ul><p>Random IV generation/negotiation has been split into separate ticket. GEA with current hardcoded IV=0 is working.</p> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=20302016-08-09T14:24:32Zmsuraev
<ul><li><strong>Blocked by</strong> <i><a class="issue tracker-1 status-7 priority-2 priority-default" href="/issues/1794">Bug #1794</a>: support random IV for GEA (via XID)</i> added</li></ul> OsmoSGSN - Bug #1582: GEA Encryption is missinghttps://osmocom.org/issues/1582?journal_id=21112016-08-30T17:05:02Zlaforge
<ul><li><strong>Blocked by</strong> deleted (<i><a class="issue tracker-2 status-5 priority-3 priority-high3 closed" href="/issues/1580">Feature #1580</a>: IP header compression</i>)</li></ul>