summaryrefslogtreecommitdiffstats
path: root/src/gsm/kasumi.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gsm/kasumi.c')
-rw-r--r--src/gsm/kasumi.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/gsm/kasumi.c b/src/gsm/kasumi.c
index 7de5cd03..f93c002b 100644
--- a/src/gsm/kasumi.c
+++ b/src/gsm/kasumi.c
@@ -159,6 +159,7 @@ void _kasumi_key_expand(const uint8_t *key, uint16_t *KLi1, uint16_t *KLi2, uint
}
}
+/* if cl is not multiple of 8 (a byte), co needs to be sized on the upper bound so the entire byte can be written. */
void _kasumi_kgcore(uint8_t CA, uint8_t cb, uint32_t cc, uint8_t cd, const uint8_t *ck, uint8_t *co, uint16_t cl)
{
uint16_t KLi1[8], KLi2[8], KOi1[8], KOi2[8], KOi3[8], KIi1[8], KIi2[8], KIi3[8], i;
@@ -181,8 +182,16 @@ void _kasumi_kgcore(uint8_t CA, uint8_t cb, uint32_t cc, uint8_t cd, const uint8
_kasumi_key_expand(ck, KLi1, KLi2, KOi1, KOi2, KOi3, KIi1, KIi2, KIi3);
/* i is a block counter */
- for (i = 0; i < cl / 64 + 1; i++) {
+ for (i = 0; i < cl / 64; i++) {
BLK = _kasumi(A ^ i ^ BLK, KLi1, KLi2, KOi1, KOi2, KOi3, KIi1, KIi2, KIi3);
osmo_store64be(BLK, co + (i * 8));
}
+
+ /* Last 64-byte unaligned round. Take also into account last bits non-byte aligned. */
+ uint8_t bytes_remain = cl/8%8 + (cl%8 ? 1 : 0);
+ if (bytes_remain) {
+ BLK = _kasumi(A ^ (cl / 64) ^ BLK, KLi1, KLi2, KOi1, KOi2, KOi3, KIi1, KIi2, KIi3);
+ BLK = BLK >> (8-bytes_remain)*8;
+ osmo_store64be_ext(BLK, co + (cl / 64 * 8), bytes_remain);
+ }
}