ue_process_nas.c 5.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Author and copyright: Laurent Thomas, open-cells.com
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
23 24
#include <openair3/NAS/COMMON/NR_NAS_defs.h>
#include <openair3/SECU/secu_defs.h>
Laurent's avatar
Laurent committed
25 26


laurent's avatar
laurent committed
27 28 29
void SGSabortNet(void *msg, nr_user_nas_t *UE) {
}

30
void ue_nas_schedule(void) {
Laurent's avatar
Laurent committed
31
}
laurent's avatar
laurent committed
32 33 34 35 36 37

/*
 *Message reception
 */

void SGSauthenticationReq(void *msg, nr_user_nas_t *UE) {
38 39 40
  authenticationrequestHeader_t *amsg=(authenticationrequestHeader_t *) msg;
  arrayCpy(UE->uicc->rand,amsg->RAND);
  arrayCpy(UE->uicc->autn,amsg->AUTN);
Laurent's avatar
Laurent committed
41 42 43
  // AUTHENTICATION REQUEST message that contains a valid ngKSI, SQN and MAC is received
  // TBD verify ngKSI (we set it as '2', see gNB code)
  // SQN and MAC are tested in auth resp processing
44
  ue_nas_schedule();
45 46 47
}

void SGSidentityReq(void *msg, nr_user_nas_t *UE) {
Laurent's avatar
Laurent committed
48 49 50 51
  Identityrequest_t *idmsg=(Identityrequest_t *) msg;

  if (idmsg->it == SUCI ) {
    LOG_I(NAS,"Received Identity request, scheduling answer\n");
52
    ue_nas_schedule();
Laurent's avatar
Laurent committed
53 54
  } else
    LOG_E(NAS,"Not developped: identity request for %d\n", idmsg->it);
laurent's avatar
laurent committed
55 56 57 58 59 60 61 62 63 64 65 66 67
}

void SGSsecurityModeCommand(void *msg, nr_user_nas_t *UE) {
}


void UEprocessNAS(void *msg,nr_user_nas_t *UE) {
  SGScommonHeader_t *header=(SGScommonHeader_t *) msg;

  if ( header->sh > 4 )
    SGSabortNet(msg, UE);
  else {
    switch  (header->epd) {
Laurent's avatar
Laurent committed
68
      case SGSmobilitymanagementmessages:
69 70
        LOG_I(NAS,"Received message: %s\n", idStr(message_text_info, header->mt));

laurent's avatar
laurent committed
71
        switch (header->mt) {
Laurent's avatar
Laurent committed
72
          case Authenticationrequest:
laurent's avatar
laurent committed
73 74
            SGSauthenticationReq(msg, UE);
            break;
Laurent's avatar
Laurent committed
75 76

          case Identityrequest:
laurent's avatar
laurent committed
77 78
            SGSidentityReq(msg, UE);
            break;
Laurent's avatar
Laurent committed
79 80

          case Securitymodecommand:
laurent's avatar
laurent committed
81 82 83 84 85 86 87 88
            SGSsecurityModeCommand(msg, UE);
            break;

          default:
            SGSabortNet(msg, UE);
        }

        break;
Laurent's avatar
Laurent committed
89 90

      case SGSsessionmanagementmessages:
laurent's avatar
laurent committed
91 92 93 94 95 96 97 98 99 100 101 102 103
        SGSabortNet(msg, UE);
        break;

      default:
        SGSabortNet(msg, UE);
    }
  }
}

/*
 * Messages emission
 */

Laurent's avatar
Laurent committed
104 105 106 107 108 109
int identityResponse(void **msg, nr_user_nas_t *UE) {
  if (UE->uicc == NULL)
    // config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE
    UE->uicc=init_uicc("uicc");

  // TS 24.501 9.11.3.4
Laurent's avatar
Laurent committed
110
  int imsiL=strlen(UE->uicc->imsiStr);
Laurent's avatar
Laurent committed
111 112 113 114 115 116 117 118
  int msinL=imsiL-3-UE->uicc->nmc_size;
  int respSize=sizeof(IdentityresponseIMSI_t) + (msinL+1)/2;
  IdentityresponseIMSI_t *resp=(IdentityresponseIMSI_t *) calloc(respSize,1);
  resp->common.epd=SGSmobilitymanagementmessages;
  resp->common.sh=0;
  resp->common.mt=Identityresponse;
  resp->common.len=htons(respSize-sizeof(Identityresponse_t));
  resp->mi=SUCI;
Laurent's avatar
Laurent committed
119 120 121 122 123 124
  resp->mcc1=UE->uicc->imsiStr[0]-'0';
  resp->mcc2=UE->uicc->imsiStr[1]-'0';
  resp->mcc3=UE->uicc->imsiStr[2]-'0';
  resp->mnc1=UE->uicc->imsiStr[3]-'0';
  resp->mnc2=UE->uicc->imsiStr[4]-'0';
  resp->mnc3=UE->uicc->nmc_size==2? 0xF : UE->uicc->imsiStr[3]-'0';
Laurent's avatar
Laurent committed
125 126
  // TBD: routing to fill (FF ?)
  char *out=(char *)(resp+1);
Laurent's avatar
Laurent committed
127
  char *ptr=UE->uicc->imsiStr + 3 + UE->uicc->nmc_size;
Laurent's avatar
Laurent committed
128

Laurent's avatar
Laurent committed
129
  while ( ptr < UE->uicc->imsiStr+strlen(UE->uicc->imsiStr) ) {
Laurent's avatar
Laurent committed
130 131 132 133 134 135 136 137 138 139
    *out=((*(ptr+1)-'0')<<4) | (*(ptr) -'0');
    out++;
    ptr+=2;
  }

  if (msinL%2 == 1)
    *out=((*(ptr-1)-'0')) | 0xF0;

  *msg=resp;
  return respSize;
laurent's avatar
laurent committed
140 141
}

Laurent's avatar
Laurent committed
142
int authenticationResponse(void **msg,nr_user_nas_t *UE) {
143 144 145
  if (UE->uicc == NULL)
    // config file section hardcoded as "uicc", nevertheless it opens to manage several UEs or a multi SIM UE
    UE->uicc=init_uicc("uicc");
146

147 148 149 150 151
  myCalloc(resp, authenticationresponse_t);
  resp->epd=SGSmobilitymanagementmessages;
  resp->sh=0;
  resp->mt=Authenticationresponse;
  resp->iei=IEI_AuthenticationResponse;
Laurent's avatar
Laurent committed
152
  resp->RESlen=sizeof(resp->RES); // always 16 see TS 24.501 Table 8.2.2.1.1
153
  // Verify the AUTN
154 155 156 157 158
  // a full implementation need to test several SQN
  // as the last 5bits can be any value
  // and the value can also be greater and accepted (if it is in the accepted window)
  uint8_t AUTN[16];
  uicc_milenage_generate(AUTN, UE->uicc);
Laurent's avatar
Laurent committed
159

160
  if ( memcmp(UE->uicc->autn, AUTN, sizeof(AUTN)) == 0 ) {
161
    // prepare and send good answer
162
    resToresStar(resp->RES,UE->uicc);
163
  } else {
164 165
    // prepare and send autn is not compatible with our data
    abort();
166
  }
167

168 169
  *msg=resp;
  return sizeof(authenticationresponse_t);
laurent's avatar
laurent committed
170 171
}

Laurent's avatar
Laurent committed
172 173
int securityModeComplete(void **msg, nr_user_nas_t *UE) {
  return -1;
laurent's avatar
laurent committed
174 175
}

Laurent's avatar
Laurent committed
176 177
int registrationComplete(void **msg, nr_user_nas_t *UE) {
  return -1;
laurent's avatar
laurent committed
178
}