Exemplo n.º 1
0
void Randomizer() {
    do {
        AJ_RandBytes((uint8_t*) &tid1, sizeof(tid1));
        AJ_Sleep(10);
        AJ_RandBytes((uint8_t*) &tid2, sizeof(tid2));
        AJ_Sleep(10);
        AJ_RandBytes((uint8_t*) &tid3, sizeof(tid3));
        AJ_Sleep(10);
        AJ_RandBytes((uint8_t*) &tid4, sizeof(tid4));
        AJ_InfoPrintf(("Randomizer values: %u %u %u %u\n", tid1, tid2, tid3, tid4));
    } while (tid1 == 0 || tid2 == 0 || tid3 == 0 || tid4 == 0);
}
Exemplo n.º 2
0
AJ_Status AJ_GetGroupKey(const char* name, uint8_t* key)
{
  //  AJ_InfoPrintf(("AJ_GetGroupKey(name=\"%s\", key=0x%p)\n", name, key));
    if (name) 
	{
        NameToGUID* mapping = LookupName(name);
        if (!mapping) 
		{
    //        AJ_WarnPrintf(("AJ_GetGroupKey(): AJ_ERR_NO_MATCH\n"));
            return AJ_ERR_NO_MATCH;
        }
        memcpy(key, mapping->groupKey, 16);
    }
	else
	{
        // Check if the group key needs to be initialized
        memset(key, 0, 16);
        if (memcmp(localGroupKey, key, 16) == 0)
		{
            AJ_RandBytes(localGroupKey, 16);
        }
        memcpy(key, localGroupKey, 16);
    }
    return AJ_OK;
}
Exemplo n.º 3
0
AJ_Status AJ_GetGroupKey(const char* name, uint8_t* key)
{
    if (name) {
        NameToGUID* mapping = LookupName(name);
        if (!mapping) {
            return AJ_ERR_NO_MATCH;
        }
        memcpy(key, mapping->groupKey, 16);
    } else {
        /*
         * Check if the group key needs to be initialized
         */
        memset(key, 0, 16);
        if (memcmp(localGroupKey, key, 16) == 0) {
            AJ_RandBytes(localGroupKey, 16);
        }
        memcpy(key, localGroupKey, 16);
    }
    return AJ_OK;
}
Exemplo n.º 4
0
void AJ_Initialize(void)
{
    AJ_GUID localGuid;
    if (!initialized) {
        initialized = TRUE;
        AJ_NVRAM_Init();
        /*
         * This will seed the random number generator
         */
        AJ_RandBytes(NULL, 0);
        /*
         * This will initialize credentials if needed
         */
        AJ_GetLocalGUID(&localGuid);

        /*
         * Clear the Routing Node black list
         */
        AJ_InitRoutingNodeBlacklist();

        AJ_InitRoutingNodeResponselist();
    }
}
Exemplo n.º 5
0
void AJ_Main(void)
{
    uint8_t i = 0;
    AJ_Status status = AJ_ERR_FAILURE; /* the glass is half-empty */
    AJ_BusAttachment bus;

    /* these variables are used when kicking off DHCP */
    uint32_t current_ip_address = 0;
    uint32_t current_subnet_mask = 0;
    uint32_t current_default_gateway = 0;
    AJ_Time dhcpTimer;
    uint32_t timeTakenForDhcp = 0;

    AJ_Initialize();

    AJ_Printf("\nAllJoyn Release: %s\n\n", AJ_GetVersion());

    AJ_Printf("INFO: The parameter RUN_NEGATIVE_TESTS is %s\n", (RUN_NEGATIVE_TESTS ? "true" : "false"));
    AJ_Printf("INFO: The parameter DELAY_BETWEEN_SCANS is %u ms\n", DELAY_BETWEEN_SCANS);
    AJ_Printf("INFO: The parameter DELAY_BETWEEN_ASSOCIATIONS is %u ms\n", DELAY_BETWEEN_ASSOCIATIONS);
    AJ_Printf("INFO: The parameter DHCP_TIMEOUT is %u ms\n", DHCP_TIMEOUT);
    AJ_Printf("INFO: The parameter DISCOVER_TIMEOUT is %u ms\n", DISCOVER_TIMEOUT);

    /* reset the wifi to start with a clean slate */
    status = AJ_ResetWiFi();
    if (AJ_OK != status) {
        AJ_Printf("WARN: AJ_ResetWiFi returned %s (code: %u).\n", AJ_StatusText(status), status);
    }

    /*
     * Repeatedly do the following:
     * a. scan for access points in the vicinity
     * b. For each open access point in the returned results:
     *      i.   associate using AJ_ConnectWiFi
     *      ii.  acquire an ip address using AJ_AcquireIPAddress
     *      iii. perform a short-lived discovery on some random node prefix
     *           using AJ_FindBusAndConnect
     *      iv.  disassociate using AJ_DisconnectWiFi
     * c. For each secured access point in the returned results:
     *      i. Connect to it with intentionally incorrect parameters
     *         (Negative test)
     */
    while (TRUE) {
        AJ_RandBytes(&currentContext, sizeof(currentContext));

        uint8_t currentMaxAps = 0;
        AJ_RandBytes(&currentMaxAps, sizeof(currentMaxAps));

        /* Reset numValidScanEntries, before every scan attempt. */
        numValidScanEntries = 0;

        status = AJ_WiFiScan((void*) (sentinelForWifiScanContext + currentContext), wifiScanResultCallback, currentMaxAps);

        if (AJ_OK != status) {
            if (AJ_ERR_FAILURE == status && 0 != currentMaxAps) {
                scanStats.numFailed++;
            } else if (AJ_ERR_RESOURCES == status) {
                scanStats.numFailed++;
            }

            AJ_Printf("Failed to scan: %s (code: %u)\n", AJ_StatusText(status), status);

            /* No point in attempting to do wifi operations, when scan failed */
            continue;
        } else {
            /*
             * A success was returned from AJ_WiFiScan. Were any results
             * returned after all??
             */
            if (0 < numValidScanEntries) {
                scanStats.numSuccessful++;
            } else {
                AJ_Printf("WARN: AJ_WiFiScan returned %s (code: %u), but returned ZERO scan results...\n", AJ_StatusText(status), status);
                scanStats.numFailed++;

                /* When num of scan results is zero, there is nothing to do */
                continue;
            }
        }

        /* numValidScanEntries is an index into the array. Hence +1. */
        if (currentMaxAps < numValidScanEntries + 1) {
            AJ_Printf("WARN: Scan returned more results (%u) than requested (%u).\n", numValidScanEntries + 1, currentMaxAps);
        } else {
            AJ_Printf("Wifi scan successful (got %u results).\n", numValidScanEntries);
        }

        for (i = 0; i < numValidScanEntries; i++) {
            if (AJ_WIFI_SECURITY_NONE != wifiScanInfo[i].secType) {
                /* On some targets, it is not possible to check for 802.11
                 * authentication failure when security type is WEP.
                 * Hence, run negative tests only for WPA/WPA2-based APs.
                 */
                if (RUN_NEGATIVE_TESTS && AJ_WIFI_SECURITY_WEP != wifiScanInfo[i].secType) {
                    /* Run a negative test for wifi association */
                    AJ_Printf("RUN (negative test): Attempting to associate with %s using a randomly generated passphrase...", wifiScanInfo[i].ssid);
                    char random_passphrase[128 + 1];
                    AJ_RandHex(random_passphrase, sizeof(random_passphrase), (sizeof(random_passphrase) - 1) / 2);

                    /* Set a random passphrase length based on security type */
                    uint8_t randomPassphraseLen = 0;
                    /* WPA / WPA2 - assuming min len is 8 and max is 64 */
                    AJ_RandBytes(&randomPassphraseLen, sizeof(randomPassphraseLen));
                    randomPassphraseLen = 8 + randomPassphraseLen % (64 - 8 + 1);
                    random_passphrase[randomPassphraseLen] = '\0';
                    status = AJ_ConnectWiFi(wifiScanInfo[i].ssid, wifiScanInfo[i].secType, wifiScanInfo[i].cipherType, random_passphrase);
                    if (AJ_OK == status) {
                        /* negative test failed */
                        AJ_Printf("FAIL (negative test): Associated with SSID: %s BSSID: %x:%x:%x:%x:%x:%x Security: %s(%s) Passphrase: %s RSSI: %u ...\n", wifiScanInfo[i].ssid, wifiScanInfo[i].bssid[0], wifiScanInfo[i].bssid[1], wifiScanInfo[i].bssid[2], wifiScanInfo[i].bssid[3], wifiScanInfo[i].bssid[4], wifiScanInfo[i].bssid[5], secStr[wifiScanInfo[i].secType], ciphStr[wifiScanInfo[i].cipherType], random_passphrase, wifiScanInfo[i].rssi);

                        /* negative test failed - don't go any further */
                        AJ_ASSERT(0);
                    } else {
                        AJ_Printf("Done (negative test).\n");
                    }
                    status = AJ_DisconnectWiFi();
                    AJ_Sleep(DELAY_BETWEEN_ASSOCIATIONS);
                }

                continue;
            } else {
                AJ_Printf("Attempting to associate with SSID: %s BSSID: %x:%x:%x:%x:%x:%x Security: %s(%s) RSSI: %u ...\n",
                          wifiScanInfo[i].ssid,
                          wifiScanInfo[i].bssid[0], wifiScanInfo[i].bssid[1], wifiScanInfo[i].bssid[2], wifiScanInfo[i].bssid[3], wifiScanInfo[i].bssid[4], wifiScanInfo[i].bssid[5],
                          secStr[wifiScanInfo[i].secType], ciphStr[wifiScanInfo[i].cipherType],
                          wifiScanInfo[i].rssi);
                status = AJ_ConnectWiFi(wifiScanInfo[i].ssid, wifiScanInfo[i].secType, wifiScanInfo[i].cipherType, "");
                if (AJ_OK != status) {
                    associationStats.numFailed++;
                    AJ_Printf("Failed to associate : %s (code: %u)\n", AJ_StatusText(status), status);
                    /*
                     * No point in proceeding any further when WiFi association
                     * has failed
                     */
                    continue;
                } else {
                    associationStats.numSuccessful++;
                }

                AJ_Printf("Successfully associated. Attempting to get IP Address via DHCP...\n");

                AJ_InitTimer(&dhcpTimer);

                status = AJ_AcquireIPAddress(&current_ip_address, &current_subnet_mask, &current_default_gateway, DHCP_TIMEOUT);

                timeTakenForDhcp = AJ_GetElapsedTime(&dhcpTimer, FALSE);

                if (AJ_OK != status) {
                    if (AJ_ERR_TIMEOUT == status) {
                        dhcpStats.numTimedout++;
                        AJ_Printf("Timedout (%u ms) while trying to get IP Address via DHCP\n", timeTakenForDhcp);
                        /*
                         * Discovery timed out.
                         * Check whether the API returned in a timely manner.
                         * See whether the actual duration is off by +/- 500ms.
                         * Delay beyond that is unusual.
                         */
                        if (500 < abs(DHCP_TIMEOUT - timeTakenForDhcp)) {
                            AJ_Printf("WARN: AJ_AcquireIPAddress API did not return in a timely manner. Timeout parameter: %u Actual time elapsed: %u\n",
                                      DHCP_TIMEOUT,
                                      timeTakenForDhcp);
                        }
                    } else {
                        dhcpStats.numFailed++;
                        AJ_Printf("Failed to get IP Address via DHCP : %s (code: %u)\n", AJ_StatusText(status), status);
                    }
                    /*
                     * No point in proceeding any further when IP address was
                     * not acquired
                     */
                    continue;
                } else {
                    dhcpStats.numSuccessful++;
                    AJ_Printf("Successfully obtained\n");
                    AJ_Printf("\tIP Addresss    : %s\n", TestAddrStr(current_ip_address));
                    AJ_Printf("\tSubnet Mask    : %s\n", TestAddrStr(current_subnet_mask));
                    AJ_Printf("\tDefault Gateway: %s\n", TestAddrStr(current_default_gateway));
                }

                /* Generate a random name using routingNodePrefix */
                char currentRoutingNodeName[32 + 1];
                strncpy(currentRoutingNodeName, routingNodePrefix, sizeof(routingNodePrefix));
                AJ_RandHex(currentRoutingNodeName + strlen(routingNodePrefix), sizeof(currentRoutingNodeName) - sizeof(routingNodePrefix), (sizeof(currentRoutingNodeName) - sizeof(routingNodePrefix) - 1) / 2);
                currentRoutingNodeName[32] = '\0'; /* just to be safe */

                AJ_Printf("Attempting to discover routing node: %s...", currentRoutingNodeName);

                status = AJ_FindBusAndConnect(&bus, currentRoutingNodeName, DISCOVER_TIMEOUT);

                if (AJ_ERR_TIMEOUT == status) {
                    /* this is the expected result */
                    discoverStats.numTimedout++;
                    AJ_Printf("Done (discovery of routing node).\n");
                } else if (AJ_OK != status) {
                    discoverStats.numFailed++;
                    AJ_Printf("Failed to connect to routing node: %s (code: %u)\n", AJ_StatusText(status), status);
                } else if (AJ_OK == status) {
                    /*
                     * the test attempted to discovery a randomly generated
                     * routing node prefix and it worked - highly unlikely event
                     */
                    AJ_Printf("FATAL: Was able to discover and connect to routing node with prefix %s. Got unique address %s.", currentRoutingNodeName, AJ_GetUniqueName(&bus));
                    AJ_ASSERT(0);
                }

                status = AJ_DisconnectWiFi();

                if (AJ_OK != status) {
                    disassociationStats.numFailed++;
                    AJ_Printf("Failed to disassociate: %s (code: %u)\n", AJ_StatusText(status), status);
                } else {
                    disassociationStats.numSuccessful++;
                    AJ_Printf("Disassociated from access point. ");
                }
                AJ_Sleep(DELAY_BETWEEN_ASSOCIATIONS);
            }
        }

        PrintStats();

        AJ_Sleep(DELAY_BETWEEN_SCANS);
    }
}
/**
 * Send Notification - see notes in h file
 */
AJ_Status AJNS_Producer_SendNotification(AJ_BusAttachment* busAttachment, AJNS_NotificationContent* content, uint16_t messageType, uint32_t ttl, uint32_t* messageSerialNumber)
{
    AJ_Status status;
    AJNS_Notification notification;
    uint32_t serialNumber;

  //  AJ_InfoPrintf(("In SendNotification\n"));

    notification.version = AJNS_NotificationVersion;
    if (messageType >= AJNS_NUM_MESSAGE_TYPES)
	{
        AJ_ErrPrintf(("Could not Send Notification - MessageType is not valid\n"));
        return AJ_ERR_DISALLOWED;
    }
    notification.messageType = messageType;

    if ((ttl < AJNS_NOTIFICATION_TTL_MIN) || (ttl > AJNS_NOTIFICATION_TTL_MAX)) 
	{      //ttl is mandatory and must be in range
        AJ_ErrPrintf(("TTL '%u' is not a valid TTL value\n", ttl));
        return AJ_ERR_DISALLOWED;
    }

    notification.deviceId = AJSVC_PropertyStore_GetValue(AJSVC_PROPERTY_STORE_DEVICE_ID);
    notification.deviceName = AJSVC_PropertyStore_GetValueForLang(AJSVC_PROPERTY_STORE_DEVICE_NAME, AJSVC_PropertyStore_GetLanguageIndex(""));
    notification.appId = AJSVC_PropertyStore_GetValue(AJSVC_PROPERTY_STORE_APP_ID);
    notification.appName = AJSVC_PropertyStore_GetValue(AJSVC_PROPERTY_STORE_APP_NAME);

    if ((notification.deviceId == 0) || (notification.deviceName == 0) ||
        (notification.appId == 0) || (notification.appName == 0)) 
	{
        AJ_ErrPrintf(("DeviceId/DeviceName/AppId/AppName can not be NULL\n"));
        return AJ_ERR_DISALLOWED;
    }

    if ((strlen(notification.deviceId) == 0) || (strlen(notification.deviceName) == 0) ||
        (strlen(notification.appId) == 0) || (strlen(notification.appName) == 0)) 
	{
        AJ_ErrPrintf(("DeviceId/DeviceName/AppId/AppName can not be empty\n"));
        return AJ_ERR_DISALLOWED;
    }

    if (notification.version > 1) 
	{
        notification.originalSenderName = AJ_GetUniqueName(busAttachment);

        if (notification.originalSenderName == 0) 
		{
            AJ_ErrPrintf(("OriginalSender can not be NULL\n"));
            return AJ_ERR_DISALLOWED;
        }

        if (strlen(notification.originalSenderName) == 0) 
		{
            AJ_ErrPrintf(("OriginalSender can not be empty\n"));
            return AJ_ERR_DISALLOWED;
        }
    }
	else 
	{
        notification.originalSenderName = NULL;
    }

    if (!notificationId)
	{
    //    AJ_InfoPrintf(("Generating random number for notification id\n"));
        AJ_RandBytes((uint8_t*)&notificationId, 4);
    }

    notification.notificationId = notificationId;
    notification.content = content;

    status = AJNS_Producer_SendNotifySignal(busAttachment, &notification, ttl, &serialNumber);

    if (status == AJ_OK) 
	{
        lastSentNotifications[messageType].notificationId = notificationId++;
        lastSentNotifications[messageType].serialNum = serialNumber;
        if (messageSerialNumber != NULL) 
		{
            *messageSerialNumber = serialNumber;
        }
    }

    return status;
}
Exemplo n.º 7
0
AJ_Status AJ_SelectRoutingNodeFromResponseList(AJ_Service* service)
{
    /*
     * The selection involves choosing the router with the
     * highest protocol version and the lowest service priority
     * (inverse of static rank/score).
     */
    uint8_t i = 1;
    uint8_t selectedIndex = 0;
    uint32_t runningSum = 0;
    uint8_t skip = 0;
    uint32_t priority_idx = 0;
    uint32_t priority_srv = 0;
    uint32_t rand32 = 0;
    if (RNResponseList[0].ipv4 || RNResponseList[0].ipv4Udp) {
        service->ipv4 = RNResponseList[0].ipv4;
        service->ipv4port = RNResponseList[0].ipv4port;
        service->ipv4Udp = RNResponseList[0].ipv4Udp;
        service->ipv4portUdp = RNResponseList[0].ipv4portUdp;
        service->pv = RNResponseList[0].pv;
        service->addrTypes = RNResponseList[0].addrTypes;
        service->priority = RNResponseList[0].priority;
        runningSum = service->priority;
        skip = RNAttemptsList[0];
        if (skip) {
            AJ_InfoPrintf(("Index 0 was previously selected\n"));
        }
        for (; i  < AJ_ROUTING_NODE_RESPONSELIST_SIZE; ++i) {
            if (RNResponseList[i].ipv4 || RNResponseList[i].ipv4Udp) {
                if (RNAttemptsList[i]) {
                    AJ_InfoPrintf(("Index %d was previously selected\n", i));
                    continue;
                }
                if (skip) {
                    service->ipv4 = RNResponseList[i].ipv4;
                    service->ipv4port = RNResponseList[i].ipv4port;
                    service->ipv4Udp = RNResponseList[i].ipv4Udp;
                    service->ipv4portUdp = RNResponseList[i].ipv4portUdp;
                    service->pv = RNResponseList[i].pv;
                    service->addrTypes = RNResponseList[i].addrTypes;
                    service->priority = RNResponseList[i].priority;
                    selectedIndex = i;
                    runningSum = service->priority;
                    skip = 0;
                    continue;
                }
                if (RNResponseList[i].pv < service->pv) {
                    continue;
                }
                if (RNResponseList[i].pv > service->pv || (RNResponseList[i].pv == service->pv && RNResponseList[i].priority < service->priority)) {
                    service->ipv4 = RNResponseList[i].ipv4;
                    service->ipv4port = RNResponseList[i].ipv4port;
                    service->ipv4Udp = RNResponseList[i].ipv4Udp;
                    service->ipv4portUdp = RNResponseList[i].ipv4portUdp;
                    service->pv = RNResponseList[i].pv;
                    service->addrTypes = RNResponseList[i].addrTypes;
                    service->priority = RNResponseList[i].priority;
                    runningSum = service->priority;
                    selectedIndex = i;
                    AJ_InfoPrintf(("Tentatively selecting routing node %x (pv = %d, port = %d, priority = %d).\n", service->ipv4, service->pv, service->ipv4port, service->priority));
                } else if (RNResponseList[i].priority == service->priority) {
                    /*
                     * Randomly select one of out of all the routing nodes with the same
                     * protocol version and priority with each node given an equal chance
                     * of being selected. To select from a pair of nodes, the first node's
                     * priority is used as its associated sum, while the sum of the two
                     * priorities under consideration is used as the second node's
                     * associated sum. A uniform random number up to the sum of the two
                     * priorities (inclusive) is chosen and the first node whose associated
                     * sum is greater than or equal to the random number is selected.
                     */
                    rand32 = 0;
                    AJ_RandBytes((uint8_t*)&rand32, sizeof(rand32));
                    priority_idx = RNResponseList[i].priority + runningSum;
                    priority_srv = runningSum;
                    runningSum = priority_idx;
                    rand32 %= (runningSum + 1);
                    AJ_InfoPrintf(("P_idx is %u and P_srv is %u and random is %u\n", priority_idx, priority_srv, rand32));
                    if (rand32 > priority_srv) {
                        AJ_InfoPrintf(("Picking index %d on this round\n", i));
                        service->ipv4 = RNResponseList[i].ipv4;
                        service->ipv4port = RNResponseList[i].ipv4port;
                        service->ipv4Udp = RNResponseList[i].ipv4Udp;
                        service->ipv4portUdp = RNResponseList[i].ipv4portUdp;
                        service->pv = RNResponseList[i].pv;
                        service->addrTypes = RNResponseList[i].addrTypes;
                        service->priority = RNResponseList[i].priority;
                        selectedIndex = i;
                        AJ_InfoPrintf(("Tentatively selecting routing node 0x%x (pv = %d, port = %d, priority = %d).\n", service->ipv4, service->pv, service->ipv4port, service->priority));
                    }
                }
            } else {
                // break early if list isn't full
                break;
            }
        }
    } else {
        AJ_InitRoutingNodeResponselist();
        return AJ_ERR_TIMEOUT;
    }

    if (skip) {
        AJ_InfoPrintf(("All entries in the response list have been previously selected\n"));
        return AJ_ERR_END_OF_DATA;
    }
    RNAttemptsList[selectedIndex] = 1;
    AJ_InfoPrintf(("Selected routing node 0x%x (pv = %d, port = %d, priority = %d) out of %d responses in the list.\n", service->ipv4, service->pv, service->ipv4port, service->priority, RNResponseListIndex));
    return AJ_OK;
}
Exemplo n.º 8
0
int AJ_Main_nvramtest()
{
    AJ_Status status = AJ_OK;
    static uint16_t oRand = 0;
    while (status == AJ_OK) {
        AJ_AlwaysPrintf(("AJ Initialize\n"));
        AJ_Initialize();

#ifdef OBS_ONLY
        AJ_RandBytes(&oRand, sizeof(oRand));
        AJ_InfoPrintf(("BEGIN OBSWRITE TEST\n"));
        status = testObsWrite();
        if (oRand % 2 == 0) {
            AJ_InfoPrintf(("CALLING REBOOT WITHOUT REWRITING TO 0"));
#ifdef READABLE_LOG
            AJ_Sleep(1500);
#endif
            AJ_Reboot();
        }
        AJ_InfoPrintf(("REWRITE OBS TO 0 AND READ TEST\n"));
#ifdef READABLE_LOG
        AJ_Sleep(1500);
#endif
        status = TestNvramDelete();
        AJ_Reboot();
#endif
        AJ_NVRAM_Clear();

        AJ_AlwaysPrintf(("TEST LOCAL AND REMOTE CREDS\n"));
        status = TestCreds();
        AJ_ASSERT(status == AJ_OK);
#ifdef READABLE_LOG
        AJ_Sleep(1500);
#endif

        AJ_AlwaysPrintf(("AJ_Main 2\n"));
        status = TestNVRAM();
#ifdef READABLE_LOG
        AJ_Sleep(1500);
#endif

#ifdef RAND_DATA
        Randomizer();
#endif
        AJ_InfoPrintf(("\nBEGIN GUID EXIST TEST\n"));
        status = TestExist();
#ifdef READABLE_LOG
        AJ_Sleep(1500);
#endif
        AJ_InfoPrintf(("\nBEGIN OBSWRITE TEST\n"));
        status = TestObsWrite();
#ifdef READABLE_LOG
        AJ_Sleep(1500);
#endif

        AJ_InfoPrintf(("\nOBSWRITE STATUS %u, BEGIN WRITE TEST\n", status));
#ifdef READABLE_LOG
        AJ_Sleep(1500);
#endif
        status = TestNvramWrite();
        AJ_InfoPrintf(("\nWRITE STATUS %u, BEGIN READ TEST\n", status));
#ifdef READABLE_LOG
        AJ_Sleep(1500);
#endif
        status = TestNvramRead();
        AJ_InfoPrintf(("\nREAD STATUS %u, BEGIN DELETE TEST\n", status));
#ifdef READABLE_LOG
        AJ_Sleep(1500);
#endif
        status = TestNvramDelete();
        AJ_InfoPrintf(("\nDONE\n"));

        AJ_AlwaysPrintf(("AJ_Main 3\n"));
        AJ_ASSERT(status == AJ_OK);

        AJ_InfoPrintf(("\nDELETE STATUS %u, NVRAMTEST RUN %u TIMES\n", status, count++));
#ifdef READABLE_LOG
        AJ_Sleep(3000);
#endif

        status = TestECCCreds();
        AJ_InfoPrintf(("\nECC STATUS %u, NVRAMTEST RUN %u TIMES\n", status, count++));
        AJ_ASSERT(status == AJ_OK);
    }
    return 0;
}
Exemplo n.º 9
0
AJ_Status CreateTrailOfBreadcrumbs(void)
{
    uint16_t minNvramSpaceNeeded;
    uint16_t currentAvailableNvramSpace;


    uint16_t someNvramId = 0;
    AJ_NV_DATASET* someDataHandle = NULL;

    uint8_t sizeOfEachSlice;
    uint16_t i;

    size_t numBytesExpectingToWrite;
    size_t numBytesActuallyWritten;

    /*
     * Test program would write (place breadcrumbs) over the NVRAM, anyway.
     */
    AJ_NVRAM_Clear();

    currentAvailableNvramSpace = AJ_NVRAM_GetSizeRemaining();

    /*
     * At minimum, the test needs to store:
     * a. The message itself
     * b. The number of breadcrumbs in the trail (the mininum value is 1)
     *    (this is essentially the value held by lengthOfBreadcrumbTrail)
     */
    minNvramSpaceNeeded = (estimatedOverheadPerNvramItem + sizeof(sensumManifestum)) +
                          (estimatedOverheadPerNvramItem + sizeof(lengthOfBreadcrumbTrail));

    if (currentAvailableNvramSpace < minNvramSpaceNeeded) {
        AJ_Printf("ERROR: Available NVRAM space (%u bytes) is less than needed (%u bytes).\n", currentAvailableNvramSpace, minNvramSpaceNeeded);
        return AJ_ERR_RESOURCES;
    }

    /*
     * Any remaining space can be used to add more breadcrumbs.
     * max_num_bread_crumbs = nvram_size_available / size_occupied_by_each_crumb
     *
     * size_occupied_by_each_crumb = estimatedOverheadPerNvramItem + sizeof(id)
     */
    lengthOfBreadcrumbTrail = (currentAvailableNvramSpace - minNvramSpaceNeeded) /
                              (estimatedOverheadPerNvramItem  + sizeof(someNvramId));

    /*
     * Create the trail of bread crumbs starting at smId
     *
     * Generate a random list of nvram ids, lengthOfBreadcrumbTrail number of
     * elements. The list should not have any duplicates and should not include
     * marker ids viz. smId and countId.
     *
     * This is necessary to ensure that the trail of breadcrumbs is without
     * any loops. The simplest way to generate a list of unique nvram ids
     * would be to divide the available space into equal slices and generate
     * one id from each slice.
     *
     * The starting id is AJ_NVRAM_ID_APPS_BEGIN and the ending id is 0xFFFF.
     *
     * There are a total of (lengthOfBreadcrumbTrail + 1) items to
     * go through, including the starting point smId.
     */

    sizeOfEachSlice = (0xFFFF - AJ_NVRAM_ID_APPS_BEGIN) / lengthOfBreadcrumbTrail;

    /* The starting point has to be the constant marker, smId */
    someNvramId = smId;
    for (i = 0; i < lengthOfBreadcrumbTrail + 1; i++) {
        uint8_t randByte;
        uint16_t startId;
        uint16_t nextId;

        void* pointerToData;

        AJ_RandBytes(&randByte, sizeof(randByte));
        startId = AJ_NVRAM_ID_APPS_BEGIN + sizeOfEachSlice * i;

        nextId = startId + randByte % sizeOfEachSlice;

        /* Ensure uniqueness of id - no conflicts with well-known markers */
        if (smId == nextId || countId == nextId) {
            nextId += (0 == i % 2) ? -1 : 1;
        }

        numBytesExpectingToWrite =  (lengthOfBreadcrumbTrail != i) ? sizeof(nextId) : sizeof(sensumManifestum);

        currentAvailableNvramSpace = AJ_NVRAM_GetSizeRemaining();

        someDataHandle = AJ_NVRAM_Open(someNvramId, AJTestWriteMode, numBytesExpectingToWrite);

        if (NULL == someDataHandle) {
            /* Cannot proceed any further due to failed breadcrumb access */
            return AJ_ERR_NVRAM_WRITE;
        }

        pointerToData = (lengthOfBreadcrumbTrail != i) ? (void*) (&nextId) : (void*) sensumManifestum;
        numBytesActuallyWritten = AJ_NVRAM_Write(pointerToData,
                                                 numBytesExpectingToWrite,
                                                 someDataHandle);

        /* done writing the data, can close the handle */
        if (AJ_OK != AJ_NVRAM_Close(someDataHandle)) {
            AJ_Printf("WARN: For id: %u, AJ_NVRAM_Close did NOT return %s (code: %u)\n", someNvramId, AJ_StatusText(AJ_OK), AJ_OK);
        }

        if (AJTestNvramWriteFailure == numBytesActuallyWritten ||
            numBytesExpectingToWrite != numBytesActuallyWritten) {
            /* Cannot proceed any further due to breadcrumb write failure */
            return AJ_ERR_NVRAM_WRITE;
        }

        /*
         * The write has been successful.
         *
         * Check whether estimatedOverheadPerNvramItem (rough estimate) is
         * accurate. Overestimating estimatedOverheadPerNvramItem is fine
         * (erring on the side on caution).
         */
        if (estimatedOverheadPerNvramItem < currentAvailableNvramSpace - AJ_NVRAM_GetSizeRemaining() - numBytesExpectingToWrite) {
            AJ_Printf("ERROR: The estimated overhead per NVRAM item (%u bytes) is not accurate. It needs to be increased.\n", estimatedOverheadPerNvramItem);
            return AJ_ERR_FAILURE;
        }

        /* Move to the next breadcrumb */
        someNvramId = nextId;
    }

    /*
     * All the items are written.
     * Write the value of lengthOfBreadcrumbTrail
     */
    someDataHandle = AJ_NVRAM_Open(countId, AJTestWriteMode, sizeof(lengthOfBreadcrumbTrail));

    if (NULL == someDataHandle) {
        return AJ_ERR_NVRAM_WRITE;
    }

    numBytesExpectingToWrite = sizeof(lengthOfBreadcrumbTrail);
    numBytesActuallyWritten = AJ_NVRAM_Write((void*)&lengthOfBreadcrumbTrail,
                                             numBytesExpectingToWrite,
                                             someDataHandle);

    /* done writing the data, can close the handle */
    if (AJ_OK != AJ_NVRAM_Close(someDataHandle)) {
        AJ_Printf("WARN: For id: %u, AJ_NVRAM_Close did NOT return %s (code: %u)\n", countId, AJ_StatusText(AJ_OK), AJ_OK);
    }

    if (AJTestNvramWriteFailure == numBytesActuallyWritten ||
        numBytesExpectingToWrite != numBytesActuallyWritten) {
        return AJ_ERR_NVRAM_WRITE;
    }

    return AJ_OK;
}
Exemplo n.º 10
0
int AJ_Main_certificate(int ac, char** av)
{
    AJ_Status status = AJ_OK;
    size_t num = 2;
    size_t i;
    uint8_t* b8;
    char* pem;
    size_t pemlen;
    ecc_privatekey root_prvkey;
    ecc_publickey root_pubkey;
    uint8_t* manifest;
    size_t manifestlen;
    uint8_t digest[SHA256_DIGEST_LENGTH];
    ecc_privatekey peer_prvkey;
    ecc_publickey peer_pubkey;
    AJ_Certificate* cert;
    AJ_GUID guild;

    /*
     * Create an owner key pair
     */
    AJ_GenerateDSAKeyPair(&root_pubkey, &root_prvkey);

    b8 = (uint8_t*) AJ_Malloc(sizeof (ecc_publickey));
    AJ_ASSERT(b8);
    status = AJ_BigEndianEncodePublicKey(&root_pubkey, b8);
    AJ_ASSERT(AJ_OK == status);
    pemlen = 4 * ((sizeof (ecc_publickey) + 2) / 3) + 1;
    pem = (char*) AJ_Malloc(pemlen);
    status = AJ_RawToB64(b8, sizeof (ecc_publickey), pem, pemlen);
    AJ_ASSERT(AJ_OK == status);
    AJ_Printf("Owner Public Key\n");
    AJ_Printf("-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n", pem);
    AJ_Free(b8);
    AJ_Free(pem);

    CreateManifest(&manifest, &manifestlen);
    ManifestDigest(manifest, &manifestlen, digest);

    AJ_RandBytes((uint8_t*) &guild, sizeof (AJ_GUID));

    for (i = 0; i < num; i++) {
        AJ_GenerateDSAKeyPair(&peer_pubkey, &peer_prvkey);

        b8 = (uint8_t*) AJ_Malloc(sizeof (ecc_publickey));
        AJ_ASSERT(b8);
        status = AJ_BigEndianEncodePublicKey(&peer_pubkey, b8);
        AJ_ASSERT(AJ_OK == status);
        pemlen = 4 * ((sizeof (ecc_publickey) + 2) / 3) + 1;
        pem = (char*) AJ_Malloc(pemlen);
        status = AJ_RawToB64(b8, sizeof (ecc_publickey), pem, pemlen);
        AJ_ASSERT(AJ_OK == status);
        AJ_Printf("Peer Public Key\n");
        AJ_Printf("-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n", pem);
        AJ_Free(b8);
        AJ_Free(pem);

        b8 = (uint8_t*) AJ_Malloc(sizeof (ecc_privatekey));
        AJ_ASSERT(b8);
        status = AJ_BigEndianEncodePrivateKey(&peer_prvkey, b8);
        AJ_ASSERT(AJ_OK == status);
        pemlen = 4 * ((sizeof (ecc_privatekey) + 2) / 3) + 1;
        pem = (char*) AJ_Malloc(pemlen);
        status = AJ_RawToB64(b8, sizeof (ecc_privatekey), pem, pemlen);
        AJ_ASSERT(AJ_OK == status);
        AJ_Printf("Peer Private Key\n");
        AJ_Printf("-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----\n", pem);
        AJ_Free(b8);
        AJ_Free(pem);

        cert = (AJ_Certificate*) AJ_Malloc(sizeof (AJ_Certificate));
        AJ_ASSERT(cert);
        status = AJ_CreateCertificate(cert, 0, &peer_pubkey, NULL, NULL, digest, 0);
        AJ_ASSERT(AJ_OK == status);
        status = AJ_SignCertificate(cert, &peer_prvkey);
        AJ_ASSERT(AJ_OK == status);
        status = AJ_VerifyCertificate(cert);
        AJ_ASSERT(AJ_OK == status);

        b8 = (uint8_t*) AJ_Malloc(sizeof (AJ_Certificate));
        AJ_ASSERT(b8);
        status = AJ_BigEndianEncodeCertificate(cert, b8, sizeof (AJ_Certificate));
        AJ_ASSERT(AJ_OK == status);
        pemlen = 4 * ((sizeof (AJ_Certificate) + 2) / 3) + 1;
        pem = (char*) AJ_Malloc(pemlen);
        status = AJ_RawToB64(b8, cert->size, pem, pemlen);
        AJ_ASSERT(AJ_OK == status);
        AJ_Printf("Peer Certificate (Type 0)\n");
        AJ_Printf("-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n", pem);

        status = AJ_CreateCertificate(cert, 1, &root_pubkey, &peer_pubkey, NULL, digest, 0);
        AJ_ASSERT(AJ_OK == status);
        status = AJ_SignCertificate(cert, &root_prvkey);
        AJ_ASSERT(AJ_OK == status);
        status = AJ_VerifyCertificate(cert);
        AJ_ASSERT(AJ_OK == status);

        status = AJ_BigEndianEncodeCertificate(cert, b8, sizeof (AJ_Certificate));
        AJ_ASSERT(AJ_OK == status);
        status = AJ_RawToB64(b8, cert->size, pem, pemlen);
        AJ_ASSERT(AJ_OK == status);
        AJ_Printf("Root Certificate (Type 1)\n");
        AJ_Printf("-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n", pem);

        status = AJ_CreateCertificate(cert, 2, &root_pubkey, &peer_pubkey, &guild, digest, 0);
        AJ_ASSERT(AJ_OK == status);
        status = AJ_SignCertificate(cert, &root_prvkey);
        AJ_ASSERT(AJ_OK == status);
        status = AJ_VerifyCertificate(cert);
        AJ_ASSERT(AJ_OK == status);

        status = AJ_BigEndianEncodeCertificate(cert, b8, sizeof (AJ_Certificate));
        AJ_ASSERT(AJ_OK == status);
        status = AJ_RawToB64(b8, cert->size, pem, pemlen);
        AJ_ASSERT(AJ_OK == status);
        AJ_Printf("Root Certificate (Type 2)\n");
        AJ_Printf("-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n", pem);
        AJ_Free(cert);
        AJ_Free(b8);
        AJ_Free(pem);
    }

    AJ_Free(manifest);

    return 0;
}